-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CRUD APIs and security policies for scheduled reports (#3293)
* Support ad-hoc code files backed by Postgres * Typo * Implement database functions * Background job to garbage collect soft deleted virtual files * Format query * Self review * CRUD APIs and security policies for scheduled reports * Fix proto linter * Fix golang lint * Self review * nits * Add permissions for reports * Incorporate permissions * Fix migration * QA on APIs * Generate pretty report YAML * Pretty export format
- Loading branch information
1 parent
ac96221
commit cd32b80
Showing
52 changed files
with
8,907 additions
and
2,912 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
ALTER TABLE project_roles ADD create_reports BOOLEAN NOT NULL DEFAULT false; | ||
UPDATE project_roles SET create_reports = read_prod; | ||
|
||
ALTER TABLE project_roles ADD manage_reports BOOLEAN NOT NULL DEFAULT false; | ||
UPDATE project_roles SET manage_reports = manage_prod; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package admin | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/rilldata/rill/admin/database" | ||
runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1" | ||
"github.com/rilldata/rill/runtime" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
) | ||
|
||
// TriggerReport triggers an ad-hoc run of a report | ||
func (s *Service) TriggerReport(ctx context.Context, depl *database.Deployment, report string) (err error) { | ||
names := []*runtimev1.ResourceName{ | ||
{ | ||
Kind: runtime.ResourceKindReport, | ||
Name: report, | ||
}, | ||
} | ||
|
||
rt, err := s.openRuntimeClientForDeployment(depl) | ||
if err != nil { | ||
return err | ||
} | ||
defer rt.Close() | ||
|
||
_, err = rt.CreateTrigger(ctx, &runtimev1.CreateTriggerRequest{ | ||
InstanceId: depl.RuntimeInstanceID, | ||
Trigger: &runtimev1.CreateTriggerRequest_RefreshTriggerSpec{ | ||
RefreshTriggerSpec: &runtimev1.RefreshTriggerSpec{OnlyNames: names}, | ||
}, | ||
}) | ||
return err | ||
} | ||
|
||
// TriggerReconcileAndAwaitReport triggers a reconcile and polls the runtime until the given report's spec version has been updated (or ctx is canceled). | ||
func (s *Service) TriggerReconcileAndAwaitReport(ctx context.Context, depl *database.Deployment, reportName string) error { | ||
rt, err := s.openRuntimeClientForDeployment(depl) | ||
if err != nil { | ||
return err | ||
} | ||
defer rt.Close() | ||
|
||
reportReq := &runtimev1.GetResourceRequest{ | ||
InstanceId: depl.RuntimeInstanceID, | ||
Name: &runtimev1.ResourceName{ | ||
Kind: runtime.ResourceKindReport, | ||
Name: reportName, | ||
}, | ||
} | ||
|
||
// Get old spec version | ||
var oldSpecVersion *int64 | ||
r, err := rt.GetResource(ctx, reportReq) | ||
if err == nil { | ||
oldSpecVersion = &r.Resource.Meta.SpecVersion | ||
} | ||
|
||
// Trigger reconcile | ||
_, err = rt.CreateTrigger(ctx, &runtimev1.CreateTriggerRequest{ | ||
InstanceId: depl.RuntimeInstanceID, | ||
Trigger: &runtimev1.CreateTriggerRequest_PullTriggerSpec{ | ||
PullTriggerSpec: &runtimev1.PullTriggerSpec{}, | ||
}, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Poll every 1 seconds until the report is found or the ctx is cancelled or times out | ||
ctx, cancel := context.WithTimeout(ctx, time.Minute) | ||
defer cancel() | ||
ticker := time.NewTicker(time.Second) | ||
defer ticker.Stop() | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return ctx.Err() | ||
case <-ticker.C: | ||
} | ||
|
||
r, err := rt.GetResource(ctx, reportReq) | ||
if err != nil { | ||
if s, ok := status.FromError(err); !ok || s.Code() != codes.NotFound { | ||
return fmt.Errorf("failed to poll for report: %w", err) | ||
} | ||
if oldSpecVersion != nil { | ||
// Success - previously the report was found, now we cannot find it anymore | ||
return nil | ||
} | ||
// Continue polling | ||
continue | ||
} | ||
if oldSpecVersion == nil { | ||
// Success - previously the report was not found, now we found one | ||
return nil | ||
} | ||
if *oldSpecVersion != r.Resource.Meta.SpecVersion { | ||
// Success - the spec version has changed | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
// LookupReport fetches a report's spec from a runtime deployment. | ||
func (s *Service) LookupReport(ctx context.Context, depl *database.Deployment, reportName string) (*runtimev1.ReportSpec, error) { | ||
rt, err := s.openRuntimeClientForDeployment(depl) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer rt.Close() | ||
|
||
res, err := rt.GetResource(ctx, &runtimev1.GetResourceRequest{ | ||
InstanceId: depl.RuntimeInstanceID, | ||
Name: &runtimev1.ResourceName{ | ||
Kind: runtime.ResourceKindReport, | ||
Name: reportName, | ||
}, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return res.Resource.Resource.(*runtimev1.Resource_Report).Report.Spec, nil | ||
} |
Oops, something went wrong.
cd32b80
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Published on https://ui.rilldata.io as production
🚀 Deployed on https://653afcf646654b488164bbf7--rill-ui-stage.netlify.app