Skip to content

Commit

Permalink
gateway: add api to get commit status deliveries
Browse files Browse the repository at this point in the history
add an api to get commit status deliveries by project ref.
  • Loading branch information
alessandro-sorint committed Dec 14, 2023
1 parent e83156f commit e515f66
Show file tree
Hide file tree
Showing 7 changed files with 481 additions and 0 deletions.
84 changes: 84 additions & 0 deletions internal/services/gateway/action/commitstatusdelivery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2023 Sorint.lab
//
// 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 action

import (
"context"

"github.com/sorintlab/errors"

"agola.io/agola/internal/util"
"agola.io/agola/services/notification/client"
nstypes "agola.io/agola/services/notification/types"
)

type GetProjectCommitStatusDeliveriesRequest struct {
ProjectRef string
DeliveryStatusFilter []string

Cursor string

Limit int
SortDirection SortDirection
}

type GetProjectCommitStatusDeliveriesResponse struct {
CommitStatusDeliveries []*nstypes.CommitStatusDelivery
Cursor string
}

func (h *ActionHandler) GetProjectCommitStatusDeliveries(ctx context.Context, req *GetProjectCommitStatusDeliveriesRequest) (*GetProjectCommitStatusDeliveriesResponse, error) {
project, _, err := h.configstoreClient.GetProject(ctx, req.ProjectRef)
if err != nil {
return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
}
isUserOwner, err := h.IsAuthUserProjectOwner(ctx, project.OwnerType, project.OwnerID)
if err != nil {
return nil, errors.Wrapf(err, "failed to determine permissions")
}
if !isUserOwner {
return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
}

inCursor := &StartSequenceCursor{}
sortDirection := req.SortDirection
if req.Cursor != "" {
if err := UnmarshalCursor(req.Cursor, inCursor); err != nil {
return nil, errors.WithStack(err)
}
sortDirection = inCursor.SortDirection
}

commitStatusDeliveries, resp, err := h.notificationClient.GetProjectCommitStatusDeliveries(ctx, project.ID, &client.GetProjectCommitStatusDeliveriesOptions{ListOptions: &client.ListOptions{Limit: req.Limit, SortDirection: nstypes.SortDirection(sortDirection)}, StartSequence: inCursor.StartSequence, DeliveryStatusFilter: req.DeliveryStatusFilter})
if err != nil {
return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
}

var outCursor string
if resp.HasMore && len(commitStatusDeliveries) > 0 {
lastCommitStatusDeliverySequence := commitStatusDeliveries[len(commitStatusDeliveries)-1].Sequence
outCursor, err = MarshalCursor(&StartSequenceCursor{StartSequence: lastCommitStatusDeliverySequence})
if err != nil {
return nil, errors.WithStack(err)
}
}

res := &GetProjectCommitStatusDeliveriesResponse{
CommitStatusDeliveries: commitStatusDeliveries,
Cursor: outCursor,
}

return res, nil
}
96 changes: 96 additions & 0 deletions internal/services/gateway/api/commitstatusdelivery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2023 Sorint.lab
//
// 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 api

import (
"net/http"

"github.com/gorilla/mux"
"github.com/rs/zerolog"
"github.com/sorintlab/errors"

"agola.io/agola/internal/services/gateway/action"
util "agola.io/agola/internal/util"
gwapitypes "agola.io/agola/services/gateway/api/types"
nstypes "agola.io/agola/services/notification/types"
)

func createCommitStatusDeliveryResponse(r *nstypes.CommitStatusDelivery) *gwapitypes.CommitStatusDeliveryResponse {
commitStatusDelivery := &gwapitypes.CommitStatusDeliveryResponse{
ID: r.ID,
Sequence: r.Sequence,
DeliveryStatus: gwapitypes.DeliveryStatus(r.DeliveryStatus),
DeliveredAt: r.DeliveredAt,
}
return commitStatusDelivery
}

type ProjectCommitStatusDeliveries struct {
log zerolog.Logger
ah *action.ActionHandler
}

func NewProjectCommitStatusDeliveriesHandler(log zerolog.Logger, ah *action.ActionHandler) *ProjectCommitStatusDeliveries {
return &ProjectCommitStatusDeliveries{log: log, ah: ah}
}

func (h *ProjectCommitStatusDeliveries) ServeHTTP(w http.ResponseWriter, r *http.Request) {
res, err := h.do(w, r)
if util.HTTPError(w, err) {
h.log.Err(err).Send()
return
}

if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Err(err).Send()
}
}

