mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-29 16:58:24 +00:00
* feat: atlantis import * feat: atlantis import * regenerate mock comment builder * remove duplicate err check * instrumented import command runner/builder * atlantis import subcommand accept args before hyphen * fix link checker * docs: review feedback * fix atlantis import options order * Update runatlantis.io/docs/using-atlantis.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/using-atlantis.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/using-atlantis.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/using-atlantis.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/using-atlantis.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update server/events/comment_parser.go Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update server/events/comment_parser.go Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/server-side-repo-config.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update runatlantis.io/docs/command-requirements.md Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update server/events/command_requirement_handler.go Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * Update server/events/command_requirement_handler_test.go Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com> * fix test import usage * fix e2e expected txt * fix doc link * docs: workflow import stage/step * docs fixup Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
164 lines
5.1 KiB
Go
164 lines
5.1 KiB
Go
package raw
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
validation "github.com/go-ozzo/ozzo-validation"
|
|
version "github.com/hashicorp/go-version"
|
|
"github.com/pkg/errors"
|
|
"github.com/runatlantis/atlantis/server/core/config/valid"
|
|
)
|
|
|
|
const (
|
|
DefaultWorkspace = "default"
|
|
ApprovedRequirement = "approved"
|
|
MergeableRequirement = "mergeable"
|
|
UnDivergedRequirement = "undiverged"
|
|
)
|
|
|
|
type Project struct {
|
|
Name *string `yaml:"name,omitempty"`
|
|
Branch *string `yaml:"branch,omitempty"`
|
|
Dir *string `yaml:"dir,omitempty"`
|
|
Workspace *string `yaml:"workspace,omitempty"`
|
|
Workflow *string `yaml:"workflow,omitempty"`
|
|
TerraformVersion *string `yaml:"terraform_version,omitempty"`
|
|
Autoplan *Autoplan `yaml:"autoplan,omitempty"`
|
|
ApplyRequirements []string `yaml:"apply_requirements,omitempty"`
|
|
ImportRequirements []string `yaml:"import_requirements,omitempty"`
|
|
DeleteSourceBranchOnMerge *bool `yaml:"delete_source_branch_on_merge,omitempty"`
|
|
RepoLocking *bool `yaml:"repo_locking,omitempty"`
|
|
ExecutionOrderGroup *int `yaml:"execution_order_group,omitempty"`
|
|
}
|
|
|
|
func (p Project) Validate() error {
|
|
hasDotDot := func(value interface{}) error {
|
|
if strings.Contains(*value.(*string), "..") {
|
|
return errors.New("cannot contain '..'")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
validName := func(value interface{}) error {
|
|
strPtr := value.(*string)
|
|
if strPtr == nil {
|
|
return nil
|
|
}
|
|
if *strPtr == "" {
|
|
return errors.New("if set cannot be empty")
|
|
}
|
|
if !validProjectName(*strPtr) {
|
|
return fmt.Errorf("%q is not allowed: must contain only URL safe characters", *strPtr)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
branchValid := func(value interface{}) error {
|
|
strPtr := value.(*string)
|
|
if strPtr == nil {
|
|
return nil
|
|
}
|
|
branch := *strPtr
|
|
if !strings.HasPrefix(branch, "/") || !strings.HasSuffix(branch, "/") {
|
|
return errors.New("regex must begin and end with a slash '/'")
|
|
}
|
|
withoutSlashes := branch[1 : len(branch)-1]
|
|
_, err := regexp.Compile(withoutSlashes)
|
|
return errors.Wrapf(err, "parsing: %s", branch)
|
|
}
|
|
|
|
return validation.ValidateStruct(&p,
|
|
validation.Field(&p.Dir, validation.Required, validation.By(hasDotDot)),
|
|
validation.Field(&p.ApplyRequirements, validation.By(validApplyReq)),
|
|
validation.Field(&p.ImportRequirements, validation.By(validImportReq)),
|
|
validation.Field(&p.TerraformVersion, validation.By(VersionValidator)),
|
|
validation.Field(&p.Name, validation.By(validName)),
|
|
validation.Field(&p.Branch, validation.By(branchValid)),
|
|
)
|
|
}
|
|
|
|
func (p Project) ToValid() valid.Project {
|
|
var v valid.Project
|
|
// Prepend ./ and then run .Clean() so we're guaranteed to have a relative
|
|
// directory. This is necessary because we use this dir without sanitation
|
|
// in DefaultProjectFinder.
|
|
cleanedDir := filepath.Clean("./" + *p.Dir)
|
|
v.Dir = cleanedDir
|
|
|
|
if p.Branch != nil {
|
|
branch := *p.Branch
|
|
withoutSlashes := branch[1 : len(branch)-1]
|
|
// Safe to use MustCompile because we test it in Validate().
|
|
v.BranchRegex = regexp.MustCompile(withoutSlashes)
|
|
}
|
|
|
|
if p.Workspace == nil || *p.Workspace == "" {
|
|
v.Workspace = DefaultWorkspace
|
|
} else {
|
|
v.Workspace = *p.Workspace
|
|
}
|
|
|
|
v.WorkflowName = p.Workflow
|
|
if p.TerraformVersion != nil {
|
|
v.TerraformVersion, _ = version.NewVersion(*p.TerraformVersion)
|
|
}
|
|
if p.Autoplan == nil {
|
|
v.Autoplan = DefaultAutoPlan()
|
|
} else {
|
|
v.Autoplan = p.Autoplan.ToValid()
|
|
}
|
|
|
|
// There are no default apply/import requirements.
|
|
v.ApplyRequirements = p.ApplyRequirements
|
|
v.ImportRequirements = p.ImportRequirements
|
|
|
|
v.Name = p.Name
|
|
|
|
if p.DeleteSourceBranchOnMerge != nil {
|
|
v.DeleteSourceBranchOnMerge = p.DeleteSourceBranchOnMerge
|
|
}
|
|
|
|
if p.RepoLocking != nil {
|
|
v.RepoLocking = p.RepoLocking
|
|
}
|
|
|
|
if p.ExecutionOrderGroup != nil {
|
|
v.ExecutionOrderGroup = *p.ExecutionOrderGroup
|
|
}
|
|
|
|
return v
|
|
}
|
|
|
|
// validProjectName returns true if the project name is valid.
|
|
// Since the name might be used in URLs and definitely in files we don't
|
|
// support any characters that must be url escaped *except* for '/' because
|
|
// users like to name their projects to match the directory it's in.
|
|
func validProjectName(name string) bool {
|
|
nameWithoutSlashes := strings.Replace(name, "/", "-", -1)
|
|
return nameWithoutSlashes == url.QueryEscape(nameWithoutSlashes)
|
|
}
|
|
|
|
func validApplyReq(value interface{}) error {
|
|
reqs := value.([]string)
|
|
for _, r := range reqs {
|
|
if r != ApprovedRequirement && r != MergeableRequirement && r != UnDivergedRequirement {
|
|
return fmt.Errorf("%q is not a valid apply_requirement, only %q, %q and %q are supported", r, ApprovedRequirement, MergeableRequirement, UnDivergedRequirement)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validImportReq(value interface{}) error {
|
|
reqs := value.([]string)
|
|
for _, r := range reqs {
|
|
if r != ApprovedRequirement && r != MergeableRequirement && r != UnDivergedRequirement {
|
|
return fmt.Errorf("%q is not a valid import_requirement, only %q, %q and %q are supported", r, ApprovedRequirement, MergeableRequirement, UnDivergedRequirement)
|
|
}
|
|
}
|
|
return nil
|
|
}
|