endpoint to paginate through all repos
This commit is contained in:
parent
4596e510f6
commit
cbfd342333
6 changed files with 152 additions and 46 deletions
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Added
|
||||
- added nsswitch to docker images
|
||||
- option to auto-cancel pending builds when newer build enqueued, by [@bradrydzewski](https://github.com/bradrydzewski). [#1980](https://github.com/drone/drone/issues/1980).
|
||||
- endpoint to list all repositories in the database, by [@bradrydzewski](https://github.com/bradrydzewski). [#2785](https://github.com/drone/drone/issues/2785).
|
||||
|
||||
## [1.5.1] - 2019-09-30
|
||||
### Added
|
||||
|
|
|
@ -82,6 +82,10 @@ type (
|
|||
// the datastore with incomplete builds.
|
||||
ListIncomplete(context.Context) ([]*Repository, error)
|
||||
|
||||
// ListAll returns a paginated list of all repositories
|
||||
// stored in the database, including disabled repositories.
|
||||
ListAll(ctx context.Context, limit, offset int) ([]*Repository, error)
|
||||
|
||||
// Find returns a repository from the datastore.
|
||||
Find(context.Context, int64) (*Repository, error)
|
||||
|
||||
|
|
|
@ -154,67 +154,72 @@ func (s Server) Handler() http.Handler {
|
|||
cors := cors.New(corsOpts)
|
||||
r.Use(cors.Handler)
|
||||
|
||||
r.Route("/repos/{owner}/{name}", func(r chi.Router) {
|
||||
r.Use(acl.InjectRepository(s.Repoz, s.Repos, s.Perms))
|
||||
r.Use(acl.CheckReadAccess())
|
||||
|
||||
r.Get("/", repos.HandleFind())
|
||||
r.Route("/repos", func(r chi.Router) {
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Patch("/", repos.HandleUpdate(s.Repos))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/", repos.HandleEnable(s.Hooks, s.Repos, s.Webhook))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Delete("/", repos.HandleDisable(s.Repos, s.Webhook))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/chown", repos.HandleChown(s.Repos))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/repair", repos.HandleRepair(s.Hooks, s.Repoz, s.Repos, s.Users, s.System.Link))
|
||||
).Get("/", repos.HandleAll(s.Repos))
|
||||
|
||||
r.Route("/builds", func(r chi.Router) {
|
||||
r.Get("/", builds.HandleList(s.Repos, s.Builds))
|
||||
r.With(acl.CheckWriteAccess()).Post("/", builds.HandleCreate(s.Repos, s.Commits, s.Triggerer))
|
||||
|
||||
r.Get("/latest", builds.HandleLast(s.Repos, s.Builds, s.Stages))
|
||||
r.Get("/{number}", builds.HandleFind(s.Repos, s.Builds, s.Stages))
|
||||
r.Get("/{number}/logs/{stage}/{step}", logs.HandleFind(s.Repos, s.Builds, s.Stages, s.Steps, s.Logs))
|
||||
|
||||
r.With(
|
||||
acl.CheckWriteAccess(),
|
||||
).Post("/{number}", builds.HandleRetry(s.Repos, s.Builds, s.Triggerer))
|
||||
|
||||
r.With(
|
||||
acl.CheckWriteAccess(),
|
||||
).Delete("/{number}", builds.HandleCancel(s.Users, s.Repos, s.Builds, s.Stages, s.Steps, s.Status, s.Scheduler, s.Webhook))
|
||||
|
||||
r.With(
|
||||
acl.CheckWriteAccess(),
|
||||
).Post("/{number}/promote", builds.HandlePromote(s.Repos, s.Builds, s.Triggerer))
|
||||
r.Route("/{owner}/{name}", func(r chi.Router) {
|
||||
r.Use(acl.InjectRepository(s.Repoz, s.Repos, s.Perms))
|
||||
r.Use(acl.CheckReadAccess())
|
||||
|
||||
r.Get("/", repos.HandleFind())
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/{number}/rollback", builds.HandleRollback(s.Repos, s.Builds, s.Triggerer))
|
||||
|
||||
).Patch("/", repos.HandleUpdate(s.Repos))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/{number}/decline/{stage}", stages.HandleDecline(s.Repos, s.Builds, s.Stages))
|
||||
|
||||
).Post("/", repos.HandleEnable(s.Hooks, s.Repos, s.Webhook))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/{number}/approve/{stage}", stages.HandleApprove(s.Repos, s.Builds, s.Stages, s.Scheduler))
|
||||
|
||||
).Delete("/", repos.HandleDisable(s.Repos, s.Webhook))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Delete("/{number}/logs/{stage}/{step}", logs.HandleDelete(s.Repos, s.Builds, s.Stages, s.Steps, s.Logs))
|
||||
|
||||
).Post("/chown", repos.HandleChown(s.Repos))
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Delete("/", builds.HandlePurge(s.Repos, s.Builds))
|
||||
).Post("/repair", repos.HandleRepair(s.Hooks, s.Repoz, s.Repos, s.Users, s.System.Link))
|
||||
|
||||
r.Route("/builds", func(r chi.Router) {
|
||||
r.Get("/", builds.HandleList(s.Repos, s.Builds))
|
||||
r.With(acl.CheckWriteAccess()).Post("/", builds.HandleCreate(s.Repos, s.Commits, s.Triggerer))
|
||||
|
||||
r.Get("/latest", builds.HandleLast(s.Repos, s.Builds, s.Stages))
|
||||
r.Get("/{number}", builds.HandleFind(s.Repos, s.Builds, s.Stages))
|
||||
r.Get("/{number}/logs/{stage}/{step}", logs.HandleFind(s.Repos, s.Builds, s.Stages, s.Steps, s.Logs))
|
||||
|
||||
r.With(
|
||||
acl.CheckWriteAccess(),
|
||||
).Post("/{number}", builds.HandleRetry(s.Repos, s.Builds, s.Triggerer))
|
||||
|
||||
r.With(
|
||||
acl.CheckWriteAccess(),
|
||||
).Delete("/{number}", builds.HandleCancel(s.Users, s.Repos, s.Builds, s.Stages, s.Steps, s.Status, s.Scheduler, s.Webhook))
|
||||
|
||||
r.With(
|
||||
acl.CheckWriteAccess(),
|
||||
).Post("/{number}/promote", builds.HandlePromote(s.Repos, s.Builds, s.Triggerer))
|
||||
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/{number}/rollback", builds.HandleRollback(s.Repos, s.Builds, s.Triggerer))
|
||||
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/{number}/decline/{stage}", stages.HandleDecline(s.Repos, s.Builds, s.Stages))
|
||||
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Post("/{number}/approve/{stage}", stages.HandleApprove(s.Repos, s.Builds, s.Stages, s.Scheduler))
|
||||
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Delete("/{number}/logs/{stage}/{step}", logs.HandleDelete(s.Repos, s.Builds, s.Stages, s.Steps, s.Logs))
|
||||
|
||||
r.With(
|
||||
acl.CheckAdminAccess(),
|
||||
).Delete("/", builds.HandlePurge(s.Repos, s.Builds))
|
||||
})
|
||||
})
|
||||
|
||||
r.Route("/secrets", func(r chi.Router) {
|
||||
|
|
55
handler/api/repos/all.go
Normal file
55
handler/api/repos/all.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2019 Drone IO, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package repos
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/drone/drone/core"
|
||||
"github.com/drone/drone/handler/api/render"
|
||||
"github.com/drone/drone/logger"
|
||||
)
|
||||
|
||||
// HandleAll returns an http.HandlerFunc that processes http
|
||||
// requests to list all repositories in the database.
|
||||
func HandleAll(repos core.RepositoryStore) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
page = r.FormValue("page")
|
||||
perPage = r.FormValue("per_page")
|
||||
)
|
||||
offset, _ := strconv.Atoi(page)
|
||||
limit, _ := strconv.Atoi(perPage)
|
||||
if limit < 1 { // || limit > 100
|
||||
limit = 25
|
||||
}
|
||||
switch offset {
|
||||
case 0, 1:
|
||||
offset = 0
|
||||
default:
|
||||
offset = (offset - 1) * limit
|
||||
}
|
||||
repo, err := repos.ListAll(r.Context(), limit, offset)
|
||||
if err != nil {
|
||||
render.InternalError(w, err)
|
||||
logger.FromRequest(r).
|
||||
WithError(err).
|
||||
Debugln("api: cannot list repositories")
|
||||
} else {
|
||||
render.JSON(w, repo, 200)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1768,6 +1768,21 @@ func (mr *MockRepositoryStoreMockRecorder) List(arg0, arg1 interface{}) *gomock.
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockRepositoryStore)(nil).List), arg0, arg1)
|
||||
}
|
||||
|
||||
// ListAll mocks base method
|
||||
func (m *MockRepositoryStore) ListAll(arg0 context.Context, arg1, arg2 int) ([]*core.Repository, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListAll", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].([]*core.Repository)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ListAll indicates an expected call of ListAll
|
||||
func (mr *MockRepositoryStoreMockRecorder) ListAll(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAll", reflect.TypeOf((*MockRepositoryStore)(nil).ListAll), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ListIncomplete mocks base method
|
||||
func (m *MockRepositoryStore) ListIncomplete(arg0 context.Context) ([]*core.Repository, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -104,6 +104,27 @@ func (s *repoStore) ListIncomplete(ctx context.Context) ([]*core.Repository, err
|
|||
return out, err
|
||||
}
|
||||
|
||||
func (s *repoStore) ListAll(ctx context.Context, limit, offset int) ([]*core.Repository, error) {
|
||||
var out []*core.Repository
|
||||
err := s.db.View(func(queryer db.Queryer, binder db.Binder) error {
|
||||
params := map[string]interface{}{
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}
|
||||
query, args, err := binder.BindNamed(queryAll, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := queryer.Query(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out, err = scanRows(rows)
|
||||
return err
|
||||
})
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (s *repoStore) Find(ctx context.Context, id int64) (*core.Repository, error) {
|
||||
out := &core.Repository{ID: id}
|
||||
err := s.db.View(func(queryer db.Queryer, binder db.Binder) error {
|
||||
|
@ -329,6 +350,11 @@ WHERE perms.perm_user_id = :user_id
|
|||
ORDER BY repo_slug ASC
|
||||
`
|
||||
|
||||
const queryAll = queryCols + `
|
||||
FROM repos
|
||||
LIMIT :limit OFFSET :offset
|
||||
`
|
||||
|
||||
const stmtDelete = `
|
||||
DELETE FROM repos WHERE repo_id = :repo_id
|
||||
`
|
||||
|
|
Loading…
Reference in a new issue