From a9cbe2dfc3b6493015a50f956f7b17333087e200 Mon Sep 17 00:00:00 2001 From: wsan3 Date: Tue, 9 Jul 2024 13:19:10 -0500 Subject: [PATCH] Add instance key to ruleset --- pipeline/container.go | 3 ++ pipeline/ruleset.go | 54 +++++++++++++++++------------- pipeline/ruleset_test.go | 18 ++++++++++ yaml/ruleset.go | 59 +++++++++++++++++--------------- yaml/ruleset_test.go | 72 +++++++++++++++++++++------------------- 5 files changed, 122 insertions(+), 84 deletions(-) diff --git a/pipeline/container.go b/pipeline/container.go index 8e2e55f1..85a96d8b 100644 --- a/pipeline/container.go +++ b/pipeline/container.go @@ -167,6 +167,9 @@ func (c *Container) Execute(r *RuleData) (bool, error) { c.Ruleset.If.Label = []string{} c.Ruleset.Unless.Label = []string{} + c.Ruleset.If.Instance = []string{} + c.Ruleset.Unless.Instance = []string{} + // check if the build is in a running state if strings.EqualFold(r.Status, constants.StatusRunning) { // treat the ruleset status as success diff --git a/pipeline/ruleset.go b/pipeline/ruleset.go index a27c8ea6..53126e6c 100644 --- a/pipeline/ruleset.go +++ b/pipeline/ruleset.go @@ -29,16 +29,17 @@ type ( // // swagger:model PipelineRules Rules struct { - Branch Ruletype `json:"branch,omitempty" yaml:"branch,omitempty"` - Comment Ruletype `json:"comment,omitempty" yaml:"comment,omitempty"` - Event Ruletype `json:"event,omitempty" yaml:"event,omitempty"` - Path Ruletype `json:"path,omitempty" yaml:"path,omitempty"` - Repo Ruletype `json:"repo,omitempty" yaml:"repo,omitempty"` - Status Ruletype `json:"status,omitempty" yaml:"status,omitempty"` - Tag Ruletype `json:"tag,omitempty" yaml:"tag,omitempty"` - Target Ruletype `json:"target,omitempty" yaml:"target,omitempty"` - Label Ruletype `json:"label,omitempty" yaml:"label,omitempty"` - Parallel bool `json:"-" yaml:"-"` + Branch Ruletype `json:"branch,omitempty" yaml:"branch,omitempty"` + Comment Ruletype `json:"comment,omitempty" yaml:"comment,omitempty"` + Event Ruletype `json:"event,omitempty" yaml:"event,omitempty"` + Path Ruletype `json:"path,omitempty" yaml:"path,omitempty"` + Repo Ruletype `json:"repo,omitempty" yaml:"repo,omitempty"` + Status Ruletype `json:"status,omitempty" yaml:"status,omitempty"` + Tag Ruletype `json:"tag,omitempty" yaml:"tag,omitempty"` + Target Ruletype `json:"target,omitempty" yaml:"target,omitempty"` + Label Ruletype `json:"label,omitempty" yaml:"label,omitempty"` + Instance Ruletype `json:"instance,omitempty" yaml:"instance,omitempty"` + Parallel bool `json:"-" yaml:"-"` } // Ruletype is the pipeline representation of an element @@ -50,16 +51,17 @@ type ( // RuleData is the data to check our ruleset // against for a step in a pipeline. RuleData struct { - Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` - Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` - Event string `json:"event,omitempty" yaml:"event,omitempty"` - Path []string `json:"path,omitempty" yaml:"path,omitempty"` - Repo string `json:"repo,omitempty" yaml:"repo,omitempty"` - Status string `json:"status,omitempty" yaml:"status,omitempty"` - Tag string `json:"tag,omitempty" yaml:"tag,omitempty"` - Target string `json:"target,omitempty" yaml:"target,omitempty"` - Label []string `json:"label,omitempty" yaml:"label,omitempty"` - Parallel bool `json:"-" yaml:"-"` + Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` + Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` + Event string `json:"event,omitempty" yaml:"event,omitempty"` + Path []string `json:"path,omitempty" yaml:"path,omitempty"` + Repo string `json:"repo,omitempty" yaml:"repo,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Tag string `json:"tag,omitempty" yaml:"tag,omitempty"` + Target string `json:"target,omitempty" yaml:"target,omitempty"` + Label []string `json:"label,omitempty" yaml:"label,omitempty"` + Instance string `json:"instance,omitempty" yaml:"instance,omitempty"` + Parallel bool `json:"-" yaml:"-"` } ) @@ -114,7 +116,8 @@ func (r *Rules) Empty() bool { len(r.Status) == 0 && len(r.Tag) == 0 && len(r.Target) == 0 && - len(r.Label) == 0 { + len(r.Label) == 0 && + len(r.Instance) == 0 { return true } @@ -180,11 +183,16 @@ func (r *Rules) Match(from *RuleData, matcher, op string) (bool, error) { return false, err } + matchInstance, err := r.Instance.MatchSingle(from.Instance, matcher, op) + if err != nil { + return false, err + } + switch op { case constants.OperatorOr: - return (matchBranch || matchComment || matchEvent || matchPath || matchRepo || matchTag || matchTarget || matchLabel || status), nil + return (matchBranch || matchComment || matchEvent || matchPath || matchRepo || matchTag || matchTarget || matchLabel || matchInstance || status), nil default: - return (matchBranch && matchComment && matchEvent && matchPath && matchRepo && matchTag && matchTarget && matchLabel && status), nil + return (matchBranch && matchComment && matchEvent && matchPath && matchRepo && matchTag && matchTarget && matchLabel && matchInstance && status), nil } } diff --git a/pipeline/ruleset_test.go b/pipeline/ruleset_test.go index 7ea87a31..26a23823 100644 --- a/pipeline/ruleset_test.go +++ b/pipeline/ruleset_test.go @@ -471,6 +471,18 @@ func TestPipeline_Rules_Match(t *testing.T) { operator: "or", want: true, }, + { + rules: &Rules{Event: []string{"push"}, Instance: []string{"http://localhost:8080"}}, + data: &RuleData{Branch: "main", Event: "push", Repo: "octocat/hello-world", Status: "pending", Instance: "http://localhost:5432"}, + operator: "and", + want: false, + }, + { + rules: &Rules{Event: []string{"push"}, Instance: []string{"http://localhost:8080"}}, + data: &RuleData{Branch: "main", Event: "push", Repo: "octocat/hello-world", Status: "pending", Instance: "http://localhost:8080"}, + operator: "and", + want: true, + }, } // run test @@ -567,6 +579,9 @@ func TestPipeline_Ruletype_MatchAnd(t *testing.T) { // Label with regexp matcher {matcher: "regexp", rule: []string{"enhancement", "documentation"}, pattern: "documentation", want: true}, {matcher: "regexp", rule: []string{"enhancement", "documentation"}, pattern: "question", want: false}, + // Instance with regexp matcher + {matcher: "regexp", rule: []string{"http://localhost:8080", "http://localhost:1234"}, pattern: "http://localhost:5432", want: false}, + {matcher: "regexp", rule: []string{"http://localhost:8080", "http://localhost:1234"}, pattern: "http://localhost:8080", want: true}, } // run test @@ -647,6 +662,9 @@ func TestPipeline_Ruletype_MatchOr(t *testing.T) { // Label with regexp matcher {matcher: "regexp", rule: []string{"enhancement", "documentation"}, pattern: "documentation", want: true}, {matcher: "regexp", rule: []string{"enhancement", "documentation"}, pattern: "question", want: false}, + // Instance with regexp matcher + {matcher: "regexp", rule: []string{"http://localhost:8080", "http://localhost:1234"}, pattern: "http://localhost:5432", want: false}, + {matcher: "regexp", rule: []string{"http://localhost:8080", "http://localhost:1234"}, pattern: "http://localhost:8080", want: true}, } // run test diff --git a/yaml/ruleset.go b/yaml/ruleset.go index 4a6d87f7..ce7fb227 100644 --- a/yaml/ruleset.go +++ b/yaml/ruleset.go @@ -22,15 +22,16 @@ type ( // Rules is the yaml representation of the ruletypes // from a ruleset block for a step in a pipeline. Rules struct { - Branch []string `yaml:"branch,omitempty,flow" json:"branch,omitempty" jsonschema:"description=Limits the execution of a step to matching build branches.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Comment []string `yaml:"comment,omitempty,flow" json:"comment,omitempty" jsonschema:"description=Limits the execution of a step to matching a pull request comment.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Event []string `yaml:"event,omitempty,flow" json:"event,omitempty" jsonschema:"description=Limits the execution of a step to matching build events.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Path []string `yaml:"path,omitempty,flow" json:"path,omitempty" jsonschema:"description=Limits the execution of a step to matching files changed in a repository.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Repo []string `yaml:"repo,omitempty,flow" json:"repo,omitempty" jsonschema:"description=Limits the execution of a step to matching repos.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Status []string `yaml:"status,omitempty,flow" json:"status,omitempty" jsonschema:"enum=[failure],enum=[success],description=Limits the execution of a step to matching build statuses.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Tag []string `yaml:"tag,omitempty,flow" json:"tag,omitempty" jsonschema:"description=Limits the execution of a step to matching build tag references.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Target []string `yaml:"target,omitempty,flow" json:"target,omitempty" jsonschema:"description=Limits the execution of a step to matching build deployment targets.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` - Label []string `yaml:"label,omitempty,flow" json:"label,omitempty" jsonschema:"description=Limits step execution to match on pull requests labels.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Branch []string `yaml:"branch,omitempty,flow" json:"branch,omitempty" jsonschema:"description=Limits the execution of a step to matching build branches.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Comment []string `yaml:"comment,omitempty,flow" json:"comment,omitempty" jsonschema:"description=Limits the execution of a step to matching a pull request comment.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Event []string `yaml:"event,omitempty,flow" json:"event,omitempty" jsonschema:"description=Limits the execution of a step to matching build events.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Path []string `yaml:"path,omitempty,flow" json:"path,omitempty" jsonschema:"description=Limits the execution of a step to matching files changed in a repository.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Repo []string `yaml:"repo,omitempty,flow" json:"repo,omitempty" jsonschema:"description=Limits the execution of a step to matching repos.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Status []string `yaml:"status,omitempty,flow" json:"status,omitempty" jsonschema:"enum=[failure],enum=[success],description=Limits the execution of a step to matching build statuses.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Tag []string `yaml:"tag,omitempty,flow" json:"tag,omitempty" jsonschema:"description=Limits the execution of a step to matching build tag references.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Target []string `yaml:"target,omitempty,flow" json:"target,omitempty" jsonschema:"description=Limits the execution of a step to matching build deployment targets.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Label []string `yaml:"label,omitempty,flow" json:"label,omitempty" jsonschema:"description=Limits step execution to match on pull requests labels.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` + Instance []string `yaml:"instance,omitempty,flow" json:"instance,omitempty" jsonschema:"description=Limits step execution to match on certain instances.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-tag"` } ) @@ -86,6 +87,7 @@ func (r *Ruleset) UnmarshalYAML(unmarshal func(interface{}) error) error { advanced.If.Tag = append(advanced.If.Tag, simple.Tag...) advanced.If.Target = append(advanced.If.Target, simple.Target...) advanced.If.Label = append(advanced.If.Label, simple.Label...) + advanced.If.Instance = append(advanced.If.Instance, simple.Instance...) // set ruleset `if` to advanced `if` rules r.If = advanced.If @@ -107,15 +109,16 @@ func (r *Ruleset) UnmarshalYAML(unmarshal func(interface{}) error) error { // type to a pipeline Rules type. func (r *Rules) ToPipeline() *pipeline.Rules { return &pipeline.Rules{ - Branch: r.Branch, - Comment: r.Comment, - Event: r.Event, - Path: r.Path, - Repo: r.Repo, - Status: r.Status, - Tag: r.Tag, - Target: r.Target, - Label: r.Label, + Branch: r.Branch, + Comment: r.Comment, + Event: r.Event, + Path: r.Path, + Repo: r.Repo, + Status: r.Status, + Tag: r.Tag, + Target: r.Target, + Label: r.Label, + Instance: r.Instance, } } @@ -123,15 +126,16 @@ func (r *Rules) ToPipeline() *pipeline.Rules { func (r *Rules) UnmarshalYAML(unmarshal func(interface{}) error) error { // rules struct we try unmarshalling to rules := new(struct { - Branch raw.StringSlice - Comment raw.StringSlice - Event raw.StringSlice - Path raw.StringSlice - Repo raw.StringSlice - Status raw.StringSlice - Tag raw.StringSlice - Target raw.StringSlice - Label raw.StringSlice + Branch raw.StringSlice + Comment raw.StringSlice + Event raw.StringSlice + Path raw.StringSlice + Repo raw.StringSlice + Status raw.StringSlice + Tag raw.StringSlice + Target raw.StringSlice + Label raw.StringSlice + Instance raw.StringSlice }) // attempt to unmarshal rules @@ -145,6 +149,7 @@ func (r *Rules) UnmarshalYAML(unmarshal func(interface{}) error) error { r.Tag = rules.Tag r.Target = rules.Target r.Label = rules.Label + r.Instance = rules.Instance // account for users who use non-scoped pull_request event events := []string{} diff --git a/yaml/ruleset_test.go b/yaml/ruleset_test.go index 9b95f304..2d674c0f 100644 --- a/yaml/ruleset_test.go +++ b/yaml/ruleset_test.go @@ -21,25 +21,27 @@ func TestYaml_Ruleset_ToPipeline(t *testing.T) { { ruleset: &Ruleset{ If: Rules{ - Branch: []string{"main"}, - Comment: []string{"test comment"}, - Event: []string{"push", "pull_request:labeled"}, - Path: []string{"foo.txt"}, - Repo: []string{"github/octocat"}, - Status: []string{"success"}, - Tag: []string{"v0.1.0"}, - Target: []string{"production"}, - Label: []string{"enhancement"}, + Branch: []string{"main"}, + Comment: []string{"test comment"}, + Event: []string{"push", "pull_request:labeled"}, + Path: []string{"foo.txt"}, + Repo: []string{"github/octocat"}, + Status: []string{"success"}, + Tag: []string{"v0.1.0"}, + Target: []string{"production"}, + Label: []string{"enhancement"}, + Instance: []string{"http://localhost:8080"}, }, Unless: Rules{ - Branch: []string{"main"}, - Comment: []string{"real comment"}, - Event: []string{"pull_request"}, - Path: []string{"bar.txt"}, - Repo: []string{"github/octocat"}, - Status: []string{"failure"}, - Tag: []string{"v0.2.0"}, - Target: []string{"production"}, + Branch: []string{"main"}, + Comment: []string{"real comment"}, + Event: []string{"pull_request"}, + Path: []string{"bar.txt"}, + Repo: []string{"github/octocat"}, + Status: []string{"failure"}, + Tag: []string{"v0.2.0"}, + Target: []string{"production"}, + Instance: []string{"http://localhost:8080"}, }, Matcher: "filepath", Operator: "and", @@ -47,25 +49,27 @@ func TestYaml_Ruleset_ToPipeline(t *testing.T) { }, want: &pipeline.Ruleset{ If: pipeline.Rules{ - Branch: []string{"main"}, - Comment: []string{"test comment"}, - Event: []string{"push", "pull_request:labeled"}, - Path: []string{"foo.txt"}, - Repo: []string{"github/octocat"}, - Status: []string{"success"}, - Tag: []string{"v0.1.0"}, - Target: []string{"production"}, - Label: []string{"enhancement"}, + Branch: []string{"main"}, + Comment: []string{"test comment"}, + Event: []string{"push", "pull_request:labeled"}, + Path: []string{"foo.txt"}, + Repo: []string{"github/octocat"}, + Status: []string{"success"}, + Tag: []string{"v0.1.0"}, + Target: []string{"production"}, + Label: []string{"enhancement"}, + Instance: []string{"http://localhost:8080"}, }, Unless: pipeline.Rules{ - Branch: []string{"main"}, - Comment: []string{"real comment"}, - Event: []string{"pull_request"}, - Path: []string{"bar.txt"}, - Repo: []string{"github/octocat"}, - Status: []string{"failure"}, - Tag: []string{"v0.2.0"}, - Target: []string{"production"}, + Branch: []string{"main"}, + Comment: []string{"real comment"}, + Event: []string{"pull_request"}, + Path: []string{"bar.txt"}, + Repo: []string{"github/octocat"}, + Status: []string{"failure"}, + Tag: []string{"v0.2.0"}, + Target: []string{"production"}, + Instance: []string{"http://localhost:8080"}, }, Matcher: "filepath", Operator: "and",