Skip to content

Commit

Permalink
Add capabilities parameter in search endpoint (#1054)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrodm authored Jul 14, 2023
1 parent eaa62bf commit 7911da9
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* Add new query parameter "capabilities" in search endpoint [#1054](https://github.com/elastic/package-registry/pull/1054)

### Deprecated

### Known Issues
Expand Down
16 changes: 15 additions & 1 deletion packages/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ type KibanaConditions struct {

// ElasticConditions defines conditions related to Elastic subscriptions or partnerships.
type ElasticConditions struct {
Subscription string `config:"subscription" json:"subscription" yaml:"subscription"`
Subscription string `config:"subscription" json:"subscription" yaml:"subscription"`
Capabilities []string `config:"capabilities,omitempty" json:"capabilities,omitempty" yaml:"capabilities,omitempty"`
}

type Version struct {
Expand Down Expand Up @@ -387,6 +388,19 @@ func (p *Package) HasKibanaVersion(version *semver.Version) bool {
return p.Conditions.Kibana.constraint.Check(version)
}

func (p *Package) WorksWithCapabilities(capabilities []string) bool {
if p.Conditions == nil || p.Conditions.Elastic == nil || p.Conditions.Elastic.Capabilities == nil || capabilities == nil {
return true
}

for _, requiredCapability := range p.Conditions.Elastic.Capabilities {
if !util.StringsContains(capabilities, requiredCapability) {
return false
}
}
return true
}

func (p *Package) IsNewerOrEqual(pp *Package) bool {
return !p.versionSemVer.LessThan(pp.versionSemVer)
}
Expand Down
13 changes: 13 additions & 0 deletions packages/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ type Filter struct {
PackageName string
PackageVersion string
PackageType string
Capabilities []string

// Deprecated, release tags to be removed.
Experimental bool
Expand Down Expand Up @@ -342,6 +343,12 @@ func (f *Filter) Apply(ctx context.Context, packages Packages) Packages {
continue
}

if f.Capabilities != nil {
if valid := p.WorksWithCapabilities(f.Capabilities); !valid {
continue
}
}

addPackage := true
if !f.AllVersions {
// Check if the version exists and if it should be added or not.
Expand Down Expand Up @@ -405,6 +412,12 @@ func (f *Filter) legacyApply(ctx context.Context, packages Packages) Packages {
continue
}

if f.Capabilities != nil {
if valid := p.WorksWithCapabilities(f.Capabilities); !valid {
continue
}
}

addPackage := true
if !f.AllVersions {
// Check if the version exists and if it should be added or not.
Expand Down
119 changes: 111 additions & 8 deletions packages/packages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,36 @@ func TestPackagesFilter(t *testing.T) {
Type: "integration",
KibanaVersion: "^8.0.0",
},
{
Name: "obs_package",
Version: "1.1.0",
Type: "integration",
Capabilities: []string{"observability"},
},
{
Name: "obs_sec_package",
Version: "1.0.0",
Type: "integration",
Capabilities: []string{"observability", "security"},
},
{
Name: "obs_sec_package",
Version: "2.0.0-rc1",
Type: "integration",
Capabilities: []string{"observability", "security"},
},
{
Name: "obs_sec_package",
Version: "2.0.0",
Type: "integration",
Capabilities: []string{"observability", "security"},
},
{
Name: "obs_sec_uptime_package",
Version: "2.0.0",
Type: "integration",
Capabilities: []string{"observability", "security", "uptime"},
},
}
packages := buildFilterTestPackages(filterTestPackages)

Expand Down Expand Up @@ -164,6 +194,9 @@ func TestPackagesFilter(t *testing.T) {
{Name: "apache", Version: "1.0.0"},
{Name: "nginx", Version: "2.0.0"},
{Name: "redisenterprise", Version: "1.0.0"},
{Name: "obs_package", Version: "1.1.0"},
{Name: "obs_sec_package", Version: "2.0.0"},
{Name: "obs_sec_uptime_package", Version: "2.0.0"},
},
},
{
Expand Down Expand Up @@ -231,6 +264,7 @@ func TestPackagesFilter(t *testing.T) {
filterTestPackage{Name: "apache", Version: "1.0.0-rc1"},
filterTestPackage{Name: "apache", Version: "2.0.0-rc2"},
filterTestPackage{Name: "redisenterprise", Version: "0.1.1"},
filterTestPackage{Name: "obs_sec_package", Version: "2.0.0-rc1"},
),
},
{
Expand Down Expand Up @@ -350,6 +384,60 @@ func TestPackagesFilter(t *testing.T) {
{Name: "etcd", Version: "1.0.0-rc2"},
},
},
{
Title: "non existing capabilities search",
Filter: Filter{
Capabilities: []string{"no_match"},
},
Expected: []filterTestPackage{
{Name: "apache", Version: "1.0.0"},
{Name: "nginx", Version: "2.0.0"},
{Name: "redisenterprise", Version: "1.0.0"},
},
},
{
Title: "observability capabilities search",
Filter: Filter{
Capabilities: []string{"observability"},
},
Expected: []filterTestPackage{
{Name: "apache", Version: "1.0.0"},
{Name: "nginx", Version: "2.0.0"},
{Name: "redisenterprise", Version: "1.0.0"},
{Name: "obs_package", Version: "1.1.0"},
},
},
{
Title: "observability and security capabilities search",
Filter: Filter{
Capabilities: []string{"observability", "security"},
},
Expected: []filterTestPackage{
{Name: "apache", Version: "1.0.0"},
{Name: "nginx", Version: "2.0.0"},
{Name: "redisenterprise", Version: "1.0.0"},
{Name: "obs_package", Version: "1.1.0"},
{Name: "obs_sec_package", Version: "2.0.0"},
},
},
{
Title: "observability, security and uptime capabilities search - legacy kibana",
Filter: Filter{
Experimental: true,
Capabilities: []string{"observability", "security", "uptime"},
},
Expected: []filterTestPackage{
{Name: "apache", Version: "1.0.0"},
{Name: "nginx", Version: "2.0.0"},
{Name: "mysql", Version: "0.9.0"},
{Name: "logstash", Version: "1.1.0"},
{Name: "etcd", Version: "1.0.0-rc2"},
{Name: "redisenterprise", Version: "1.0.0"},
{Name: "obs_package", Version: "1.1.0"},
{Name: "obs_sec_package", Version: "2.0.0"},
{Name: "obs_sec_uptime_package", Version: "2.0.0"},
},
},
}

for _, c := range cases {
Expand All @@ -366,6 +454,7 @@ type filterTestPackage struct {
Release string
Type string
KibanaVersion string
Capabilities []string
}

func (p filterTestPackage) Build() *Package {
Expand All @@ -377,15 +466,29 @@ func (p filterTestPackage) Build() *Package {
build.Release = p.Release
build.Type = p.Type

constraints, err := semver.NewConstraint(p.KibanaVersion)
if err != nil {
panic(err)
if p.KibanaVersion != "" {
constraints, err := semver.NewConstraint(p.KibanaVersion)
if err != nil {
panic(err)
}
build.Conditions = &Conditions{
Kibana: &KibanaConditions{
Version: p.KibanaVersion,
constraint: constraints,
},
}
}
build.Conditions = &Conditions{
Kibana: &KibanaConditions{
Version: p.KibanaVersion,
constraint: constraints,
},
if p.Capabilities != nil {
elasticConditions := ElasticConditions{
Capabilities: p.Capabilities,
}
if build.Conditions != nil {
build.Conditions.Elastic = &elasticConditions
} else {
build.Conditions = &Conditions{
Elastic: &elasticConditions,
}
}
}
return &build
}
Expand Down
5 changes: 5 additions & 0 deletions search.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/url"
"sort"
"strconv"
"strings"
"time"

"github.com/Masterminds/semver/v3"
Expand Down Expand Up @@ -99,6 +100,10 @@ func newSearchFilterFromQuery(query url.Values) (*packages.Filter, error) {
filter.PackageType = v
}

if v := query.Get("capabilities"); v != "" {
filter.Capabilities = strings.Split(v, ",")
}

if v := query.Get("all"); v != "" {
// Default is false, also on error
filter.AllVersions, err = strconv.ParseBool(v)
Expand Down

0 comments on commit 7911da9

Please sign in to comment.