Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Managed connectors #6134

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions admin/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ type DB interface {
DeleteProjectVariables(ctx context.Context, projectID, environment string, vars []string) error

FindProvisionerResourcesForDeployment(ctx context.Context, deploymentID string) ([]*ProvisionerResource, error)
FindProvisionerResourceByName(ctx context.Context, deploymentID, typ, name string) (*ProvisionerResource, error)
InsertProvisionerResource(ctx context.Context, opts *InsertProvisionerResourceOptions) (*ProvisionerResource, error)
UpdateProvisionerResource(ctx context.Context, id string, opts *UpdateProvisionerResourceOptions) (*ProvisionerResource, error)
DeleteProvisionerResource(ctx context.Context, id string) error
Expand Down Expand Up @@ -783,26 +784,28 @@ type OrganizationRole struct {

// ProjectRole represents roles for projects.
type ProjectRole struct {
ID string
Name string
ReadProject bool `db:"read_project"`
ManageProject bool `db:"manage_project"`
ReadProd bool `db:"read_prod"`
ReadProdStatus bool `db:"read_prod_status"`
ManageProd bool `db:"manage_prod"`
ReadDev bool `db:"read_dev"`
ReadDevStatus bool `db:"read_dev_status"`
ManageDev bool `db:"manage_dev"`
ReadProjectMembers bool `db:"read_project_members"`
ManageProjectMembers bool `db:"manage_project_members"`
CreateMagicAuthTokens bool `db:"create_magic_auth_tokens"`
ManageMagicAuthTokens bool `db:"manage_magic_auth_tokens"`
CreateReports bool `db:"create_reports"`
ManageReports bool `db:"manage_reports"`
CreateAlerts bool `db:"create_alerts"`
ManageAlerts bool `db:"manage_alerts"`
CreateBookmarks bool `db:"create_bookmarks"`
ManageBookmarks bool `db:"manage_bookmarks"`
ID string
Name string
ReadProject bool `db:"read_project"`
ManageProject bool `db:"manage_project"`
ReadProd bool `db:"read_prod"`
ReadProdStatus bool `db:"read_prod_status"`
ManageProd bool `db:"manage_prod"`
ReadDev bool `db:"read_dev"`
ReadDevStatus bool `db:"read_dev_status"`
ManageDev bool `db:"manage_dev"`
ReadProvisionerResources bool `db:"read_provisioner_resources"`
ManageProvisionerResources bool `db:"manage_provisioner_resources"`
ReadProjectMembers bool `db:"read_project_members"`
ManageProjectMembers bool `db:"manage_project_members"`
CreateMagicAuthTokens bool `db:"create_magic_auth_tokens"`
ManageMagicAuthTokens bool `db:"manage_magic_auth_tokens"`
CreateReports bool `db:"create_reports"`
ManageReports bool `db:"manage_reports"`
CreateAlerts bool `db:"create_alerts"`
ManageAlerts bool `db:"manage_alerts"`
CreateBookmarks bool `db:"create_bookmarks"`
ManageBookmarks bool `db:"manage_bookmarks"`
}

// MemberUser is a convenience type used for display-friendly representation of an org or project member.
Expand Down
5 changes: 5 additions & 0 deletions admin/database/postgres/migrations/0055.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ALTER TABLE project_roles ADD read_provisioner_resources BOOLEAN DEFAULT false NOT NULL;
UPDATE project_roles SET read_provisioner_resources = read_prod_status;

ALTER TABLE project_roles ADD manage_provisioner_resources BOOLEAN DEFAULT false NOT NULL;
UPDATE project_roles SET manage_provisioner_resources = manage_prod;
9 changes: 9 additions & 0 deletions admin/database/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -2232,6 +2232,15 @@ func (c *connection) FindProvisionerResourcesForDeployment(ctx context.Context,
return c.provisionerResourcesFromDTOs(res)
}

func (c *connection) FindProvisionerResourceByName(ctx context.Context, deploymentID, typ, name string) (*database.ProvisionerResource, error) {
res := &provisionerResourceDTO{}
err := c.getDB(ctx).QueryRowxContext(ctx, `SELECT * FROM provisioner_resources WHERE deployment_id = $1 AND "type" = $2 AND name = $3`, deploymentID, typ, name).StructScan(res)
if err != nil {
return nil, parseErr("provisioner resource", err)
}
return c.provisionerResourceFromDTO(res)
}

func (c *connection) InsertProvisionerResource(ctx context.Context, opts *database.InsertProvisionerResourceOptions) (*database.ProvisionerResource, error) {
if err := database.Validate(opts); err != nil {
return nil, err
Expand Down
92 changes: 13 additions & 79 deletions admin/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"
"time"

"github.com/google/uuid"
"github.com/hashicorp/go-version"
"github.com/rilldata/rill/admin/database"
"github.com/rilldata/rill/admin/provisioner"
Expand Down Expand Up @@ -478,107 +477,42 @@ type provisionRuntimeOptions struct {
}

func (s *Service) provisionRuntime(ctx context.Context, opts *provisionRuntimeOptions) (*database.ProvisionerResource, error) {
// Get provisioner from the set.
// Use default if no provisioner is specified.
if opts.Provisioner == "" {
opts.Provisioner = s.opts.DefaultProvisioner
}
p, ok := s.ProvisionerSet[opts.Provisioner]
if !ok {
return nil, fmt.Errorf("provisioner: %q is not in the provisioner set", opts.Provisioner)
}

// Create provisioner args
args := &provisioner.RuntimeArgs{
Slots: opts.Slots,
Version: opts.Version,
}

// Attempt to find an existing provisioned runtime for the deployment
pr, ok, err := s.findProvisionedRuntimeResource(ctx, opts.DeploymentID)
if err != nil {
return nil, err
}
if ok && pr.Provisioner != opts.Provisioner {
return nil, fmt.Errorf("provisioner: cannot change provisioner from %q to %q for deployment %q", pr.Provisioner, opts.Provisioner, opts.DeploymentID)
}

// If we didn't find an existing DB entry, create one
if !ok {
pr, err = s.DB.InsertProvisionerResource(ctx, &database.InsertProvisionerResourceOptions{
ID: uuid.New().String(),
DeploymentID: opts.DeploymentID,
Type: string(provisioner.ResourceTypeRuntime),
Name: "", // Not giving runtime resources a name since there should only be one per deployment.
Status: database.ProvisionerResourceStatusPending,
StatusMessage: "Provisioning...",
Provisioner: opts.Provisioner,
Args: args.AsMap(),
State: nil, // Will be populated after provisioning
Config: nil, // Will be populated after provisioning
})
if err != nil {
return nil, err
}
}

// Provision the runtime
r := &provisioner.Resource{
ID: pr.ID,
Type: provisioner.ResourceTypeRuntime,
State: pr.State, // Empty if inserting
Config: pr.Config, // Empty if inserting
}
r, err = p.Provision(ctx, r, &provisioner.ResourceOptions{
Args: args.AsMap(),
Annotations: opts.Annotations,
RillVersion: s.resolveRillVersion(),
})
if err != nil {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
_, _ = s.DB.UpdateProvisionerResource(ctx, pr.ID, &database.UpdateProvisionerResourceOptions{
Status: database.ProvisionerResourceStatusError,
StatusMessage: fmt.Sprintf("Failed provisioning runtime: %v", err),
Args: pr.Args,
State: pr.State,
Config: pr.Config,
})
return nil, err
}

// Update the provisioner resource
pr, err = s.DB.UpdateProvisionerResource(ctx, pr.ID, &database.UpdateProvisionerResourceOptions{
Status: database.ProvisionerResourceStatusOK,
StatusMessage: "",
Args: args.AsMap(),
State: r.State,
Config: r.Config,
// Call into the generic provision function
pr, err := s.Provision(ctx, &ProvisionOptions{
DeploymentID: opts.DeploymentID,
Type: provisioner.ResourceTypeRuntime,
Name: "", // Not giving runtime resources a name since there should only be one per deployment.
Provisioner: opts.Provisioner,
Args: args.AsMap(),
Annotations: opts.Annotations,
})
if err != nil {
return nil, err
}

// Await the runtime to be ready
err = p.AwaitReady(ctx, r)
if err != nil {
return nil, err
}

return pr, nil
}

func (s *Service) findProvisionedRuntimeResource(ctx context.Context, deploymentID string) (*database.ProvisionerResource, bool, error) {
prs, err := s.DB.FindProvisionerResourcesForDeployment(ctx, deploymentID)
pr, err := s.DB.FindProvisionerResourceByName(ctx, deploymentID, string(provisioner.ResourceTypeRuntime), "")
if err != nil {
return nil, false, err
}
for _, val := range prs {
if provisioner.ResourceType(val.Type) == provisioner.ResourceTypeRuntime {
return val, true, nil
if errors.Is(err, database.ErrNotFound) {
return nil, false, nil
}
return nil, false, err
}
return nil, false, nil
return pr, true, nil
}

func (s *Service) resolveRillVersion() string {
Expand Down
Loading
Loading