Semaphore/db/Template.go

191 lines
4.7 KiB
Go
Raw Normal View History

2017-02-23 06:12:16 +01:00
package db
2016-04-04 15:44:34 +02:00
2021-11-02 20:30:45 +01:00
import (
"encoding/json"
)
type TemplateType string
const (
TemplateTask TemplateType = ""
TemplateBuild TemplateType = "build"
TemplateDeploy TemplateType = "deploy"
)
type TemplateApp string
const (
TemplateAnsible TemplateApp = ""
TemplateTerraform TemplateApp = "terraform"
TemplateTofu TemplateApp = "tofu"
TemplateBash TemplateApp = "bash"
TemplatePulumi TemplateApp = "pulumi"
)
func (t TemplateApp) IsTerraform() bool {
return t == TemplateTerraform || t == TemplateTofu
}
2022-01-19 13:44:56 +01:00
type SurveyVarType string
const (
2024-05-19 21:32:16 +02:00
SurveyVarStr TemplateType = ""
SurveyVarInt TemplateType = "int"
SurveyVarEnum TemplateType = "enum"
2022-01-19 13:44:56 +01:00
)
2024-05-19 21:32:16 +02:00
type SurveyVarEnumValue struct {
Name string `json:"name"`
Value string `json:"value"`
}
2022-01-19 13:05:48 +01:00
type SurveyVar struct {
2024-05-19 21:32:16 +02:00
Name string `json:"name"`
Title string `json:"title"`
Required bool `json:"required"`
Type SurveyVarType `json:"type"`
Description string `json:"description"`
Values []SurveyVarEnumValue `json:"values"`
2022-01-19 13:05:48 +01:00
}
2022-01-19 20:35:59 +01:00
type TemplateFilter struct {
ViewID *int
BuildTemplateID *int
AutorunOnly bool
}
// Template is a user defined model that is used to run a task
2016-04-04 15:44:34 +02:00
type Template struct {
ID int `db:"id" json:"id"`
ProjectID int `db:"project_id" json:"project_id"`
InventoryID *int `db:"inventory_id" json:"inventory_id"`
RepositoryID int `db:"repository_id" json:"repository_id"`
EnvironmentID *int `db:"environment_id" json:"environment_id"`
2022-02-03 08:05:13 +01:00
// Name as described in https://github.com/ansible-semaphore/semaphore/issues/188
Name string `db:"name" json:"name"`
// playbook name in the form of "some_play.yml"
Playbook string `db:"playbook" json:"playbook"`
// to fit into []string
Arguments *string `db:"arguments" json:"arguments"`
// if true, semaphore will not prepend any arguments to `arguments` like inventory, etc
AllowOverrideArgsInTask bool `db:"allow_override_args_in_task" json:"allow_override_args_in_task"`
2021-08-30 21:42:11 +02:00
Description *string `db:"description" json:"description"`
VaultKeyID *int `db:"vault_key_id" json:"vault_key_id"`
VaultKey AccessKey `db:"-" json:"-"`
Type TemplateType `db:"type" json:"type"`
2021-10-12 15:59:16 +02:00
StartVersion *string `db:"start_version" json:"start_version"`
BuildTemplateID *int `db:"build_template_id" json:"build_template_id"`
2021-10-26 20:19:12 +02:00
ViewID *int `db:"view_id" json:"view_id"`
LastTask *TaskWithTpl `db:"-" json:"last_task"`
2022-01-16 21:14:44 +01:00
2022-01-19 20:35:59 +01:00
Autorun bool `db:"autorun" json:"autorun"`
2022-01-18 20:17:48 +01:00
2022-01-19 13:05:48 +01:00
// SurveyVarsJSON used internally for read from database.
// It is not used for store survey vars to database.
// Do not use it in your code. Use SurveyVars instead.
SurveyVarsJSON *string `db:"survey_vars" json:"-"`
SurveyVars []SurveyVar `db:"-" json:"survey_vars"`
SuppressSuccessAlerts bool `db:"suppress_success_alerts" json:"suppress_success_alerts"`
App TemplateApp `db:"app" json:"app"`
2024-06-30 09:48:36 +02:00
Tasks int `db:"tasks" json:"tasks"`
}
2021-11-02 20:30:45 +01:00
func (tpl *Template) Validate() error {
switch tpl.App {
case TemplateAnsible:
if tpl.InventoryID == nil {
return &ValidationError{"template inventory can not be empty"}
}
}
2022-02-03 08:05:13 +01:00
if tpl.Name == "" {
return &ValidationError{"template name can not be empty"}
2021-11-02 20:30:45 +01:00
}
if !tpl.App.IsTerraform() && tpl.Playbook == "" {
2021-11-02 20:30:45 +01:00
return &ValidationError{"template playbook can not be empty"}
}
if tpl.Arguments != nil {
if !json.Valid([]byte(*tpl.Arguments)) {
return &ValidationError{"template arguments must be valid JSON"}
}
}
return nil
}
func FillTemplates(d Store, templates []Template) (err error) {
2024-06-29 18:23:41 +02:00
var templateIDs []int
var projectID int
if len(templates) == 0 {
return
}
projectID = templates[0].ProjectID
for _, tpl := range templates {
if tpl.ProjectID != projectID {
err = &ValidationError{"templates must be from the same project"}
return
}
2024-06-29 18:23:41 +02:00
templateIDs = append(templateIDs, tpl.ID)
}
var tasks []TaskWithTpl
tasks, err = d.GetTemplateTasks(projectID, templateIDs, RetrieveQueryParams{Count: 1})
for _, task := range tasks {
i := findIntIndex(templateIDs, task.TemplateID)
if i >= 0 {
templates[i].LastTask = &task
}
}
return
}
func FillTemplate(d Store, template *Template) (err error) {
if template.VaultKeyID != nil {
template.VaultKey, err = d.GetAccessKey(template.ProjectID, *template.VaultKeyID)
}
if err != nil {
return
}
err = FillTemplates(d, []Template{*template})
2022-01-19 13:05:48 +01:00
if err != nil {
return
}
2023-06-13 11:35:24 +02:00
var tasks []TaskWithTpl
2024-06-29 18:23:41 +02:00
tasks, err = d.GetTemplateTasks(template.ProjectID, []int{template.ID}, RetrieveQueryParams{Count: 1})
2023-06-13 11:35:24 +02:00
if err != nil {
return
}
if len(tasks) > 0 {
template.LastTask = &tasks[0]
}
2022-01-19 13:05:48 +01:00
2023-06-13 12:08:29 +02:00
if template.SurveyVarsJSON != nil {
err = json.Unmarshal([]byte(*template.SurveyVarsJSON), &template.SurveyVars)
}
return
}