func (h *ProjectCommitStatusDeliveries) do(w http.ResponseWriter, r *http.Request) ([]*gwapitypes.CommitStatusDeliveryResponse, error) {
ctx := r.Context()
query := r.URL.Query()

vars := mux.Vars(r)
projectRef := vars["projectref"]

deliveryStatusFilter := query["deliverystatus"]

ropts, err := parseRequestOptions(r)
if err != nil {
return nil, errors.WithStack(err)
}

areq := &action.GetProjectCommitStatusDeliveriesRequest{
ProjectRef: projectRef,

DeliveryStatusFilter: deliveryStatusFilter,
Cursor: ropts.Cursor,
Limit: ropts.Limit,
SortDirection: action.SortDirection(ropts.SortDirection),
}
ares, err := h.ah.GetProjectCommitStatusDeliveries(ctx, areq)
if err != nil {
return nil, errors.WithStack(err)
}

commitStatusDeliveries := make([]*gwapitypes.CommitStatusDeliveryResponse, len(ares.CommitStatusDeliveries))
for i, r := range ares.CommitStatusDeliveries {
commitStatusDeliveries[i] = createCommitStatusDeliveryResponse(r)
}

addCursorHeader(w, ares.Cursor)

return commitStatusDeliveries, nil
}
2 changes: 2 additions & 0 deletions internal/services/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ func (g *Gateway) Run(ctx context.Context) error {
refreshRemoteRepositoryInfoHandler := api.NewRefreshRemoteRepositoryInfoHandler(g.log, g.ah)
projectRunWebhookDeliveriesHandler := api.NewProjectRunWebhookDeliveriesHandler(g.log, g.ah)
projectRunWebhookRedeliveryHandler := api.NewProjectRunWebhookRedeliveryHandler(g.log, g.ah)
projectCommitStatusDeliveriesHandler := api.NewProjectCommitStatusDeliveriesHandler(g.log, g.ah)

secretHandler := api.NewSecretHandler(g.log, g.ah)
createSecretHandler := api.NewCreateSecretHandler(g.log, g.ah)
Expand Down Expand Up @@ -322,6 +323,7 @@ func (g *Gateway) Run(ctx context.Context) error {
apirouter.Handle("/projects/{projectref}/refreshremoterepo", authForcedHandler(refreshRemoteRepositoryInfoHandler)).Methods("POST")
apirouter.Handle("/projects/{projectref}/runwebhookdeliveries", authForcedHandler(projectRunWebhookDeliveriesHandler)).Methods("GET")
apirouter.Handle("/projects/{projectref}/runwebhookdeliveries/{runwebhookdeliveryid}/redelivery", authForcedHandler(projectRunWebhookRedeliveryHandler)).Methods("PUT")
apirouter.Handle("/projects/{projectref}/commitstatusdeliveries", authForcedHandler(projectCommitStatusDeliveriesHandler)).Methods("GET")

apirouter.Handle("/projectgroups/{projectgroupref}/secrets", authForcedHandler(secretHandler)).Methods("GET")
apirouter.Handle("/projects/{projectref}/secrets", authForcedHandler(secretHandler)).Methods("GET")
Expand Down
24 changes: 24 additions & 0 deletions services/gateway/api/types/commitstatusdelivery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2023 Sorint.lab
//
// 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 types

import "time"

type CommitStatusDeliveryResponse struct {
ID string `json:"id"`
Sequence uint64 `json:"sequence"`
DeliveryStatus DeliveryStatus `json:"delivery_status"`
DeliveredAt *time.Time `json:"delivered_at"`
}
13 changes: 13 additions & 0 deletions services/gateway/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -828,3 +828,16 @@ func (c *Client) GetProjectRunWebhookDeliveries(ctx context.Context, projectRef
func (c *Client) ProjectRunWebhookRedelivery(ctx context.Context, projectRef string, runWebhookDeliveryID string) (*Response, error) {
return c.getResponse(ctx, "PUT", fmt.Sprintf("/projects/%s/runwebhookdeliveries/%s/redelivery", projectRef, runWebhookDeliveryID), nil, jsonContent, nil)
}

func (c *Client) GetProjectCommitStatusDeliveries(ctx context.Context, projectRef string, deliveryStatusFilter []string, opts *ListOptions) ([]*gwapitypes.CommitStatusDeliveryResponse, *Response, error) {
q := url.Values{}
opts.Add(q)

for _, deliveryStatus := range deliveryStatusFilter {
q.Add("deliverystatus", deliveryStatus)
}

commitStatusDeliveries := []*gwapitypes.CommitStatusDeliveryResponse{}
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/commitstatusdeliveries", url.PathEscape(projectRef)), q, common.JSONContent, nil, &commitStatusDeliveries)
return commitStatusDeliveries, resp, errors.WithStack(err)
}
28 changes: 28 additions & 0 deletions services/notification/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,31 @@ func (c *Client) RunWebhookRedelivery(ctx context.Context, projectID, runWebhook
resp, err := c.GetResponse(ctx, "PUT", fmt.Sprintf("/projects/%s/runwebhookdeliveries/%s/redelivery", projectID, runWebhookDeliveryID), nil, -1, common.JSONContent, nil)
return resp, errors.WithStack(err)
}

type GetProjectCommitStatusDeliveriesOptions struct {
*ListOptions

StartSequence uint64
DeliveryStatusFilter []string
}

func (o *GetProjectCommitStatusDeliveriesOptions) Add(q url.Values) {
o.ListOptions.Add(q)

if o.StartSequence > 0 {
q.Add("startsequence", strconv.FormatUint(o.StartSequence, 10))
}
}

func (c *Client) GetProjectCommitStatusDeliveries(ctx context.Context, projectID string, opts *GetProjectCommitStatusDeliveriesOptions) ([]*types.CommitStatusDelivery, *Response, error) {
q := url.Values{}
opts.Add(q)

for _, deliveryStatus := range opts.DeliveryStatusFilter {
q.Add("deliverystatus", deliveryStatus)
}

commitStatusDeliveries := []*types.CommitStatusDelivery{}
resp, err := c.GetParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/commitstatusdeliveries", projectID), q, common.JSONContent, nil, &commitStatusDeliveries)
return commitStatusDeliveries, resp, errors.WithStack(err)
}
Loading

0 comments on commit e515f66

Please # to comment.