-
Notifications
You must be signed in to change notification settings - Fork 111
/
admin.go
112 lines (101 loc) · 3.08 KB
/
admin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package admin
import (
"context"
"fmt"
"github.com/rilldata/rill/admin/ai"
"github.com/rilldata/rill/admin/database"
"github.com/rilldata/rill/admin/provisioner"
"github.com/rilldata/rill/runtime/pkg/email"
"github.com/rilldata/rill/runtime/server/auth"
"go.uber.org/zap"
)
type Options struct {
DatabaseDriver string
DatabaseDSN string
ProvisionerSetJSON string
DefaultProvisioner string
ExternalURL string
VersionNumber string
VersionCommit string
MetricsProjectOrg string
MetricsProjectName string
AutoscalerCron string
}
type Service struct {
DB database.DB
ProvisionerSet map[string]provisioner.Provisioner
Email *email.Client
Github Github
AI ai.Client
Used *usedFlusher
Logger *zap.Logger
opts *Options
issuer *auth.Issuer
VersionNumber string
VersionCommit string
metricsProjectID string
AutoscalerCron string
}
func New(ctx context.Context, opts *Options, logger *zap.Logger, issuer *auth.Issuer, emailClient *email.Client, github Github, aiClient ai.Client) (*Service, error) {
// Init db
db, err := database.Open(opts.DatabaseDriver, opts.DatabaseDSN)
if err != nil {
logger.Fatal("error connecting to database", zap.Error(err))
}
// Auto-run migrations
v1, err := db.FindMigrationVersion(ctx)
if err != nil {
logger.Fatal("error getting migration version", zap.Error(err))
}
err = db.Migrate(ctx)
if err != nil {
logger.Fatal("error migrating database", zap.Error(err))
}
v2, err := db.FindMigrationVersion(ctx)
if err != nil {
logger.Fatal("error getting migration version", zap.Error(err))
}
if v1 == v2 {
logger.Info("database is up to date", zap.Int("version", v2))
} else {
logger.Info("database migrated", zap.Int("from_version", v1), zap.Int("to_version", v2))
}
// Create provisioner set
provSet, err := provisioner.NewSet(opts.ProvisionerSetJSON, db, logger)
if err != nil {
return nil, err
}
// Verify that the specified default provisioner is in the provisioner set
_, ok := provSet[opts.DefaultProvisioner]
if !ok {
return nil, fmt.Errorf("default provisioner %q is not in the provisioner set", opts.DefaultProvisioner)
}
// Look for the optional metrics project
var metricsProjectID string
if opts.MetricsProjectOrg != "" && opts.MetricsProjectName != "" {
proj, err := db.FindProjectByName(ctx, opts.MetricsProjectOrg, opts.MetricsProjectName)
if err != nil {
return nil, fmt.Errorf("error looking up metrics project: %w", err)
}
metricsProjectID = proj.ID
}
return &Service{
DB: db,
ProvisionerSet: provSet,
Email: emailClient,
Github: github,
AI: aiClient,
Used: newUsedFlusher(logger, db),
Logger: logger,
opts: opts,
issuer: issuer,
VersionNumber: opts.VersionNumber,
VersionCommit: opts.VersionCommit,
metricsProjectID: metricsProjectID,
AutoscalerCron: opts.AutoscalerCron,
}, nil
}
func (s *Service) Close() error {
s.Used.Close()
return s.DB.Close()
}