diff --git a/settings/hub.go b/settings/hub.go index 2dd3fcb4..84bd8c24 100644 --- a/settings/hub.go +++ b/settings/hub.go @@ -368,6 +368,7 @@ func (r *Hub) namespace() (ns string, err error) { // build returns the hub build version. // This is expected to be the output of `git describe`. // Examples: +// // v0.6.0-ea89gcd // v0.6.0 func (r *Hub) build() (version string, err error) { diff --git a/task/error.go b/task/error.go index 5063de5d..d8e57822 100644 --- a/task/error.go +++ b/task/error.go @@ -231,6 +231,25 @@ func (e *SelectorNotValid) Retry() (r bool) { return } +// ExtAddonNotValid reports extension addon ref error. +type ExtAddonNotValid struct { + Extension string + Reason string +} + +func (e *ExtAddonNotValid) Error() string { + return fmt.Sprintf( + "Extension '%s' addon ref not valid. reason: %s", + e.Extension, + e.Reason) +} + +func (e *ExtAddonNotValid) Is(err error) (matched bool) { + var inst *ExtAddonNotValid + matched = errors.As(err, &inst) + return +} + // PriorityNotFound report priority class not found. type PriorityNotFound struct { Name string diff --git a/task/manager.go b/task/manager.go index 9152570b..9db802db 100644 --- a/task/manager.go +++ b/task/manager.go @@ -8,6 +8,7 @@ import ( "io" "os" "path" + "regexp" "sort" "strconv" "strings" @@ -88,6 +89,10 @@ const ( Cache = "cache" ) +var ( + IsRegex = regexp.MustCompile("[^0-9A-Za-z_-]") +) + var ( Settings = &settings.Settings Log = logr.WithName("task-scheduler") @@ -555,7 +560,11 @@ func (m *Manager) selectExtensions(task *Task, addon *crd.Addon) (err error) { matched := false selector := NewSelector(m.DB, task) for _, extension := range m.cluster.Extensions() { - if extension.Spec.Addon != addon.Name { + matched, err = m.matchAddon(extension, addon) + if err != nil { + return + } + if !matched { continue } matched, err = selector.Match(extension.Spec.Selector) @@ -570,6 +579,30 @@ func (m *Manager) selectExtensions(task *Task, addon *crd.Addon) (err error) { return } +// matchAddon - returns true when the extension's `addon` +// (ref) matches the addon name. +// The `ref` is matched as a REGEX when it contains +// characters other than: [0-9A-Za-z_]. +func (m *Manager) matchAddon(extension *crd.Extension, addon *crd.Addon) (matched bool, err error) { + ref := strings.TrimSpace(extension.Spec.Addon) + p := IsRegex + if p.MatchString(ref) { + p, err = regexp.Compile(ref) + if err != nil { + err = &ExtAddonNotValid{ + Extension: extension.Name, + Reason: err.Error(), + } + return + } + matched = p.MatchString(addon.Name) + } else { + + matched = addon.Name == ref + } + return +} + // postpone Postpones a task as needed based on rules. // postpone order: // - priority (lower) diff --git a/task/task_test.go b/task/task_test.go index e088769e..611383e2 100644 --- a/task/task_test.go +++ b/task/task_test.go @@ -135,3 +135,34 @@ func TestPriorityGraph(t *testing.T) { deps := pE.graph(ready[0], ready) g.Expect(len(deps)).To(gomega.Equal(2)) } + +func TestAddonRegex(t *testing.T) { + g := gomega.NewGomegaWithT(t) + m := Manager{} + addonA := &crd.Addon{} + addonA.Name = "A" + addonB := &crd.Addon{} + addonB.Name = "B" + // direct. + ext := &crd.Extension{} + ext.Name = "Test" + ext.Spec.Addon = "A" + matched, err := m.matchAddon(ext, addonA) + g.Expect(err).To(gomega.BeNil()) + g.Expect(matched).To(gomega.BeTrue()) + matched, err = m.matchAddon(ext, addonB) + g.Expect(err).To(gomega.BeNil()) + g.Expect(matched).To(gomega.BeFalse()) + // regex. + ext.Spec.Addon = "^(A|B)$" + matched, err = m.matchAddon(ext, addonA) + g.Expect(err).To(gomega.BeNil()) + g.Expect(matched).To(gomega.BeTrue()) + matched, err = m.matchAddon(ext, addonB) + g.Expect(err).To(gomega.BeNil()) + g.Expect(matched).To(gomega.BeTrue()) + // regex not valid. + ext.Spec.Addon = "(]$" + matched, err = m.matchAddon(ext, addonA) + g.Expect(err).ToNot(gomega.BeNil()) +}