Files
paralus/internal/dao/bootstrap.go
Abin Simon df810ab45a Convert from dao interface to funcs
This was done inorder to support transactions which will be done in
the next PR. This is the first step towards that.
2022-03-16 17:10:32 +05:30

288 lines
8.7 KiB
Go

package dao
import (
"context"
"errors"
"fmt"
"time"
"github.com/RafaySystems/rcloud-base/internal/models"
"github.com/RafaySystems/rcloud-base/internal/persistence/provider/pg"
"github.com/RafaySystems/rcloud-base/internal/random"
"github.com/RafaySystems/rcloud-base/pkg/query"
commonv3 "github.com/RafaySystems/rcloud-base/proto/types/commonpb/v3"
"github.com/RafaySystems/rcloud-base/proto/types/sentry"
"github.com/google/uuid"
"github.com/uptrace/bun"
)
func CreateOrUpdateBootstrapInfra(ctx context.Context, db bun.IDB, infra *models.BootstrapInfra) error {
_, err := db.NewInsert().On("CONFLICT (name) DO UPDATE").
Set("ca_cert = ?", infra.CaCert).
Set("ca_key = ?", infra.CaKey).
Set("modified_at = ?", time.Now()).
Model(infra).
Where("bi.name = ?", infra.Name).Exec(ctx)
return err
}
func CreateOrUpdateBootstrapAgentTemplate(ctx context.Context, db bun.IDB, template *models.BootstrapAgentTemplate) error {
_, err := db.NewInsert().On("CONFLICT (name) DO UPDATE").
Set("infra_ref = ?", template.InfraRef).
Set("ignore_multiple_register = ?", template.IgnoreMultipleRegister).
Set("auto_register = ?", template.AutoRegister).
Set("incluster_template = ?", template.InclusterTemplate).
Set("outofcluster_template = ?", template.OutofclusterTemplate).
Set("hosts = ?", template.Hosts).
Set("labels = ?", template.Labels).
Set("annotations = ?", template.Annotations).
Set("modified_at = ?", time.Now()).
Model(template).
Where("bat.name = ?", template.Name).Exec(ctx)
return err
}
func GetBootstrapAgentTemplateForToken(ctx context.Context, db bun.IDB, token string) (*models.BootstrapAgentTemplate, error) {
var template models.BootstrapAgentTemplate
err := db.NewSelect().Model(&template).Where("token = ?", token).Scan(ctx)
return &template, err
}
func SelectBootstrapAgentTemplates(ctx context.Context, db bun.IDB, opts *commonv3.QueryOptions) (ret []models.BootstrapAgentTemplate, count int, err error) {
q, err := query.Select(db.NewSelect().Model(&ret), opts)
if err != nil {
return
}
q = query.Paginate(q, opts)
count, err = q.ScanAndCount(ctx)
return
}
func DeleteBootstrapAgentTempate(ctx context.Context, db bun.IDB, opts *commonv3.QueryOptions, infraRef string) error {
q, err := query.Delete(db.NewSelect().Model((*models.BootstrapAgentTemplate)(nil)), opts)
if err != nil {
return err
}
_, err = q.Exec(ctx)
return err
}
func GetBootstrapAgent(ctx context.Context, db bun.IDB, templateRef string, opts *commonv3.QueryOptions) (*models.BootstrapAgent, error) {
var ba models.BootstrapAgent
q, err := query.Get(db.NewSelect().Model(&ba), opts)
if err != nil {
return nil, err
}
// - will be used to select all the agents
// to cross template boundaries
if templateRef != "-" {
q = q.Where("template_ref = ?", templateRef)
}
err = q.Scan(ctx)
return &ba, err
}
func GetBootstrapAgents(ctx context.Context, db bun.IDB, opts *commonv3.QueryOptions, templateRef string) (ret []models.BootstrapAgent, count int, err error) {
q, err := query.Get(db.NewSelect().Model(&ret), opts)
if err != nil {
return nil, 0, err
}
if templateRef != "-" {
q = q.Where("template_ref = ?", templateRef)
}
count, err = q.ScanAndCount(ctx)
return
}
func SelectBootstrapAgents(ctx context.Context, db bun.IDB, templateRef string, opts *commonv3.QueryOptions) (ret []models.BootstrapAgent, count int, err error) {
q, err := query.Select(db.NewSelect().Model(&ret), opts)
if err != nil {
return
}
if templateRef != "-" {
q = q.Where("template_ref = ?", templateRef)
}
count, err = q.ScanAndCount(ctx)
return
}
func CreateBootstrapAgent(ctx context.Context, db bun.IDB, ba *models.BootstrapAgent) error {
ba.TokenState = sentry.BootstrapAgentState_NotRegistered.String()
_, err := pg.Create(ctx, db, ba)
return err
}
// We are explicitly taking in Tx here as it was previously doing RunInTx
// TODO: should we take Tx here or just assume we will be passed in a tx? Or should we create one?
func RegisterBootstrapAgent(ctx context.Context, db bun.Tx, token string) error {
ba, err := getBootstrapAgentForToken(ctx, db, token)
if err != nil {
return err
}
bat, err := getBootstrapAgentTemplate(ctx, db, ba.TemplateRef)
if err != nil {
return err
}
state := sentry.BootstrapAgentState_NotApproved
if bat.AutoApprove {
state = sentry.BootstrapAgentState_Approved
}
switch ba.TokenState {
case sentry.BootstrapAgentState_NotRegistered.String():
ba.TokenState = sentry.BootstrapAgentState_Approved.String()
case sentry.BootstrapAgentState_NotApproved.String(), sentry.BootstrapAgentState_Approved.String():
if !bat.IgnoreMultipleRegister {
return fmt.Errorf("cannot register token %s state is %s", token, ba.TokenState)
}
default:
return fmt.Errorf("invalid token state %s", ba.TokenState)
}
_, err = db.NewUpdate().Model(ba).
Set("token_state = ?", state).
Where("token = ?", token).
Exec(ctx)
return err
}
func getBootstrapAgentForToken(ctx context.Context, db bun.IDB, token string) (*models.BootstrapAgent, error) {
var ba models.BootstrapAgent
err := db.NewSelect().Model(&ba).Where("token = ?", token).Scan(ctx)
return &ba, err
}
func getBootstrapAgentTemplate(ctx context.Context, db bun.IDB, name string) (*models.BootstrapAgentTemplate, error) {
var template models.BootstrapAgentTemplate
err := db.NewSelect().Model(&template).Where("name = ?", name).Scan(ctx)
return &template, err
}
func DeleteBootstrapAgent(ctx context.Context, db bun.IDB, templateRef string, opts *commonv3.QueryOptions) error {
dq := db.NewDelete().Model((*models.BootstrapAgent)(nil)).Where("name = ?", opts.ID)
if templateRef != "" {
dq = dq.Where("template_ref = ?", templateRef)
}
_, err := dq.Exec(ctx)
return err
}
func UpdateBootstrapAgent(ctx context.Context, db bun.IDB, ba *models.BootstrapAgent, opts *commonv3.QueryOptions) error {
_, err := db.NewUpdate().Model(ba).Where("id = ?", ba.ID).Returning("*").Exec(ctx)
return err
}
func GetBootstrapAgentForToken(ctx context.Context, db bun.IDB, token string) (*models.BootstrapAgent, error) {
var ba models.BootstrapAgent
err := db.NewSelect().Model(&ba).Where("token = ?", token).Scan(ctx)
return &ba, err
}
func GetBootstrapAgentTemplateForHost(ctx context.Context, db bun.IDB, host string) (*models.BootstrapAgentTemplate, error) {
bat := models.BootstrapAgentTemplate{}
err := db.NewSelect().Model(&bat).
ColumnExpr("bat.*").
Join("JOIN sentry_bootstrap_template_host as bth").
JoinOn("bat.name = bth.name").
JoinOn("bth.host = ?", host).
Scan(ctx)
return &bat, err
}
func GetBootstrapAgentCountForClusterID(ctx context.Context, db bun.IDB, clusterID string, orgID uuid.UUID) (int, error) {
var ba []models.BootstrapAgent
err := db.NewSelect().Model(&ba).
Where("name = ?", clusterID).
Where("organization_id = ?", orgID).
Scan(ctx)
if err != nil {
return 0, err
}
return len(ba), nil
}
func GetBootstrapAgentForClusterID(ctx context.Context, db bun.IDB, clusterID string, orgID uuid.UUID) (*models.BootstrapAgent, error) {
var ba models.BootstrapAgent
err := db.NewSelect().Model(&ba).
Where("name = ?", clusterID).
Where("organization_id = ?", orgID).
Scan(ctx)
if err != nil {
return nil, err
}
return &ba, nil
}
// updateBootstrapAgentDeleteAt builds query for deleting resource
func UpdateBootstrapAgentDeleteAt(ctx context.Context, db bun.IDB, templateRef string) error {
var toBeDeletedAgent *models.BootstrapAgent
_, err := pg.GetX(ctx, db, "template_ref", templateRef, &toBeDeletedAgent)
if err != nil {
return err
}
if toBeDeletedAgent == nil {
return errors.New("could not find bootstrap agent to delete")
}
opts := &commonv3.QueryOptions{}
query.WithName(toBeDeletedAgent.Name)(opts)
q, err := query.Update(db.NewUpdate().Model((*models.BootstrapAgent)(nil)), opts)
if err != nil {
return err
}
now := time.Now()
q = q.Set("name = ?", fmt.Sprintf("%s-%s", opts.Name, random.NewRandomString(10)))
q = q.Set("deleted_at = ?", &now)
_, err = q.Exec(ctx)
return err
}
func UpdateBootstrapAgentTempateDeleteAt(ctx context.Context, db bun.IDB, opts *commonv3.QueryOptions) error {
q, err := query.Update(db.NewUpdate().Model((*models.BootstrapAgentTemplate)(nil)), opts)
if err != nil {
return err
}
now := time.Now()
q = q.Set("name = ?", fmt.Sprintf("%s-%s", opts.Name, random.NewRandomString(10)))
q = q.Set("deleted_at = ?", &now)
_, err = q.Exec(ctx)
return err
}
// updateBootstrapInfraDeleteAt builds query for deleting resource
func UpdateBootstrapInfraDeleteAt(ctx context.Context, db bun.IDB, opts *commonv3.QueryOptions) error {
q, err := query.Update(db.NewUpdate().Model((*models.BootstrapInfra)(nil)), opts)
if err != nil {
return err
}
now := time.Now()
q = q.Set("deleted_at = ?", &now)
_, err = q.Exec(ctx)
return err
}