Add a rudimentary filter option when listing entities

This change adds the ability to filter the list of entities returned
by the API by entity owner, name or endpoint, depending on the entity
type.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2025-06-17 22:37:18 +00:00
parent 2fd0e720e6
commit 499fbde60c
32 changed files with 879 additions and 73 deletions

View file

@ -66,13 +66,30 @@ func (a *APIController) CreateEnterpriseHandler(w http.ResponseWriter, r *http.R
// //
// List all enterprises. // List all enterprises.
// //
// Parameters:
// + name: name
// description: Exact enterprise name to filter by
// type: string
// in: query
// required: false
//
// + name: endpoint
// description: Exact endpoint name to filter by
// type: string
// in: query
// required: false
//
// Responses: // Responses:
// 200: Enterprises // 200: Enterprises
// default: APIErrorResponse // default: APIErrorResponse
func (a *APIController) ListEnterprisesHandler(w http.ResponseWriter, r *http.Request) { func (a *APIController) ListEnterprisesHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
enterprise, err := a.r.ListEnterprises(ctx) filter := runnerParams.EnterpriseFilter{
Name: r.URL.Query().Get("name"),
Endpoint: r.URL.Query().Get("endpoint"),
}
enterprise, err := a.r.ListEnterprises(ctx, filter)
if err != nil { if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing enterprise") slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing enterprise")
handleError(ctx, w, err) handleError(ctx, w, err)

View file

@ -67,13 +67,30 @@ func (a *APIController) CreateOrgHandler(w http.ResponseWriter, r *http.Request)
// //
// List organizations. // List organizations.
// //
// Parameters:
// + name: name
// description: Exact organization name to filter by
// type: string
// in: query
// required: false
//
// + name: endpoint
// description: Exact endpoint name to filter by
// type: string
// in: query
// required: false
//
// Responses: // Responses:
// 200: Organizations // 200: Organizations
// default: APIErrorResponse // default: APIErrorResponse
func (a *APIController) ListOrgsHandler(w http.ResponseWriter, r *http.Request) { func (a *APIController) ListOrgsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
orgs, err := a.r.ListOrganizations(ctx) filter := runnerParams.OrganizationFilter{
Name: r.URL.Query().Get("name"),
Endpoint: r.URL.Query().Get("endpoint"),
}
orgs, err := a.r.ListOrganizations(ctx, filter)
if err != nil { if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing orgs") slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing orgs")
handleError(ctx, w, err) handleError(ctx, w, err)

View file

@ -67,13 +67,37 @@ func (a *APIController) CreateRepoHandler(w http.ResponseWriter, r *http.Request
// //
// List repositories. // List repositories.
// //
// Parameters:
// + name: owner
// description: Exact owner name to filter by
// type: string
// in: query
// required: false
//
// + name: name
// description: Exact repository name to filter by
// type: string
// in: query
// required: false
//
// + name: endpoint
// description: Exact endpoint name to filter by
// type: string
// in: query
// required: false
//
// Responses: // Responses:
// 200: Repositories // 200: Repositories
// default: APIErrorResponse // default: APIErrorResponse
func (a *APIController) ListReposHandler(w http.ResponseWriter, r *http.Request) { func (a *APIController) ListReposHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
repos, err := a.r.ListRepositories(ctx) filter := runnerParams.RepositoryFilter{
Name: r.URL.Query().Get("name"),
Owner: r.URL.Query().Get("owner"),
Endpoint: r.URL.Query().Get("endpoint"),
}
repos, err := a.r.ListRepositories(ctx, filter)
if err != nil { if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing repositories") slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing repositories")
handleError(ctx, w, err) handleError(ctx, w, err)

View file

@ -418,6 +418,15 @@ paths:
/enterprises: /enterprises:
get: get:
operationId: ListEnterprises operationId: ListEnterprises
parameters:
- description: Exact enterprise name to filter by
in: query
name: name
type: string
- description: Exact endpoint name to filter by
in: query
name: endpoint
type: string
responses: responses:
"200": "200":
description: Enterprises description: Enterprises
@ -1254,6 +1263,15 @@ paths:
/organizations: /organizations:
get: get:
operationId: ListOrgs operationId: ListOrgs
parameters:
- description: Exact organization name to filter by
in: query
name: name
type: string
- description: Exact endpoint name to filter by
in: query
name: endpoint
type: string
responses: responses:
"200": "200":
description: Organizations description: Organizations
@ -1754,6 +1772,19 @@ paths:
/repositories: /repositories:
get: get:
operationId: ListRepos operationId: ListRepos
parameters:
- description: Exact owner name to filter by
in: query
name: owner
type: string
- description: Exact repository name to filter by
in: query
name: name
type: string
- description: Exact endpoint name to filter by
in: query
name: endpoint
type: string
responses: responses:
"200": "200":
description: Repositories description: Repositories

View file

@ -60,6 +60,19 @@ ListEnterprisesParams contains all the parameters to send to the API endpoint
Typically these are written to a http.Request. Typically these are written to a http.Request.
*/ */
type ListEnterprisesParams struct { type ListEnterprisesParams struct {
/* Endpoint.
Exact endpoint name to filter by
*/
Endpoint *string
/* Name.
Exact enterprise name to filter by
*/
Name *string
timeout time.Duration timeout time.Duration
Context context.Context Context context.Context
HTTPClient *http.Client HTTPClient *http.Client
@ -113,6 +126,28 @@ func (o *ListEnterprisesParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client o.HTTPClient = client
} }
// WithEndpoint adds the endpoint to the list enterprises params
func (o *ListEnterprisesParams) WithEndpoint(endpoint *string) *ListEnterprisesParams {
o.SetEndpoint(endpoint)
return o
}
// SetEndpoint adds the endpoint to the list enterprises params
func (o *ListEnterprisesParams) SetEndpoint(endpoint *string) {
o.Endpoint = endpoint
}
// WithName adds the name to the list enterprises params
func (o *ListEnterprisesParams) WithName(name *string) *ListEnterprisesParams {
o.SetName(name)
return o
}
// SetName adds the name to the list enterprises params
func (o *ListEnterprisesParams) SetName(name *string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request // WriteToRequest writes these params to a swagger request
func (o *ListEnterprisesParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { func (o *ListEnterprisesParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
@ -121,6 +156,40 @@ func (o *ListEnterprisesParams) WriteToRequest(r runtime.ClientRequest, reg strf
} }
var res []error var res []error
if o.Endpoint != nil {
// query param endpoint
var qrEndpoint string
if o.Endpoint != nil {
qrEndpoint = *o.Endpoint
}
qEndpoint := qrEndpoint
if qEndpoint != "" {
if err := r.SetQueryParam("endpoint", qEndpoint); err != nil {
return err
}
}
}
if o.Name != nil {
// query param name
var qrName string
if o.Name != nil {
qrName = *o.Name
}
qName := qrName
if qName != "" {
if err := r.SetQueryParam("name", qName); err != nil {
return err
}
}
}
if len(res) > 0 { if len(res) > 0 {
return errors.CompositeValidationError(res...) return errors.CompositeValidationError(res...)
} }

View file

@ -60,6 +60,19 @@ ListOrgsParams contains all the parameters to send to the API endpoint
Typically these are written to a http.Request. Typically these are written to a http.Request.
*/ */
type ListOrgsParams struct { type ListOrgsParams struct {
/* Endpoint.
Exact endpoint name to filter by
*/
Endpoint *string
/* Name.
Exact organization name to filter by
*/
Name *string
timeout time.Duration timeout time.Duration
Context context.Context Context context.Context
HTTPClient *http.Client HTTPClient *http.Client
@ -113,6 +126,28 @@ func (o *ListOrgsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client o.HTTPClient = client
} }
// WithEndpoint adds the endpoint to the list orgs params
func (o *ListOrgsParams) WithEndpoint(endpoint *string) *ListOrgsParams {
o.SetEndpoint(endpoint)
return o
}
// SetEndpoint adds the endpoint to the list orgs params
func (o *ListOrgsParams) SetEndpoint(endpoint *string) {
o.Endpoint = endpoint
}
// WithName adds the name to the list orgs params
func (o *ListOrgsParams) WithName(name *string) *ListOrgsParams {
o.SetName(name)
return o
}
// SetName adds the name to the list orgs params
func (o *ListOrgsParams) SetName(name *string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request // WriteToRequest writes these params to a swagger request
func (o *ListOrgsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { func (o *ListOrgsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
@ -121,6 +156,40 @@ func (o *ListOrgsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Regi
} }
var res []error var res []error
if o.Endpoint != nil {
// query param endpoint
var qrEndpoint string
if o.Endpoint != nil {
qrEndpoint = *o.Endpoint
}
qEndpoint := qrEndpoint
if qEndpoint != "" {
if err := r.SetQueryParam("endpoint", qEndpoint); err != nil {
return err
}
}
}
if o.Name != nil {
// query param name
var qrName string
if o.Name != nil {
qrName = *o.Name
}
qName := qrName
if qName != "" {
if err := r.SetQueryParam("name", qName); err != nil {
return err
}
}
}
if len(res) > 0 { if len(res) > 0 {
return errors.CompositeValidationError(res...) return errors.CompositeValidationError(res...)
} }

View file

@ -60,6 +60,25 @@ ListReposParams contains all the parameters to send to the API endpoint
Typically these are written to a http.Request. Typically these are written to a http.Request.
*/ */
type ListReposParams struct { type ListReposParams struct {
/* Endpoint.
Exact endpoint name to filter by
*/
Endpoint *string
/* Name.
Exact repository name to filter by
*/
Name *string
/* Owner.
Exact owner name to filter by
*/
Owner *string
timeout time.Duration timeout time.Duration
Context context.Context Context context.Context
HTTPClient *http.Client HTTPClient *http.Client
@ -113,6 +132,39 @@ func (o *ListReposParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client o.HTTPClient = client
} }
// WithEndpoint adds the endpoint to the list repos params
func (o *ListReposParams) WithEndpoint(endpoint *string) *ListReposParams {
o.SetEndpoint(endpoint)
return o
}
// SetEndpoint adds the endpoint to the list repos params
func (o *ListReposParams) SetEndpoint(endpoint *string) {
o.Endpoint = endpoint
}
// WithName adds the name to the list repos params
func (o *ListReposParams) WithName(name *string) *ListReposParams {
o.SetName(name)
return o
}
// SetName adds the name to the list repos params
func (o *ListReposParams) SetName(name *string) {
o.Name = name
}
// WithOwner adds the owner to the list repos params
func (o *ListReposParams) WithOwner(owner *string) *ListReposParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the list repos params
func (o *ListReposParams) SetOwner(owner *string) {
o.Owner = owner
}
// WriteToRequest writes these params to a swagger request // WriteToRequest writes these params to a swagger request
func (o *ListReposParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { func (o *ListReposParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
@ -121,6 +173,57 @@ func (o *ListReposParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Reg
} }
var res []error var res []error
if o.Endpoint != nil {
// query param endpoint
var qrEndpoint string
if o.Endpoint != nil {
qrEndpoint = *o.Endpoint
}
qEndpoint := qrEndpoint
if qEndpoint != "" {
if err := r.SetQueryParam("endpoint", qEndpoint); err != nil {
return err
}
}
}
if o.Name != nil {
// query param name
var qrName string
if o.Name != nil {
qrName = *o.Name
}
qName := qrName
if qName != "" {
if err := r.SetQueryParam("name", qName); err != nil {
return err
}
}
}
if o.Owner != nil {
// query param owner
var qrOwner string
if o.Owner != nil {
qrOwner = *o.Owner
}
qOwner := qrOwner
if qOwner != "" {
if err := r.SetQueryParam("owner", qOwner); err != nil {
return err
}
}
}
if len(res) > 0 { if len(res) > 0 {
return errors.CompositeValidationError(res...) return errors.CompositeValidationError(res...)
} }

View file

@ -28,6 +28,7 @@ import (
var ( var (
enterpriseName string enterpriseName string
enterpriseEndpoint string
enterpriseWebhookSecret string enterpriseWebhookSecret string
enterpriseCreds string enterpriseCreds string
) )
@ -85,6 +86,8 @@ var enterpriseListCmd = &cobra.Command{
} }
listEnterprisesReq := apiClientEnterprises.NewListEnterprisesParams() listEnterprisesReq := apiClientEnterprises.NewListEnterprisesParams()
listEnterprisesReq.Name = &enterpriseName
listEnterprisesReq.Endpoint = &enterpriseEndpoint
response, err := apiCli.Enterprises.ListEnterprises(listEnterprisesReq, authToken) response, err := apiCli.Enterprises.ListEnterprises(listEnterprisesReq, authToken)
if err != nil { if err != nil {
return err return err
@ -185,6 +188,8 @@ func init() {
enterpriseAddCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", string(params.PoolBalancerTypeRoundRobin), "The balancing strategy to use when creating runners in pools matching requested labels.") enterpriseAddCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", string(params.PoolBalancerTypeRoundRobin), "The balancing strategy to use when creating runners in pools matching requested labels.")
enterpriseListCmd.Flags().BoolVarP(&long, "long", "l", false, "Include additional info.") enterpriseListCmd.Flags().BoolVarP(&long, "long", "l", false, "Include additional info.")
enterpriseListCmd.Flags().StringVarP(&enterpriseName, "name", "n", "", "Exact enterprise name to filter by.")
enterpriseListCmd.Flags().StringVarP(&enterpriseEndpoint, "endpoint", "e", "", "Exact endpoint name to filter by.")
enterpriseAddCmd.MarkFlagRequired("credentials") //nolint enterpriseAddCmd.MarkFlagRequired("credentials") //nolint
enterpriseAddCmd.MarkFlagRequired("name") //nolint enterpriseAddCmd.MarkFlagRequired("name") //nolint

View file

@ -29,6 +29,7 @@ import (
var ( var (
orgName string orgName string
orgEndpoint string
orgWebhookSecret string orgWebhookSecret string
orgCreds string orgCreds string
orgRandomWebhookSecret bool orgRandomWebhookSecret bool
@ -243,6 +244,8 @@ var orgListCmd = &cobra.Command{
} }
listOrgsReq := apiClientOrgs.NewListOrgsParams() listOrgsReq := apiClientOrgs.NewListOrgsParams()
listOrgsReq.Name = &orgName
listOrgsReq.Endpoint = &orgEndpoint
response, err := apiCli.Organizations.ListOrgs(listOrgsReq, authToken) response, err := apiCli.Organizations.ListOrgs(listOrgsReq, authToken)
if err != nil { if err != nil {
return err return err
@ -314,7 +317,10 @@ func init() {
orgAddCmd.Flags().BoolVar(&installOrgWebhook, "install-webhook", false, "Install the webhook as part of the add operation.") orgAddCmd.Flags().BoolVar(&installOrgWebhook, "install-webhook", false, "Install the webhook as part of the add operation.")
orgAddCmd.MarkFlagsMutuallyExclusive("webhook-secret", "random-webhook-secret") orgAddCmd.MarkFlagsMutuallyExclusive("webhook-secret", "random-webhook-secret")
orgAddCmd.MarkFlagsOneRequired("webhook-secret", "random-webhook-secret") orgAddCmd.MarkFlagsOneRequired("webhook-secret", "random-webhook-secret")
orgListCmd.Flags().BoolVarP(&long, "long", "l", false, "Include additional info.") orgListCmd.Flags().BoolVarP(&long, "long", "l", false, "Include additional info.")
orgListCmd.Flags().StringVarP(&orgName, "name", "n", "", "Exact org name to filter by.")
orgListCmd.Flags().StringVarP(&orgEndpoint, "endpoint", "e", "", "Exact endpoint name to filter by.")
orgAddCmd.MarkFlagRequired("credentials") //nolint orgAddCmd.MarkFlagRequired("credentials") //nolint
orgAddCmd.MarkFlagRequired("name") //nolint orgAddCmd.MarkFlagRequired("name") //nolint

View file

@ -30,6 +30,7 @@ import (
var ( var (
repoOwner string repoOwner string
repoName string repoName string
repoEndpoint string
repoWebhookSecret string repoWebhookSecret string
repoCreds string repoCreds string
forgeType string forgeType string
@ -213,6 +214,9 @@ var repoListCmd = &cobra.Command{
} }
listReposReq := apiClientRepos.NewListReposParams() listReposReq := apiClientRepos.NewListReposParams()
listReposReq.Name = &repoName
listReposReq.Owner = &repoOwner
listReposReq.Endpoint = &repoEndpoint
response, err := apiCli.Repositories.ListRepos(listReposReq, authToken) response, err := apiCli.Repositories.ListRepos(listReposReq, authToken)
if err != nil { if err != nil {
return err return err
@ -321,6 +325,9 @@ func init() {
repoAddCmd.MarkFlagsOneRequired("webhook-secret", "random-webhook-secret") repoAddCmd.MarkFlagsOneRequired("webhook-secret", "random-webhook-secret")
repoListCmd.Flags().BoolVarP(&long, "long", "l", false, "Include additional info.") repoListCmd.Flags().BoolVarP(&long, "long", "l", false, "Include additional info.")
repoListCmd.Flags().StringVarP(&repoName, "name", "n", "", "Exact repo name to filter by.")
repoListCmd.Flags().StringVarP(&repoOwner, "owner", "o", "", "Exact repo owner to filter by.")
repoListCmd.Flags().StringVarP(&repoEndpoint, "endpoint", "e", "", "Exact endpoint name to filter by.")
repoAddCmd.MarkFlagRequired("credentials") //nolint repoAddCmd.MarkFlagRequired("credentials") //nolint
repoAddCmd.MarkFlagRequired("owner") //nolint repoAddCmd.MarkFlagRequired("owner") //nolint

View file

@ -1524,9 +1524,9 @@ func (_m *Store) ListAllScaleSets(ctx context.Context) ([]params.ScaleSet, error
return r0, r1 return r0, r1
} }
// ListEnterprises provides a mock function with given fields: ctx // ListEnterprises provides a mock function with given fields: ctx, filter
func (_m *Store) ListEnterprises(ctx context.Context) ([]params.Enterprise, error) { func (_m *Store) ListEnterprises(ctx context.Context, filter params.EnterpriseFilter) ([]params.Enterprise, error) {
ret := _m.Called(ctx) ret := _m.Called(ctx, filter)
if len(ret) == 0 { if len(ret) == 0 {
panic("no return value specified for ListEnterprises") panic("no return value specified for ListEnterprises")
@ -1534,19 +1534,19 @@ func (_m *Store) ListEnterprises(ctx context.Context) ([]params.Enterprise, erro
var r0 []params.Enterprise var r0 []params.Enterprise
var r1 error var r1 error
if rf, ok := ret.Get(0).(func(context.Context) ([]params.Enterprise, error)); ok { if rf, ok := ret.Get(0).(func(context.Context, params.EnterpriseFilter) ([]params.Enterprise, error)); ok {
return rf(ctx) return rf(ctx, filter)
} }
if rf, ok := ret.Get(0).(func(context.Context) []params.Enterprise); ok { if rf, ok := ret.Get(0).(func(context.Context, params.EnterpriseFilter) []params.Enterprise); ok {
r0 = rf(ctx) r0 = rf(ctx, filter)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).([]params.Enterprise) r0 = ret.Get(0).([]params.Enterprise)
} }
} }
if rf, ok := ret.Get(1).(func(context.Context) error); ok { if rf, ok := ret.Get(1).(func(context.Context, params.EnterpriseFilter) error); ok {
r1 = rf(ctx) r1 = rf(ctx, filter)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
} }
@ -1824,9 +1824,9 @@ func (_m *Store) ListJobsByStatus(ctx context.Context, status params.JobStatus)
return r0, r1 return r0, r1
} }
// ListOrganizations provides a mock function with given fields: ctx // ListOrganizations provides a mock function with given fields: ctx, filter
func (_m *Store) ListOrganizations(ctx context.Context) ([]params.Organization, error) { func (_m *Store) ListOrganizations(ctx context.Context, filter params.OrganizationFilter) ([]params.Organization, error) {
ret := _m.Called(ctx) ret := _m.Called(ctx, filter)
if len(ret) == 0 { if len(ret) == 0 {
panic("no return value specified for ListOrganizations") panic("no return value specified for ListOrganizations")
@ -1834,19 +1834,19 @@ func (_m *Store) ListOrganizations(ctx context.Context) ([]params.Organization,
var r0 []params.Organization var r0 []params.Organization
var r1 error var r1 error
if rf, ok := ret.Get(0).(func(context.Context) ([]params.Organization, error)); ok { if rf, ok := ret.Get(0).(func(context.Context, params.OrganizationFilter) ([]params.Organization, error)); ok {
return rf(ctx) return rf(ctx, filter)
} }
if rf, ok := ret.Get(0).(func(context.Context) []params.Organization); ok { if rf, ok := ret.Get(0).(func(context.Context, params.OrganizationFilter) []params.Organization); ok {
r0 = rf(ctx) r0 = rf(ctx, filter)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).([]params.Organization) r0 = ret.Get(0).([]params.Organization)
} }
} }
if rf, ok := ret.Get(1).(func(context.Context) error); ok { if rf, ok := ret.Get(1).(func(context.Context, params.OrganizationFilter) error); ok {
r1 = rf(ctx) r1 = rf(ctx, filter)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
} }
@ -1884,9 +1884,9 @@ func (_m *Store) ListPoolInstances(ctx context.Context, poolID string) ([]params
return r0, r1 return r0, r1
} }
// ListRepositories provides a mock function with given fields: ctx // ListRepositories provides a mock function with given fields: ctx, filter
func (_m *Store) ListRepositories(ctx context.Context) ([]params.Repository, error) { func (_m *Store) ListRepositories(ctx context.Context, filter params.RepositoryFilter) ([]params.Repository, error) {
ret := _m.Called(ctx) ret := _m.Called(ctx, filter)
if len(ret) == 0 { if len(ret) == 0 {
panic("no return value specified for ListRepositories") panic("no return value specified for ListRepositories")
@ -1894,19 +1894,19 @@ func (_m *Store) ListRepositories(ctx context.Context) ([]params.Repository, err
var r0 []params.Repository var r0 []params.Repository
var r1 error var r1 error
if rf, ok := ret.Get(0).(func(context.Context) ([]params.Repository, error)); ok { if rf, ok := ret.Get(0).(func(context.Context, params.RepositoryFilter) ([]params.Repository, error)); ok {
return rf(ctx) return rf(ctx, filter)
} }
if rf, ok := ret.Get(0).(func(context.Context) []params.Repository); ok { if rf, ok := ret.Get(0).(func(context.Context, params.RepositoryFilter) []params.Repository); ok {
r0 = rf(ctx) r0 = rf(ctx, filter)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).([]params.Repository) r0 = ret.Get(0).([]params.Repository)
} }
} }
if rf, ok := ret.Get(1).(func(context.Context) error); ok { if rf, ok := ret.Get(1).(func(context.Context, params.RepositoryFilter) error); ok {
r1 = rf(ctx) r1 = rf(ctx, filter)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
} }

View file

@ -41,7 +41,7 @@ type RepoStore interface {
CreateRepository(ctx context.Context, owner, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (param params.Repository, err error) CreateRepository(ctx context.Context, owner, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (param params.Repository, err error)
GetRepository(ctx context.Context, owner, name, endpointName string) (params.Repository, error) GetRepository(ctx context.Context, owner, name, endpointName string) (params.Repository, error)
GetRepositoryByID(ctx context.Context, repoID string) (params.Repository, error) GetRepositoryByID(ctx context.Context, repoID string) (params.Repository, error)
ListRepositories(ctx context.Context) ([]params.Repository, error) ListRepositories(ctx context.Context, filter params.RepositoryFilter) ([]params.Repository, error)
DeleteRepository(ctx context.Context, repoID string) error DeleteRepository(ctx context.Context, repoID string) error
UpdateRepository(ctx context.Context, repoID string, param params.UpdateEntityParams) (params.Repository, error) UpdateRepository(ctx context.Context, repoID string, param params.UpdateEntityParams) (params.Repository, error)
} }
@ -50,7 +50,7 @@ type OrgStore interface {
CreateOrganization(ctx context.Context, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (org params.Organization, err error) CreateOrganization(ctx context.Context, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (org params.Organization, err error)
GetOrganization(ctx context.Context, name, endpointName string) (params.Organization, error) GetOrganization(ctx context.Context, name, endpointName string) (params.Organization, error)
GetOrganizationByID(ctx context.Context, orgID string) (params.Organization, error) GetOrganizationByID(ctx context.Context, orgID string) (params.Organization, error)
ListOrganizations(ctx context.Context) ([]params.Organization, error) ListOrganizations(ctx context.Context, filter params.OrganizationFilter) ([]params.Organization, error)
DeleteOrganization(ctx context.Context, orgID string) error DeleteOrganization(ctx context.Context, orgID string) error
UpdateOrganization(ctx context.Context, orgID string, param params.UpdateEntityParams) (params.Organization, error) UpdateOrganization(ctx context.Context, orgID string, param params.UpdateEntityParams) (params.Organization, error)
} }
@ -59,7 +59,7 @@ type EnterpriseStore interface {
CreateEnterprise(ctx context.Context, name string, credentialsName params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error) CreateEnterprise(ctx context.Context, name string, credentialsName params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error)
GetEnterprise(ctx context.Context, name, endpointName string) (params.Enterprise, error) GetEnterprise(ctx context.Context, name, endpointName string) (params.Enterprise, error)
GetEnterpriseByID(ctx context.Context, enterpriseID string) (params.Enterprise, error) GetEnterpriseByID(ctx context.Context, enterpriseID string) (params.Enterprise, error)
ListEnterprises(ctx context.Context) ([]params.Enterprise, error) ListEnterprises(ctx context.Context, filter params.EnterpriseFilter) ([]params.Enterprise, error)
DeleteEnterprise(ctx context.Context, enterpriseID string) error DeleteEnterprise(ctx context.Context, enterpriseID string) error
UpdateEnterprise(ctx context.Context, enterpriseID string, param params.UpdateEntityParams) (params.Enterprise, error) UpdateEnterprise(ctx context.Context, enterpriseID string, param params.UpdateEntityParams) (params.Enterprise, error)
} }

View file

@ -111,13 +111,19 @@ func (s *sqlDatabase) GetEnterpriseByID(ctx context.Context, enterpriseID string
return param, nil return param, nil
} }
func (s *sqlDatabase) ListEnterprises(_ context.Context) ([]params.Enterprise, error) { func (s *sqlDatabase) ListEnterprises(_ context.Context, filter params.EnterpriseFilter) ([]params.Enterprise, error) {
var enterprises []Enterprise var enterprises []Enterprise
q := s.conn. q := s.conn.
Preload("Credentials"). Preload("Credentials").
Preload("Credentials.Endpoint"). Preload("Credentials.Endpoint").
Preload("Endpoint"). Preload("Endpoint")
Find(&enterprises) if filter.Name != "" {
q = q.Where("name = ?", filter.Name)
}
if filter.Endpoint != "" {
q = q.Where("endpoint_name = ?", filter.Endpoint)
}
q = q.Find(&enterprises)
if q.Error != nil { if q.Error != nil {
return []params.Enterprise{}, errors.Wrap(q.Error, "fetching enterprises") return []params.Enterprise{}, errors.Wrap(q.Error, "fetching enterprises")
} }

View file

@ -54,8 +54,10 @@ type EnterpriseTestSuite struct {
adminUserID string adminUserID string
testCreds params.ForgeCredentials testCreds params.ForgeCredentials
ghesCreds params.ForgeCredentials
secondaryTestCreds params.ForgeCredentials secondaryTestCreds params.ForgeCredentials
githubEndpoint params.ForgeEndpoint githubEndpoint params.ForgeEndpoint
ghesEndpoint params.ForgeEndpoint
} }
func (s *EnterpriseTestSuite) equalInstancesByName(expected, actual []params.Instance) { func (s *EnterpriseTestSuite) equalInstancesByName(expected, actual []params.Instance) {
@ -90,7 +92,9 @@ func (s *EnterpriseTestSuite) SetupTest() {
s.Require().NotEmpty(s.adminUserID) s.Require().NotEmpty(s.adminUserID)
s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T()) s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T())
s.ghesEndpoint = garmTesting.CreateGHESEndpoint(adminCtx, db, s.T())
s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint) s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint)
s.ghesCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "ghes-creds", db, s.T(), s.ghesEndpoint)
s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint) s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint)
// create some enterprise objects in the database, for testing purposes // create some enterprise objects in the database, for testing purposes
@ -272,18 +276,68 @@ func (s *EnterpriseTestSuite) TestGetEnterpriseDBDecryptingErr() {
} }
func (s *EnterpriseTestSuite) TestListEnterprises() { func (s *EnterpriseTestSuite) TestListEnterprises() {
enterprises, err := s.Store.ListEnterprises(s.adminCtx) enterprises, err := s.Store.ListEnterprises(s.adminCtx, params.EnterpriseFilter{})
s.Require().Nil(err) s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), s.Fixtures.Enterprises, enterprises) garmTesting.EqualDBEntityByName(s.T(), s.Fixtures.Enterprises, enterprises)
} }
func (s *EnterpriseTestSuite) TestListEnterprisesWithFilter() {
enterprise, err := s.Store.CreateEnterprise(
s.adminCtx,
"test-enterprise",
s.ghesCreds,
"test-secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
enterprise2, err := s.Store.CreateEnterprise(
s.adminCtx,
"test-enterprise",
s.testCreds,
"test-secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
enterprise3, err := s.Store.CreateEnterprise(
s.adminCtx,
"test-enterprise2",
s.testCreds,
"test-secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
enterprises, err := s.Store.ListEnterprises(s.adminCtx, params.EnterpriseFilter{
Name: "test-enterprise",
})
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Enterprise{enterprise, enterprise2}, enterprises)
enterprises, err = s.Store.ListEnterprises(s.adminCtx, params.EnterpriseFilter{
Name: "test-enterprise",
Endpoint: s.ghesEndpoint.Name,
})
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Enterprise{enterprise}, enterprises)
enterprises, err = s.Store.ListEnterprises(s.adminCtx, params.EnterpriseFilter{
Name: "test-enterprise2",
})
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Enterprise{enterprise3}, enterprises)
}
func (s *EnterpriseTestSuite) TestListEnterprisesDBFetchErr() { func (s *EnterpriseTestSuite) TestListEnterprisesDBFetchErr() {
s.Fixtures.SQLMock. s.Fixtures.SQLMock.
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `enterprises` WHERE `enterprises`.`deleted_at` IS NULL")). ExpectQuery(regexp.QuoteMeta("SELECT * FROM `enterprises` WHERE `enterprises`.`deleted_at` IS NULL")).
WillReturnError(fmt.Errorf("fetching user from database mock error")) WillReturnError(fmt.Errorf("fetching user from database mock error"))
_, err := s.StoreSQLMocked.ListEnterprises(s.adminCtx) _, err := s.StoreSQLMocked.ListEnterprises(s.adminCtx, params.EnterpriseFilter{})
s.assertSQLMockExpectations() s.assertSQLMockExpectations()
s.Require().NotNil(err) s.Require().NotNil(err)

View file

@ -92,15 +92,23 @@ func (s *sqlDatabase) GetOrganization(ctx context.Context, name, endpointName st
return param, nil return param, nil
} }
func (s *sqlDatabase) ListOrganizations(_ context.Context) ([]params.Organization, error) { func (s *sqlDatabase) ListOrganizations(_ context.Context, filter params.OrganizationFilter) ([]params.Organization, error) {
var orgs []Organization var orgs []Organization
q := s.conn. q := s.conn.
Preload("Credentials"). Preload("Credentials").
Preload("GiteaCredentials"). Preload("GiteaCredentials").
Preload("Credentials.Endpoint"). Preload("Credentials.Endpoint").
Preload("GiteaCredentials.Endpoint"). Preload("GiteaCredentials.Endpoint").
Preload("Endpoint"). Preload("Endpoint")
Find(&orgs)
if filter.Name != "" {
q = q.Where("name = ?", filter.Name)
}
if filter.Endpoint != "" {
q = q.Where("endpoint_name = ?", filter.Endpoint)
}
q = q.Find(&orgs)
if q.Error != nil { if q.Error != nil {
return []params.Organization{}, errors.Wrap(q.Error, "fetching org from database") return []params.Organization{}, errors.Wrap(q.Error, "fetching org from database")
} }

View file

@ -333,18 +333,74 @@ func (s *OrgTestSuite) TestGetOrganizationDBDecryptingErr() {
} }
func (s *OrgTestSuite) TestListOrganizations() { func (s *OrgTestSuite) TestListOrganizations() {
orgs, err := s.Store.ListOrganizations(s.adminCtx) orgs, err := s.Store.ListOrganizations(s.adminCtx, params.OrganizationFilter{})
s.Require().Nil(err) s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), s.Fixtures.Orgs, orgs) garmTesting.EqualDBEntityByName(s.T(), s.Fixtures.Orgs, orgs)
} }
func (s *OrgTestSuite) TestListOrganizationsWithFilters() {
org, err := s.Store.CreateOrganization(
s.adminCtx,
"test-org",
s.testCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
org2, err := s.Store.CreateOrganization(
s.adminCtx,
"test-org",
s.testCredsGitea,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
org3, err := s.Store.CreateOrganization(
s.adminCtx,
"test-org2",
s.testCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
orgs, err := s.Store.ListOrganizations(
s.adminCtx,
params.OrganizationFilter{
Name: "test-org",
})
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Organization{org, org2}, orgs)
orgs, err = s.Store.ListOrganizations(
s.adminCtx,
params.OrganizationFilter{
Name: "test-org",
Endpoint: s.giteaEndpoint.Name,
})
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Organization{org2}, orgs)
orgs, err = s.Store.ListOrganizations(
s.adminCtx,
params.OrganizationFilter{
Name: "test-org2",
})
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Organization{org3}, orgs)
}
func (s *OrgTestSuite) TestListOrganizationsDBFetchErr() { func (s *OrgTestSuite) TestListOrganizationsDBFetchErr() {
s.Fixtures.SQLMock. s.Fixtures.SQLMock.
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `organizations` WHERE `organizations`.`deleted_at` IS NULL")). ExpectQuery(regexp.QuoteMeta("SELECT * FROM `organizations` WHERE `organizations`.`deleted_at` IS NULL")).
WillReturnError(fmt.Errorf("fetching user from database mock error")) WillReturnError(fmt.Errorf("fetching user from database mock error"))
_, err := s.StoreSQLMocked.ListOrganizations(s.adminCtx) _, err := s.StoreSQLMocked.ListOrganizations(s.adminCtx, params.OrganizationFilter{})
s.assertSQLMockExpectations() s.assertSQLMockExpectations()
s.Require().NotNil(err) s.Require().NotNil(err)

View file

@ -93,15 +93,24 @@ func (s *sqlDatabase) GetRepository(ctx context.Context, owner, name, endpointNa
return param, nil return param, nil
} }
func (s *sqlDatabase) ListRepositories(_ context.Context) ([]params.Repository, error) { func (s *sqlDatabase) ListRepositories(_ context.Context, filter params.RepositoryFilter) ([]params.Repository, error) {
var repos []Repository var repos []Repository
q := s.conn. q := s.conn.
Preload("Credentials"). Preload("Credentials").
Preload("GiteaCredentials"). Preload("GiteaCredentials").
Preload("Credentials.Endpoint"). Preload("Credentials.Endpoint").
Preload("GiteaCredentials.Endpoint"). Preload("GiteaCredentials.Endpoint").
Preload("Endpoint"). Preload("Endpoint")
Find(&repos) if filter.Owner != "" {
q = q.Where("owner = ?", filter.Owner)
}
if filter.Name != "" {
q = q.Where("name = ?", filter.Name)
}
if filter.Endpoint != "" {
q = q.Where("endpoint_name = ?", filter.Endpoint)
}
q = q.Find(&repos)
if q.Error != nil { if q.Error != nil {
return []params.Repository{}, errors.Wrap(q.Error, "fetching user from database") return []params.Repository{}, errors.Wrap(q.Error, "fetching user from database")
} }

View file

@ -376,18 +376,99 @@ func (s *RepoTestSuite) TestGetRepositoryDBDecryptingErr() {
} }
func (s *RepoTestSuite) TestListRepositories() { func (s *RepoTestSuite) TestListRepositories() {
repos, err := s.Store.ListRepositories(s.adminCtx) repos, err := s.Store.ListRepositories(s.adminCtx, params.RepositoryFilter{})
s.Require().Nil(err) s.Require().Nil(err)
s.equalReposByName(s.Fixtures.Repos, repos) s.equalReposByName(s.Fixtures.Repos, repos)
} }
func (s *RepoTestSuite) TestListRepositoriesWithFilters() {
repo, err := s.Store.CreateRepository(
s.adminCtx,
"test-owner",
"test-repo",
s.testCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
repo2, err := s.Store.CreateRepository(
s.adminCtx,
"test-owner",
"test-repo",
s.testCredsGitea,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
repo3, err := s.Store.CreateRepository(
s.adminCtx,
"test-owner",
"test-repo2",
s.testCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
repo4, err := s.Store.CreateRepository(
s.adminCtx,
"test-owner2",
"test-repo",
s.testCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
repos, err := s.Store.ListRepositories(
s.adminCtx,
params.RepositoryFilter{
Name: "test-repo",
})
s.Require().Nil(err)
s.equalReposByName([]params.Repository{repo, repo2, repo4}, repos)
repos, err = s.Store.ListRepositories(
s.adminCtx,
params.RepositoryFilter{
Name: "test-repo",
Owner: "test-owner",
})
s.Require().Nil(err)
s.equalReposByName([]params.Repository{repo, repo2}, repos)
repos, err = s.Store.ListRepositories(
s.adminCtx,
params.RepositoryFilter{
Name: "test-repo",
Owner: "test-owner",
Endpoint: s.giteaEndpoint.Name,
})
s.Require().Nil(err)
s.equalReposByName([]params.Repository{repo2}, repos)
repos, err = s.Store.ListRepositories(
s.adminCtx,
params.RepositoryFilter{
Name: "test-repo2",
})
s.Require().Nil(err)
s.equalReposByName([]params.Repository{repo3}, repos)
}
func (s *RepoTestSuite) TestListRepositoriesDBFetchErr() { func (s *RepoTestSuite) TestListRepositoriesDBFetchErr() {
s.Fixtures.SQLMock. s.Fixtures.SQLMock.
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE `repositories`.`deleted_at` IS NULL")). ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE `repositories`.`deleted_at` IS NULL")).
WillReturnError(fmt.Errorf("fetching user from database mock error")) WillReturnError(fmt.Errorf("fetching user from database mock error"))
_, err := s.StoreSQLMocked.ListRepositories(s.adminCtx) _, err := s.StoreSQLMocked.ListRepositories(s.adminCtx, params.RepositoryFilter{})
s.Require().NotNil(err) s.Require().NotNil(err)
s.Require().Equal("fetching user from database: fetching user from database mock error", err.Error()) s.Require().Equal("fetching user from database: fetching user from database mock error", err.Error())
@ -401,7 +482,7 @@ func (s *RepoTestSuite) TestListRepositoriesDBDecryptingErr() {
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE `repositories`.`deleted_at` IS NULL")). ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE `repositories`.`deleted_at` IS NULL")).
WillReturnRows(sqlmock.NewRows([]string{"id", "webhook_secret"}).AddRow(s.Fixtures.Repos[0].ID, s.Fixtures.Repos[0].WebhookSecret)) WillReturnRows(sqlmock.NewRows([]string{"id", "webhook_secret"}).AddRow(s.Fixtures.Repos[0].ID, s.Fixtures.Repos[0].WebhookSecret))
_, err := s.StoreSQLMocked.ListRepositories(s.adminCtx) _, err := s.StoreSQLMocked.ListRepositories(s.adminCtx, params.RepositoryFilter{})
s.Require().NotNil(err) s.Require().NotNil(err)
s.Require().Equal("fetching repositories: decrypting secret: invalid passphrase length (expected length 32 characters)", err.Error()) s.Require().Equal("fetching repositories: decrypting secret: invalid passphrase length (expected length 32 characters)", err.Error())

View file

@ -85,6 +85,31 @@ func CreateGARMTestUser(ctx context.Context, username string, db common.Store, s
return user return user
} }
func CreateGHESEndpoint(ctx context.Context, db common.Store, s *testing.T) params.ForgeEndpoint {
endpointParams := params.CreateGithubEndpointParams{
Name: "ghes.example.com",
Description: "GHES endpoint",
APIBaseURL: "https://ghes.example.com",
UploadBaseURL: "https://upload.ghes.example.com/",
BaseURL: "https://ghes.example.com",
}
ep, err := db.GetGithubEndpoint(ctx, endpointParams.Name)
if err != nil {
if !errors.Is(err, runnerErrors.ErrNotFound) {
s.Fatalf("failed to get database object (%s): %v", endpointParams.Name, err)
}
ep, err = db.CreateGithubEndpoint(ctx, endpointParams)
if err != nil {
if !errors.Is(err, runnerErrors.ErrDuplicateEntity) {
s.Fatalf("failed to create database object (%s): %v", endpointParams.Name, err)
}
}
}
return ep
}
func CreateDefaultGithubEndpoint(ctx context.Context, db common.Store, s *testing.T) params.ForgeEndpoint { func CreateDefaultGithubEndpoint(ctx context.Context, db common.Store, s *testing.T) params.ForgeEndpoint {
endpointParams := params.CreateGithubEndpointParams{ endpointParams := params.CreateGithubEndpointParams{
Name: "github.com", Name: "github.com",

View file

@ -1192,3 +1192,19 @@ type ForgeEndpoint struct {
EndpointType EndpointType `json:"endpoint_type,omitempty"` EndpointType EndpointType `json:"endpoint_type,omitempty"`
} }
type RepositoryFilter struct {
Owner string
Name string
Endpoint string
}
type OrganizationFilter struct {
Name string
Endpoint string
}
type EnterpriseFilter struct {
Name string
Endpoint string
}

View file

@ -86,12 +86,12 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp
return enterprise, nil return enterprise, nil
} }
func (r *Runner) ListEnterprises(ctx context.Context) ([]params.Enterprise, error) { func (r *Runner) ListEnterprises(ctx context.Context, filter params.EnterpriseFilter) ([]params.Enterprise, error) {
if !auth.IsAdmin(ctx) { if !auth.IsAdmin(ctx) {
return nil, runnerErrors.ErrUnauthorized return nil, runnerErrors.ErrUnauthorized
} }
enterprises, err := r.store.ListEnterprises(ctx) enterprises, err := r.store.ListEnterprises(ctx, filter)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "listing enterprises") return nil, errors.Wrap(err, "listing enterprises")
} }

View file

@ -59,6 +59,8 @@ type EnterpriseTestSuite struct {
testCreds params.ForgeCredentials testCreds params.ForgeCredentials
secondaryTestCreds params.ForgeCredentials secondaryTestCreds params.ForgeCredentials
forgeEndpoint params.ForgeEndpoint forgeEndpoint params.ForgeEndpoint
ghesEndpoint params.ForgeEndpoint
ghesCreds params.ForgeCredentials
} }
func (s *EnterpriseTestSuite) SetupTest() { func (s *EnterpriseTestSuite) SetupTest() {
@ -71,8 +73,10 @@ func (s *EnterpriseTestSuite) SetupTest() {
adminCtx := garmTesting.ImpersonateAdminContext(context.Background(), db, s.T()) adminCtx := garmTesting.ImpersonateAdminContext(context.Background(), db, s.T())
s.forgeEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T()) s.forgeEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T())
s.ghesEndpoint = garmTesting.CreateGHESEndpoint(adminCtx, db, s.T())
s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.forgeEndpoint) s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.forgeEndpoint)
s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.forgeEndpoint) s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.forgeEndpoint)
s.ghesCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "ghes-creds", db, s.T(), s.ghesEndpoint)
// create some organization objects in the database, for testing purposes // create some organization objects in the database, for testing purposes
enterprises := map[string]params.Enterprise{} enterprises := map[string]params.Enterprise{}
@ -224,14 +228,74 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseStartPoolMgrFailed() {
func (s *EnterpriseTestSuite) TestListEnterprises() { func (s *EnterpriseTestSuite) TestListEnterprises() {
s.Fixtures.PoolMgrCtrlMock.On("GetEnterprisePoolManager", mock.AnythingOfType("params.Enterprise")).Return(s.Fixtures.PoolMgrMock, nil) s.Fixtures.PoolMgrCtrlMock.On("GetEnterprisePoolManager", mock.AnythingOfType("params.Enterprise")).Return(s.Fixtures.PoolMgrMock, nil)
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil) s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
orgs, err := s.Runner.ListEnterprises(s.Fixtures.AdminContext) orgs, err := s.Runner.ListEnterprises(s.Fixtures.AdminContext, params.EnterpriseFilter{})
s.Require().Nil(err) s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), garmTesting.DBEntityMapToSlice(s.Fixtures.StoreEnterprises), orgs) garmTesting.EqualDBEntityByName(s.T(), garmTesting.DBEntityMapToSlice(s.Fixtures.StoreEnterprises), orgs)
} }
func (s *EnterpriseTestSuite) TestListEnterprisesWithFilters() {
s.Fixtures.PoolMgrCtrlMock.On("GetEnterprisePoolManager", mock.AnythingOfType("params.Enterprise")).Return(s.Fixtures.PoolMgrMock, nil)
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
enterprise, err := s.Fixtures.Store.CreateEnterprise(
s.Fixtures.AdminContext,
"test-enterprise",
s.testCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
enterprise2, err := s.Fixtures.Store.CreateEnterprise(
s.Fixtures.AdminContext,
"test-enterprise2",
s.testCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
enterprise3, err := s.Fixtures.Store.CreateEnterprise(
s.Fixtures.AdminContext,
"test-enterprise",
s.ghesCreds,
"super secret",
params.PoolBalancerTypeRoundRobin,
)
s.Require().NoError(err)
orgs, err := s.Runner.ListEnterprises(
s.Fixtures.AdminContext,
params.EnterpriseFilter{
Name: "test-enterprise",
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Enterprise{enterprise, enterprise3}, orgs)
orgs, err = s.Runner.ListEnterprises(
s.Fixtures.AdminContext,
params.EnterpriseFilter{
Name: "test-enterprise",
Endpoint: s.ghesEndpoint.Name,
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Enterprise{enterprise3}, orgs)
orgs, err = s.Runner.ListEnterprises(
s.Fixtures.AdminContext,
params.EnterpriseFilter{
Name: "test-enterprise2",
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Enterprise{enterprise2}, orgs)
}
func (s *EnterpriseTestSuite) TestListEnterprisesErrUnauthorized() { func (s *EnterpriseTestSuite) TestListEnterprisesErrUnauthorized() {
_, err := s.Runner.ListEnterprises(context.Background()) _, err := s.Runner.ListEnterprises(context.Background(), params.EnterpriseFilter{})
s.Require().Equal(runnerErrors.ErrUnauthorized, err) s.Require().Equal(runnerErrors.ErrUnauthorized, err)
} }

View file

@ -19,6 +19,7 @@ import (
"strconv" "strconv"
"github.com/cloudbase/garm/metrics" "github.com/cloudbase/garm/metrics"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner" //nolint:typecheck "github.com/cloudbase/garm/runner" //nolint:typecheck
) )
@ -28,7 +29,7 @@ func CollectEnterpriseMetric(ctx context.Context, r *runner.Runner) error {
metrics.EnterpriseInfo.Reset() metrics.EnterpriseInfo.Reset()
metrics.EnterprisePoolManagerStatus.Reset() metrics.EnterprisePoolManagerStatus.Reset()
enterprises, err := r.ListEnterprises(ctx) enterprises, err := r.ListEnterprises(ctx, params.EnterpriseFilter{})
if err != nil { if err != nil {
return err return err
} }

View file

@ -19,6 +19,7 @@ import (
"strconv" "strconv"
"github.com/cloudbase/garm/metrics" "github.com/cloudbase/garm/metrics"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner" "github.com/cloudbase/garm/runner"
) )
@ -28,7 +29,7 @@ func CollectOrganizationMetric(ctx context.Context, r *runner.Runner) error {
metrics.OrganizationInfo.Reset() metrics.OrganizationInfo.Reset()
metrics.OrganizationPoolManagerStatus.Reset() metrics.OrganizationPoolManagerStatus.Reset()
organizations, err := r.ListOrganizations(ctx) organizations, err := r.ListOrganizations(ctx, params.OrganizationFilter{})
if err != nil { if err != nil {
return err return err
} }

View file

@ -19,6 +19,7 @@ import (
"strconv" "strconv"
"github.com/cloudbase/garm/metrics" "github.com/cloudbase/garm/metrics"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner" "github.com/cloudbase/garm/runner"
) )
@ -27,7 +28,7 @@ func CollectRepositoryMetric(ctx context.Context, r *runner.Runner) error {
metrics.EnterpriseInfo.Reset() metrics.EnterpriseInfo.Reset()
metrics.EnterprisePoolManagerStatus.Reset() metrics.EnterprisePoolManagerStatus.Reset()
repositories, err := r.ListRepositories(ctx) repositories, err := r.ListRepositories(ctx, params.RepositoryFilter{})
if err != nil { if err != nil {
return err return err
} }

View file

@ -95,12 +95,12 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP
return org, nil return org, nil
} }
func (r *Runner) ListOrganizations(ctx context.Context) ([]params.Organization, error) { func (r *Runner) ListOrganizations(ctx context.Context, filter params.OrganizationFilter) ([]params.Organization, error) {
if !auth.IsAdmin(ctx) { if !auth.IsAdmin(ctx) {
return nil, runnerErrors.ErrUnauthorized return nil, runnerErrors.ErrUnauthorized
} }
orgs, err := r.store.ListOrganizations(ctx) orgs, err := r.store.ListOrganizations(ctx, filter)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "listing organizations") return nil, errors.Wrap(err, "listing organizations")
} }

View file

@ -58,7 +58,9 @@ type OrgTestSuite struct {
testCreds params.ForgeCredentials testCreds params.ForgeCredentials
secondaryTestCreds params.ForgeCredentials secondaryTestCreds params.ForgeCredentials
giteaTestCreds params.ForgeCredentials
githubEndpoint params.ForgeEndpoint githubEndpoint params.ForgeEndpoint
giteaEndpoint params.ForgeEndpoint
} }
func (s *OrgTestSuite) SetupTest() { func (s *OrgTestSuite) SetupTest() {
@ -72,7 +74,9 @@ func (s *OrgTestSuite) SetupTest() {
adminCtx := garmTesting.ImpersonateAdminContext(context.Background(), db, s.T()) adminCtx := garmTesting.ImpersonateAdminContext(context.Background(), db, s.T())
s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T()) s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T())
s.giteaEndpoint = garmTesting.CreateDefaultGiteaEndpoint(adminCtx, db, s.T())
s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint) s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint)
s.giteaTestCreds = garmTesting.CreateTestGiteaCredentials(adminCtx, "gitea-creds", db, s.T(), s.giteaEndpoint)
s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint) s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint)
// create some organization objects in the database, for testing purposes // create some organization objects in the database, for testing purposes
@ -238,14 +242,74 @@ func (s *OrgTestSuite) TestCreateOrganizationStartPoolMgrFailed() {
func (s *OrgTestSuite) TestListOrganizations() { func (s *OrgTestSuite) TestListOrganizations() {
s.Fixtures.PoolMgrCtrlMock.On("GetOrgPoolManager", mock.AnythingOfType("params.Organization")).Return(s.Fixtures.PoolMgrMock, nil) s.Fixtures.PoolMgrCtrlMock.On("GetOrgPoolManager", mock.AnythingOfType("params.Organization")).Return(s.Fixtures.PoolMgrMock, nil)
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil) s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
orgs, err := s.Runner.ListOrganizations(s.Fixtures.AdminContext) orgs, err := s.Runner.ListOrganizations(s.Fixtures.AdminContext, params.OrganizationFilter{})
s.Require().Nil(err) s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), garmTesting.DBEntityMapToSlice(s.Fixtures.StoreOrgs), orgs) garmTesting.EqualDBEntityByName(s.T(), garmTesting.DBEntityMapToSlice(s.Fixtures.StoreOrgs), orgs)
} }
func (s *OrgTestSuite) TestListOrganizationsWithFilter() {
s.Fixtures.PoolMgrCtrlMock.On("GetOrgPoolManager", mock.AnythingOfType("params.Organization")).Return(s.Fixtures.PoolMgrMock, nil)
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
org, err := s.Fixtures.Store.CreateOrganization(
s.Fixtures.AdminContext,
"test-org",
s.testCreds,
"super-secret",
params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
org2, err := s.Fixtures.Store.CreateOrganization(
s.Fixtures.AdminContext,
"test-org",
s.giteaTestCreds,
"super-secret",
params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
org3, err := s.Fixtures.Store.CreateOrganization(
s.Fixtures.AdminContext,
"test-org2",
s.giteaTestCreds,
"super-secret",
params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
orgs, err := s.Runner.ListOrganizations(
s.Fixtures.AdminContext,
params.OrganizationFilter{
Name: "test-org",
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Organization{org, org2}, orgs)
orgs, err = s.Runner.ListOrganizations(
s.Fixtures.AdminContext,
params.OrganizationFilter{
Name: "test-org",
Endpoint: s.giteaEndpoint.Name,
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Organization{org2}, orgs)
orgs, err = s.Runner.ListOrganizations(
s.Fixtures.AdminContext,
params.OrganizationFilter{
Name: "test-org2",
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Organization{org3}, orgs)
}
func (s *OrgTestSuite) TestListOrganizationsErrUnauthorized() { func (s *OrgTestSuite) TestListOrganizationsErrUnauthorized() {
_, err := s.Runner.ListOrganizations(context.Background()) _, err := s.Runner.ListOrganizations(context.Background(), params.OrganizationFilter{})
s.Require().Equal(runnerErrors.ErrUnauthorized, err) s.Require().Equal(runnerErrors.ErrUnauthorized, err)
} }

View file

@ -93,12 +93,12 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa
return repo, nil return repo, nil
} }
func (r *Runner) ListRepositories(ctx context.Context) ([]params.Repository, error) { func (r *Runner) ListRepositories(ctx context.Context, filter params.RepositoryFilter) ([]params.Repository, error) {
if !auth.IsAdmin(ctx) { if !auth.IsAdmin(ctx) {
return nil, runnerErrors.ErrUnauthorized return nil, runnerErrors.ErrUnauthorized
} }
repos, err := r.store.ListRepositories(ctx) repos, err := r.store.ListRepositories(ctx, filter)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "listing repositories") return nil, errors.Wrap(err, "listing repositories")
} }

View file

@ -62,7 +62,9 @@ type RepoTestSuite struct {
testCreds params.ForgeCredentials testCreds params.ForgeCredentials
secondaryTestCreds params.ForgeCredentials secondaryTestCreds params.ForgeCredentials
giteaTestCreds params.ForgeCredentials
githubEndpoint params.ForgeEndpoint githubEndpoint params.ForgeEndpoint
giteaEndpoint params.ForgeEndpoint
} }
func (s *RepoTestSuite) SetupTest() { func (s *RepoTestSuite) SetupTest() {
@ -75,8 +77,10 @@ func (s *RepoTestSuite) SetupTest() {
adminCtx := garmTesting.ImpersonateAdminContext(context.Background(), db, s.T()) adminCtx := garmTesting.ImpersonateAdminContext(context.Background(), db, s.T())
s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T()) s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T())
s.giteaEndpoint = garmTesting.CreateDefaultGiteaEndpoint(adminCtx, db, s.T())
s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint) s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint)
s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint) s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint)
s.giteaTestCreds = garmTesting.CreateTestGiteaCredentials(adminCtx, "gitea-creds", db, s.T(), s.giteaEndpoint)
// create some repository objects in the database, for testing purposes // create some repository objects in the database, for testing purposes
repos := map[string]params.Repository{} repos := map[string]params.Repository{}
@ -254,14 +258,81 @@ func (s *RepoTestSuite) TestCreateRepositoryStartPoolMgrFailed() {
func (s *RepoTestSuite) TestListRepositories() { func (s *RepoTestSuite) TestListRepositories() {
s.Fixtures.PoolMgrCtrlMock.On("GetRepoPoolManager", mock.AnythingOfType("params.Repository")).Return(s.Fixtures.PoolMgrMock, nil) s.Fixtures.PoolMgrCtrlMock.On("GetRepoPoolManager", mock.AnythingOfType("params.Repository")).Return(s.Fixtures.PoolMgrMock, nil)
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil) s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
repos, err := s.Runner.ListRepositories(s.Fixtures.AdminContext) repos, err := s.Runner.ListRepositories(s.Fixtures.AdminContext, params.RepositoryFilter{})
s.Require().Nil(err) s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), garmTesting.DBEntityMapToSlice(s.Fixtures.StoreRepos), repos) garmTesting.EqualDBEntityByName(s.T(), garmTesting.DBEntityMapToSlice(s.Fixtures.StoreRepos), repos)
} }
func (s *RepoTestSuite) TestListRepositoriesWithFilters() {
s.Fixtures.PoolMgrCtrlMock.On("GetRepoPoolManager", mock.AnythingOfType("params.Repository")).Return(s.Fixtures.PoolMgrMock, nil)
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
repo, err := s.Fixtures.Store.CreateRepository(
s.Fixtures.AdminContext,
"example-owner",
"example-repo",
s.testCreds,
"test-webhook-secret",
params.PoolBalancerTypeRoundRobin,
)
if err != nil {
s.FailNow(fmt.Sprintf("failed to create database object (example-repo): %q", err))
}
repo2, err := s.Fixtures.Store.CreateRepository(
s.Fixtures.AdminContext,
"another-example-owner",
"example-repo",
s.testCreds,
"test-webhook-secret",
params.PoolBalancerTypeRoundRobin,
)
if err != nil {
s.FailNow(fmt.Sprintf("failed to create database object (example-repo): %q", err))
}
repo3, err := s.Fixtures.Store.CreateRepository(
s.Fixtures.AdminContext,
"example-owner",
"example-repo",
s.giteaTestCreds,
"test-webhook-secret",
params.PoolBalancerTypeRoundRobin,
)
if err != nil {
s.FailNow(fmt.Sprintf("failed to create database object (example-repo): %q", err))
}
repos, err := s.Runner.ListRepositories(s.Fixtures.AdminContext, params.RepositoryFilter{Name: "example-repo"})
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Repository{repo, repo2, repo3}, repos)
repos, err = s.Runner.ListRepositories(
s.Fixtures.AdminContext,
params.RepositoryFilter{
Name: "example-repo",
Owner: "example-owner",
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Repository{repo, repo3}, repos)
repos, err = s.Runner.ListRepositories(
s.Fixtures.AdminContext,
params.RepositoryFilter{
Name: "example-repo",
Owner: "example-owner",
Endpoint: s.giteaEndpoint.Name,
},
)
s.Require().Nil(err)
garmTesting.EqualDBEntityByName(s.T(), []params.Repository{repo3}, repos)
}
func (s *RepoTestSuite) TestListRepositoriesErrUnauthorized() { func (s *RepoTestSuite) TestListRepositoriesErrUnauthorized() {
_, err := s.Runner.ListRepositories(context.Background()) _, err := s.Runner.ListRepositories(context.Background(), params.RepositoryFilter{})
s.Require().Equal(runnerErrors.ErrUnauthorized, err) s.Require().Equal(runnerErrors.ErrUnauthorized, err)
} }

View file

@ -327,17 +327,17 @@ func (r *Runner) loadReposOrgsAndEnterprises() error {
r.mux.Lock() r.mux.Lock()
defer r.mux.Unlock() defer r.mux.Unlock()
repos, err := r.store.ListRepositories(r.ctx) repos, err := r.store.ListRepositories(r.ctx, params.RepositoryFilter{})
if err != nil { if err != nil {
return errors.Wrap(err, "fetching repositories") return errors.Wrap(err, "fetching repositories")
} }
orgs, err := r.store.ListOrganizations(r.ctx) orgs, err := r.store.ListOrganizations(r.ctx, params.OrganizationFilter{})
if err != nil { if err != nil {
return errors.Wrap(err, "fetching organizations") return errors.Wrap(err, "fetching organizations")
} }
enterprises, err := r.store.ListEnterprises(r.ctx) enterprises, err := r.store.ListEnterprises(r.ctx, params.EnterpriseFilter{})
if err != nil { if err != nil {
return errors.Wrap(err, "fetching enterprises") return errors.Wrap(err, "fetching enterprises")
} }

View file

@ -96,17 +96,17 @@ func (w *Worker) loadAllEntities() error {
return fmt.Errorf("listing scale sets: %w", err) return fmt.Errorf("listing scale sets: %w", err)
} }
repos, err := w.store.ListRepositories(w.ctx) repos, err := w.store.ListRepositories(w.ctx, params.RepositoryFilter{})
if err != nil { if err != nil {
return fmt.Errorf("listing repositories: %w", err) return fmt.Errorf("listing repositories: %w", err)
} }
orgs, err := w.store.ListOrganizations(w.ctx) orgs, err := w.store.ListOrganizations(w.ctx, params.OrganizationFilter{})
if err != nil { if err != nil {
return fmt.Errorf("listing organizations: %w", err) return fmt.Errorf("listing organizations: %w", err)
} }
enterprises, err := w.store.ListEnterprises(w.ctx) enterprises, err := w.store.ListEnterprises(w.ctx, params.EnterpriseFilter{})
if err != nil { if err != nil {
return fmt.Errorf("listing enterprises: %w", err) return fmt.Errorf("listing enterprises: %w", err)
} }

View file

@ -24,6 +24,7 @@ import (
"github.com/cloudbase/garm/auth" "github.com/cloudbase/garm/auth"
dbCommon "github.com/cloudbase/garm/database/common" dbCommon "github.com/cloudbase/garm/database/common"
"github.com/cloudbase/garm/database/watcher" "github.com/cloudbase/garm/database/watcher"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner/common" "github.com/cloudbase/garm/runner/common"
garmUtil "github.com/cloudbase/garm/util" garmUtil "github.com/cloudbase/garm/util"
) )
@ -63,7 +64,7 @@ type Controller struct {
func (c *Controller) loadAllRepositories() error { func (c *Controller) loadAllRepositories() error {
c.mux.Lock() c.mux.Lock()
defer c.mux.Unlock() defer c.mux.Unlock()
repos, err := c.store.ListRepositories(c.ctx) repos, err := c.store.ListRepositories(c.ctx, params.RepositoryFilter{})
if err != nil { if err != nil {
return fmt.Errorf("fetching repositories: %w", err) return fmt.Errorf("fetching repositories: %w", err)
} }
@ -95,7 +96,7 @@ func (c *Controller) loadAllRepositories() error {
func (c *Controller) loadAllOrganizations() error { func (c *Controller) loadAllOrganizations() error {
c.mux.Lock() c.mux.Lock()
defer c.mux.Unlock() defer c.mux.Unlock()
orgs, err := c.store.ListOrganizations(c.ctx) orgs, err := c.store.ListOrganizations(c.ctx, params.OrganizationFilter{})
if err != nil { if err != nil {
return fmt.Errorf("fetching organizations: %w", err) return fmt.Errorf("fetching organizations: %w", err)
} }
@ -127,7 +128,7 @@ func (c *Controller) loadAllOrganizations() error {
func (c *Controller) loadAllEnterprises() error { func (c *Controller) loadAllEnterprises() error {
c.mux.Lock() c.mux.Lock()
defer c.mux.Unlock() defer c.mux.Unlock()
enterprises, err := c.store.ListEnterprises(c.ctx) enterprises, err := c.store.ListEnterprises(c.ctx, params.EnterpriseFilter{})
if err != nil { if err != nil {
return fmt.Errorf("fetching enterprises: %w", err) return fmt.Errorf("fetching enterprises: %w", err)
} }