garm/database/sql/sql.go

789 lines
21 KiB
Go
Raw Normal View History

2022-04-25 00:03:26 +00:00
package sql
import (
"context"
"fmt"
"runner-manager/config"
"runner-manager/database/common"
runnerErrors "runner-manager/errors"
"runner-manager/params"
"runner-manager/util"
"github.com/pborman/uuid"
"github.com/pkg/errors"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func NewSQLDatabase(ctx context.Context, cfg config.Database) (common.Store, error) {
conn, err := util.NewDBConn(cfg)
if err != nil {
return nil, errors.Wrap(err, "creating DB connection")
}
db := &sqlDatabase{
conn: conn,
ctx: ctx,
cfg: cfg,
}
if err := db.migrateDB(); err != nil {
return nil, errors.Wrap(err, "migrating database")
}
return db, nil
}
type sqlDatabase struct {
conn *gorm.DB
ctx context.Context
cfg config.Database
}
func (s *sqlDatabase) migrateDB() error {
if err := s.conn.AutoMigrate(
&Tag{},
// &Runner{},
&Pool{},
&Repository{},
&Organization{},
2022-04-26 20:29:58 +00:00
&Address{},
&Instance{},
2022-04-25 00:03:26 +00:00
); err != nil {
return err
}
return nil
}
func (s *sqlDatabase) sqlToCommonTags(tag Tag) params.Tag {
return params.Tag{
2022-04-26 20:29:58 +00:00
// ID: tag.ID.String(),
2022-04-25 00:03:26 +00:00
ID: tag.ID.String(),
Name: tag.Name,
}
}
func (s *sqlDatabase) sqlToCommonPool(pool Pool) params.Pool {
ret := params.Pool{
ID: pool.ID.String(),
ProviderName: pool.ProviderName,
MaxRunners: pool.MaxRunners,
MinIdleRunners: pool.MinIdleRunners,
Image: pool.Image,
Flavor: pool.Flavor,
OSArch: pool.OSArch,
OSType: pool.OSType,
2022-04-27 16:56:28 +00:00
Enabled: pool.Enabled,
2022-04-25 00:03:26 +00:00
Tags: make([]params.Tag, len(pool.Tags)),
}
for idx, val := range pool.Tags {
2022-04-26 20:29:58 +00:00
ret.Tags[idx] = s.sqlToCommonTags(*val)
2022-04-25 00:03:26 +00:00
}
return ret
}
func (s *sqlDatabase) sqlToCommonRepository(repo Repository) params.Repository {
ret := params.Repository{
ID: repo.ID.String(),
Name: repo.Name,
Owner: repo.Owner,
Pools: make([]params.Pool, len(repo.Pools)),
}
for idx, pool := range repo.Pools {
ret.Pools[idx] = s.sqlToCommonPool(pool)
}
return ret
}
func (s *sqlDatabase) sqlToCommonOrganization(org Organization) params.Organization {
ret := params.Organization{
ID: org.ID.String(),
Name: org.Name,
Pools: make([]params.Pool, len(org.Pools)),
}
return ret
}
func (s *sqlDatabase) CreateRepository(ctx context.Context, owner, name, webhookSecret string) (params.Repository, error) {
secret := []byte{}
var err error
if webhookSecret != "" {
secret, err = util.Aes256EncodeString(webhookSecret, s.cfg.Passphrase)
if err != nil {
return params.Repository{}, fmt.Errorf("failed to encrypt string")
}
}
newRepo := Repository{
Name: name,
Owner: owner,
WebhookSecret: secret,
}
q := s.conn.Create(&newRepo)
if q.Error != nil {
return params.Repository{}, errors.Wrap(q.Error, "creating repository")
}
param := s.sqlToCommonRepository(newRepo)
param.WebhookSecret = webhookSecret
return param, nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) getRepo(ctx context.Context, owner, name string) (Repository, error) {
var repo Repository
2022-04-27 16:56:28 +00:00
q := s.conn.Preload(clause.Associations).
Where("name = ? and owner = ?", name, owner).
First(&repo)
2022-04-26 20:29:58 +00:00
if q.Error != nil {
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
return Repository{}, runnerErrors.ErrNotFound
}
return Repository{}, errors.Wrap(q.Error, "fetching repository from database")
}
return repo, nil
}
func (s *sqlDatabase) getRepoByID(ctx context.Context, id string) (Repository, error) {
2022-04-25 00:03:26 +00:00
u := uuid.Parse(id)
if u == nil {
return Repository{}, errors.Wrap(runnerErrors.NewBadRequestError(""), "parsing id")
}
var repo Repository
2022-04-27 16:56:28 +00:00
q := s.conn.Preload(clause.Associations).
Where("id = ?", u).
First(&repo)
2022-04-25 00:03:26 +00:00
if q.Error != nil {
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
return Repository{}, runnerErrors.ErrNotFound
}
return Repository{}, errors.Wrap(q.Error, "fetching repository from database")
}
return repo, nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) GetRepository(ctx context.Context, owner, name string) (params.Repository, error) {
repo, err := s.getRepo(ctx, owner, name)
2022-04-25 00:03:26 +00:00
if err != nil {
return params.Repository{}, errors.Wrap(err, "fetching repo")
}
param := s.sqlToCommonRepository(repo)
secret, err := util.Aes256DecodeString(repo.WebhookSecret, s.cfg.Passphrase)
if err != nil {
return params.Repository{}, errors.Wrap(err, "decrypting secret")
}
param.WebhookSecret = secret
return param, nil
}
func (s *sqlDatabase) ListRepositories(ctx context.Context) ([]params.Repository, error) {
var repos []Repository
q := s.conn.Find(&repos)
if q.Error != nil {
return []params.Repository{}, errors.Wrap(q.Error, "fetching user from database")
}
ret := make([]params.Repository, len(repos))
for idx, val := range repos {
ret[idx] = s.sqlToCommonRepository(val)
}
return ret, nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) DeleteRepository(ctx context.Context, owner, name string) error {
repo, err := s.getRepo(ctx, owner, name)
2022-04-25 00:03:26 +00:00
if err != nil {
if err == runnerErrors.ErrNotFound {
return nil
}
return errors.Wrap(err, "fetching repo")
}
q := s.conn.Delete(&repo)
if q.Error != nil && !errors.Is(q.Error, gorm.ErrRecordNotFound) {
return errors.Wrap(q.Error, "deleting repo")
}
return nil
}
func (s *sqlDatabase) CreateOrganization(ctx context.Context, name, webhookSecret string) (params.Organization, error) {
secret := []byte{}
var err error
if webhookSecret != "" {
secret, err = util.Aes256EncodeString(webhookSecret, s.cfg.Passphrase)
if err != nil {
return params.Organization{}, fmt.Errorf("failed to encrypt string")
}
}
newOrg := Organization{
Name: name,
WebhookSecret: secret,
}
q := s.conn.Create(&newOrg)
if q.Error != nil {
return params.Organization{}, errors.Wrap(q.Error, "creating org")
}
param := s.sqlToCommonOrganization(newOrg)
param.WebhookSecret = webhookSecret
return param, nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) getOrg(ctx context.Context, name string) (Organization, error) {
var org Organization
q := s.conn.Preload(clause.Associations).Where("name = ?", name).First(&org)
if q.Error != nil {
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
return Organization{}, runnerErrors.ErrNotFound
}
return Organization{}, errors.Wrap(q.Error, "fetching org from database")
}
return org, nil
}
func (s *sqlDatabase) getOrgByID(ctx context.Context, id string) (Organization, error) {
2022-04-25 00:03:26 +00:00
u := uuid.Parse(id)
if u == nil {
return Organization{}, errors.Wrap(runnerErrors.NewBadRequestError(""), "parsing id")
}
var org Organization
q := s.conn.Preload(clause.Associations).Where("id = ?", u).First(&org)
if q.Error != nil {
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
return Organization{}, runnerErrors.ErrNotFound
}
return Organization{}, errors.Wrap(q.Error, "fetching org from database")
}
return org, nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) GetOrganization(ctx context.Context, name string) (params.Organization, error) {
org, err := s.getOrg(ctx, name)
2022-04-25 00:03:26 +00:00
if err != nil {
return params.Organization{}, errors.Wrap(err, "fetching repo")
}
param := s.sqlToCommonOrganization(org)
secret, err := util.Aes256DecodeString(org.WebhookSecret, s.cfg.Passphrase)
if err != nil {
return params.Organization{}, errors.Wrap(err, "decrypting secret")
}
param.WebhookSecret = secret
return param, nil
}
func (s *sqlDatabase) ListOrganizations(ctx context.Context) ([]params.Organization, error) {
var orgs []Organization
q := s.conn.Find(&orgs)
if q.Error != nil {
return []params.Organization{}, errors.Wrap(q.Error, "fetching user from database")
}
ret := make([]params.Organization, len(orgs))
for idx, val := range orgs {
ret[idx] = s.sqlToCommonOrganization(val)
}
return ret, nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) DeleteOrganization(ctx context.Context, name string) error {
org, err := s.getOrg(ctx, name)
2022-04-25 00:03:26 +00:00
if err != nil {
if err == runnerErrors.ErrNotFound {
return nil
}
return errors.Wrap(err, "fetching repo")
}
q := s.conn.Delete(&org)
if q.Error != nil && !errors.Is(q.Error, gorm.ErrRecordNotFound) {
return errors.Wrap(q.Error, "deleting org")
}
return nil
}
func (s *sqlDatabase) getOrCreateTag(tagName string) (Tag, error) {
var tag Tag
q := s.conn.Where("name = ?", tagName).First(&tag)
if q.Error == nil {
return tag, nil
}
if !errors.Is(q.Error, gorm.ErrRecordNotFound) {
return Tag{}, errors.Wrap(q.Error, "fetching tag from database")
}
newTag := Tag{
Name: tagName,
}
q = s.conn.Create(&newTag)
if q.Error != nil {
return Tag{}, errors.Wrap(q.Error, "creating tag")
}
return newTag, nil
}
func (s *sqlDatabase) CreateRepositoryPool(ctx context.Context, repoId string, param params.CreatePoolParams) (params.Pool, error) {
if len(param.Tags) == 0 {
return params.Pool{}, runnerErrors.NewBadRequestError("no tags specified")
}
2022-04-26 20:29:58 +00:00
repo, err := s.getRepoByID(ctx, repoId)
2022-04-25 00:03:26 +00:00
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching repo")
}
newPool := Pool{
ProviderName: param.ProviderName,
MaxRunners: param.MaxRunners,
MinIdleRunners: param.MinIdleRunners,
Image: param.Image,
Flavor: param.Flavor,
OSType: param.OSType,
OSArch: param.OSArch,
2022-04-26 20:29:58 +00:00
RepoID: repo.ID,
2022-04-27 16:56:28 +00:00
Enabled: param.Enabled,
2022-04-25 00:03:26 +00:00
}
2022-04-26 20:29:58 +00:00
tags := []Tag{}
for _, val := range param.Tags {
2022-04-25 00:03:26 +00:00
t, err := s.getOrCreateTag(val)
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching tag")
}
2022-04-26 20:29:58 +00:00
tags = append(tags, t)
2022-04-25 00:03:26 +00:00
}
2022-04-26 20:29:58 +00:00
q := s.conn.Create(&newPool)
if q.Error != nil {
2022-04-25 00:03:26 +00:00
return params.Pool{}, errors.Wrap(err, "adding pool")
}
2022-04-26 20:29:58 +00:00
for _, tt := range tags {
s.conn.Model(&newPool).Association("Tags").Append(&tt)
}
repo, err = s.getRepoByID(ctx, repoId)
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching repo")
}
return s.sqlToCommonPool(repo.Pools[0]), nil
2022-04-25 00:03:26 +00:00
}
func (s *sqlDatabase) CreateOrganizationPool(ctx context.Context, orgId string, param params.CreatePoolParams) (params.Pool, error) {
if len(param.Tags) == 0 {
return params.Pool{}, runnerErrors.NewBadRequestError("no tags specified")
}
2022-04-26 20:29:58 +00:00
org, err := s.getOrgByID(ctx, orgId)
2022-04-25 00:03:26 +00:00
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching org")
}
newPool := Pool{
ProviderName: param.ProviderName,
MaxRunners: param.MaxRunners,
MinIdleRunners: param.MinIdleRunners,
Image: param.Image,
Flavor: param.Flavor,
OSType: param.OSType,
OSArch: param.OSArch,
2022-04-27 16:56:28 +00:00
Enabled: param.Enabled,
2022-04-25 00:03:26 +00:00
}
2022-04-26 20:29:58 +00:00
tags := make([]*Tag, len(param.Tags))
2022-04-25 00:03:26 +00:00
for idx, val := range param.Tags {
t, err := s.getOrCreateTag(val)
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching tag")
}
2022-04-26 20:29:58 +00:00
tags[idx] = &t
2022-04-25 00:03:26 +00:00
}
2022-04-26 20:29:58 +00:00
newPool.Tags = append(newPool.Tags, tags...)
2022-04-25 00:03:26 +00:00
err = s.conn.Model(&org).Association("Pools").Append(&newPool)
if err != nil {
return params.Pool{}, errors.Wrap(err, "adding pool")
}
return s.sqlToCommonPool(newPool), nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) getRepoPool(ctx context.Context, repoID, poolID string) (Pool, error) {
repo, err := s.getRepoByID(ctx, repoID)
2022-04-25 00:03:26 +00:00
if err != nil {
2022-04-26 20:29:58 +00:00
return Pool{}, errors.Wrap(err, "fetching repo")
2022-04-25 00:03:26 +00:00
}
u := uuid.Parse(poolID)
if u == nil {
2022-04-26 20:29:58 +00:00
return Pool{}, fmt.Errorf("invalid pool id")
2022-04-25 00:03:26 +00:00
}
var pool []Pool
err = s.conn.Model(&repo).Association("Pools").Find(&pool, "id = ?", u)
if err != nil {
2022-04-26 20:29:58 +00:00
return Pool{}, errors.Wrap(err, "fetching pool")
2022-04-25 00:03:26 +00:00
}
if len(pool) == 0 {
2022-04-26 20:29:58 +00:00
return Pool{}, runnerErrors.ErrNotFound
2022-04-25 00:03:26 +00:00
}
2022-04-26 20:29:58 +00:00
return pool[0], nil
2022-04-25 00:03:26 +00:00
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) GetRepositoryPool(ctx context.Context, repoID, poolID string) (params.Pool, error) {
pool, err := s.getRepoPool(ctx, repoID, poolID)
2022-04-25 00:03:26 +00:00
if err != nil {
2022-04-26 20:29:58 +00:00
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
}
func (s *sqlDatabase) getOrgPool(ctx context.Context, orgID, poolID string) (Pool, error) {
org, err := s.getOrgByID(ctx, orgID)
if err != nil {
return Pool{}, errors.Wrap(err, "fetching repo")
2022-04-25 00:03:26 +00:00
}
u := uuid.Parse(poolID)
if u == nil {
2022-04-26 20:29:58 +00:00
return Pool{}, fmt.Errorf("invalid pool id")
2022-04-25 00:03:26 +00:00
}
var pool []Pool
2022-04-27 16:56:28 +00:00
err = s.conn.Model(&org).
Association(clause.Associations).
Find(&pool, "id = ?", u)
2022-04-25 00:03:26 +00:00
if err != nil {
2022-04-26 20:29:58 +00:00
return Pool{}, errors.Wrap(err, "fetching pool")
2022-04-25 00:03:26 +00:00
}
if len(pool) == 0 {
2022-04-26 20:29:58 +00:00
return Pool{}, runnerErrors.ErrNotFound
}
return pool[0], nil
}
2022-04-27 16:56:28 +00:00
func (s *sqlDatabase) getPoolByID(ctx context.Context, poolID string) (Pool, error) {
u := uuid.Parse(poolID)
if u == nil {
return Pool{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id")
}
var pool Pool
q := s.conn.Model(&Pool{}).
Preload(clause.Associations).
Where("id = ?", u).First(&pool)
if q.Error != nil {
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
return Pool{}, runnerErrors.ErrNotFound
}
return Pool{}, errors.Wrap(q.Error, "fetching org from database")
}
return pool, nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) GetOrganizationPool(ctx context.Context, orgID, poolID string) (params.Pool, error) {
pool, err := s.getOrgPool(ctx, orgID, poolID)
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching pool")
2022-04-25 00:03:26 +00:00
}
2022-04-26 20:29:58 +00:00
return s.sqlToCommonPool(pool), nil
2022-04-25 00:03:26 +00:00
}
func (s *sqlDatabase) DeleteRepositoryPool(ctx context.Context, repoID, poolID string) error {
2022-04-26 20:29:58 +00:00
pool, err := s.getRepoPool(ctx, repoID, poolID)
if err != nil {
if errors.Is(err, runnerErrors.ErrNotFound) {
return nil
}
return errors.Wrap(err, "looking up repo pool")
}
q := s.conn.Delete(&pool)
if q.Error != nil && !errors.Is(q.Error, gorm.ErrRecordNotFound) {
return errors.Wrap(q.Error, "deleting pool")
}
2022-04-25 00:03:26 +00:00
return nil
}
func (s *sqlDatabase) DeleteOrganizationPool(ctx context.Context, orgID, poolID string) error {
2022-04-26 20:29:58 +00:00
pool, err := s.getOrgPool(ctx, orgID, poolID)
if err != nil {
if errors.Is(err, runnerErrors.ErrNotFound) {
return nil
}
return errors.Wrap(err, "looking up repo pool")
}
q := s.conn.Delete(&pool)
if q.Error != nil && !errors.Is(q.Error, gorm.ErrRecordNotFound) {
return errors.Wrap(q.Error, "deleting pool")
}
2022-04-25 00:03:26 +00:00
return nil
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) findPoolByTags(id, poolType string, tags []string) (params.Pool, error) {
if len(tags) == 0 {
return params.Pool{}, runnerErrors.NewBadRequestError("missing tags")
}
u := uuid.Parse(id)
if u == nil {
return params.Pool{}, errors.Wrap(runnerErrors.NewBadRequestError(""), "parsing id")
}
var pool Pool
where := fmt.Sprintf("tags.name in ? and %s = ?", poolType)
q := s.conn.Joins("JOIN pool_tags on pool_tags.pool_id=pools.id").
Joins("JOIN tags on tags.id=pool_tags.tag_id").
Group("pools.id").
Preload("Tags").
Having("count(1) = ?", len(tags)).
Where(where, tags, id).First(&pool)
if q.Error != nil {
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
return params.Pool{}, runnerErrors.ErrNotFound
}
return params.Pool{}, errors.Wrap(q.Error, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
}
func (s *sqlDatabase) FindRepositoryPoolByTags(ctx context.Context, repoID string, tags []string) (params.Pool, error) {
pool, err := s.findPoolByTags(repoID, "repo_id", tags)
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return pool, nil
}
func (s *sqlDatabase) FindOrganizationPoolByTags(ctx context.Context, orgID string, tags []string) (params.Pool, error) {
pool, err := s.findPoolByTags(orgID, "org_id", tags)
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return pool, nil
}
2022-04-27 16:56:28 +00:00
func (s *sqlDatabase) sqlAddressToParamsAddress(addr Address) params.Address {
return params.Address{
Address: addr.Address,
Type: params.AddressType(addr.Type),
}
}
func (s *sqlDatabase) sqlToParamsInstance(instance Instance) params.Instance {
ret := params.Instance{
ID: instance.ID.String(),
ProviderID: instance.ProviderID,
Name: instance.Name,
OSType: instance.OSType,
OSName: instance.OSName,
OSVersion: instance.OSVersion,
OSArch: instance.OSArch,
Status: instance.Status,
RunnerStatus: instance.RunnerStatus,
PoolID: instance.Pool.ID.String(),
CallbackURL: instance.CallbackURL,
}
for _, addr := range instance.Addresses {
ret.Addresses = append(ret.Addresses, s.sqlAddressToParamsAddress(addr))
}
return ret
}
2022-04-26 20:29:58 +00:00
func (s *sqlDatabase) CreateInstance(ctx context.Context, poolID string, param params.CreateInstanceParams) (params.Instance, error) {
2022-04-27 16:56:28 +00:00
pool, err := s.getPoolByID(ctx, param.Pool)
if err != nil {
return params.Instance{}, errors.Wrap(err, "fetching pool")
}
newInstance := Instance{
Pool: pool,
Name: param.Name,
Status: param.Status,
RunnerStatus: param.RunnerStatus,
OSType: param.OSType,
OSArch: param.OSArch,
CallbackURL: param.CallbackURL,
}
q := s.conn.Create(&newInstance)
if q.Error != nil {
return params.Instance{}, errors.Wrap(q.Error, "creating repository")
}
return s.sqlToParamsInstance(newInstance), nil
}
// func (s *sqlDatabase) GetInstance(ctx context.Context, poolID string, instanceID string) (params.Instance, error) {
// return params.Instance{}, nil
// }
func (s *sqlDatabase) getInstanceByID(ctx context.Context, instanceID string) (Instance, error) {
u := uuid.Parse(instanceID)
if u == nil {
return Instance{}, errors.Wrap(runnerErrors.ErrBadRequest, "parsing id")
}
var instance Instance
q := s.conn.Model(&Instance{}).
Preload(clause.Associations).
Where("id = ?", u).
First(&instance)
if q.Error != nil {
return Instance{}, errors.Wrap(q.Error, "fetching instance")
}
return instance, nil
2022-04-26 20:29:58 +00:00
}
2022-04-27 16:56:28 +00:00
func (s *sqlDatabase) getInstanceByName(ctx context.Context, poolID string, instanceName string) (Instance, error) {
pool, err := s.getPoolByID(ctx, poolID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return Instance{}, errors.Wrap(runnerErrors.ErrNotFound, "fetching instance")
}
return Instance{}, errors.Wrap(err, "fetching pool")
}
var instance Instance
q := s.conn.Model(&Instance{}).
Preload(clause.Associations).
Where("name = ? and pool_id = ?", instanceName, pool.ID).
First(&instance)
if q.Error != nil {
return Instance{}, errors.Wrap(q.Error, "fetching instance")
}
return instance, nil
}
func (s *sqlDatabase) GetInstanceByName(ctx context.Context, poolID string, instanceName string) (params.Instance, error) {
instance, err := s.getInstanceByName(ctx, poolID, instanceName)
if err != nil {
return params.Instance{}, errors.Wrap(err, "fetching instance")
}
return s.sqlToParamsInstance(instance), nil
}
func (s *sqlDatabase) DeleteInstance(ctx context.Context, poolID string, instanceName string) error {
instance, err := s.getInstanceByName(ctx, poolID, instanceName)
if err != nil {
if errors.Is(err, runnerErrors.ErrNotFound) {
return nil
}
return errors.Wrap(err, "deleting instance")
}
if q := s.conn.Delete(&instance); q.Error != nil {
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
return nil
}
return errors.Wrap(q.Error, "deleting instance")
}
2022-04-26 20:29:58 +00:00
return nil
}
func (s *sqlDatabase) UpdateInstance(ctx context.Context, instanceID string, param params.UpdateInstanceParams) (params.Instance, error) {
2022-04-27 16:56:28 +00:00
instance, err := s.getInstanceByID(ctx, instanceID)
if err != nil {
return params.Instance{}, errors.Wrap(err, "updating instance")
}
if param.ProviderID != "" {
instance.ProviderID = param.ProviderID
}
if param.OSName != "" {
instance.OSName = param.OSName
}
if param.OSVersion != "" {
instance.OSVersion = param.OSVersion
}
if string(param.RunnerStatus) != "" {
instance.RunnerStatus = param.RunnerStatus
}
if string(param.Status) != "" {
instance.Status = param.Status
}
q := s.conn.Save(&instance)
if q.Error != nil {
return params.Instance{}, errors.Wrap(q.Error, "updating instance")
}
if len(param.Addresses) > 0 {
addrs := []Address{}
for _, addr := range param.Addresses {
addrs = append(addrs, Address{
Address: addr.Address,
Type: string(addr.Type),
})
}
if err := s.conn.Model(&instance).Association("Addresses").Replace(addrs); err != nil {
return params.Instance{}, errors.Wrap(err, "updating addresses")
}
}
return s.sqlToParamsInstance(instance), nil
2022-04-26 20:29:58 +00:00
}
func (s *sqlDatabase) ListInstances(ctx context.Context, poolID string) ([]params.Instance, error) {
2022-04-27 16:56:28 +00:00
pool, err := s.getPoolByID(ctx, poolID)
if err != nil {
return nil, errors.Wrap(err, "fetching pool")
}
ret := make([]params.Instance, len(pool.Instances))
for idx, inst := range pool.Instances {
ret[idx] = s.sqlToParamsInstance(inst)
}
return ret, nil
2022-04-26 20:29:58 +00:00
}
func (s *sqlDatabase) ListRepoInstances(ctx context.Context, repoID string) ([]params.Instance, error) {
2022-04-27 16:56:28 +00:00
repo, err := s.getRepoByID(ctx, repoID)
if err != nil {
return nil, errors.Wrap(err, "fetching repo")
}
ret := []params.Instance{}
for _, pool := range repo.Pools {
for _, instance := range pool.Instances {
ret = append(ret, s.sqlToParamsInstance(instance))
}
}
return ret, nil
2022-04-26 20:29:58 +00:00
}
func (s *sqlDatabase) ListOrgInstances(ctx context.Context, orgID string) ([]params.Instance, error) {
2022-04-27 16:56:28 +00:00
org, err := s.getOrgByID(ctx, orgID)
if err != nil {
return nil, errors.Wrap(err, "fetching org")
}
ret := []params.Instance{}
for _, pool := range org.Pools {
for _, instance := range pool.Instances {
ret = append(ret, s.sqlToParamsInstance(instance))
}
}
return ret, nil
2022-04-26 20:29:58 +00:00
}
2022-04-27 16:56:28 +00:00
func (s *sqlDatabase) UpdateRepositoryPool(ctx context.Context, repoID, poolID string, param params.UpdatePoolParams) (params.Pool, error) {
return params.Pool{}, nil
2022-04-26 20:29:58 +00:00
}
2022-04-27 16:56:28 +00:00
func (s *sqlDatabase) UpdateOrganizationPool(ctx context.Context, orgID, poolID string, param params.UpdatePoolParams) (params.Pool, error) {
return params.Pool{}, nil
2022-04-26 20:29:58 +00:00
}