Skip to content

Commit

Permalink
feat: Add support for Bitbucket webhooks (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
zmotso authored and SergK committed Oct 4, 2024
1 parent c5fb02b commit 6902508
Show file tree
Hide file tree
Showing 29 changed files with 98,210 additions and 101 deletions.
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ run:
issues-exit-code: 1
skip-dirs:
- "mocks"
- "generated"
skip-dirs-use-default: true
skip-files:
- "mock_.*\\.go"
Expand Down
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,19 @@ MOCKERY = $(LOCALBIN)/mockery
.PHONY: mockery
mockery: ## Download mockery locally if necessary.
$(call go-get-tool,$(MOCKERY),github.com/vektra/mockery/v2,v2.43.0)

OAPICODEGEN ?= $(LOCALBIN)/oapi-codegen

.PHONY: oapi-codegen
oapi-codegen: $(OAPICODEGEN) ## Download oapi-codegen locally if necessary.
$(OAPICODEGEN): $(LOCALBIN)
test -s $(LOCALBIN)/oapi-codegen || GOBIN=$(LOCALBIN) go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest

.PHONY: update-bitbucket-swagger
update-bitbucket-swagger: ## Update bitbucket swagger file
echo "Read hack/bitbucket_api_notes.md and make manual changes to hack/bitbucket_api.json after running this command"
curl -o hack/bitbucket_api.json https://dac-static.atlassian.com/cloud/bitbucket/swagger.v3.json?_v=2.300.64-0.1310.0

.PHONY: generate-bitbucket-api-client
generate-bitbucket-api-client: oapi-codegen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(OAPICODEGEN) -config oapicfg.yaml hack/bitbucket_api.json
14 changes: 14 additions & 0 deletions api/v1/codebase_types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package v1

import (
"strconv"
"strings"

metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -193,14 +194,27 @@ type CodebaseStatus struct {
Git string `json:"git"`

// Stores ID of webhook which was created for a codebase.
// Deprecated: Because the webhook id can be more than just an integer. Use WebHookRef instead.
// +optional
WebHookID int `json:"webHookID,omitempty"`

// WebHookRef stores unique reference to webhook which was created for a codebase.
// +optional
WebHookRef string `json:"webHookRef,omitempty"`

// Stores GitWebUrl of codebase.
// +optional
GitWebUrl string `json:"gitWebUrl,omitempty"`
}

func (in *CodebaseStatus) GetWebHookRef() string {
if in.WebHookRef == "" && in.WebHookID != 0 {
return strconv.Itoa(in.WebHookID)
}

return in.WebHookRef
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:shortName=cdbs
Expand Down
8 changes: 7 additions & 1 deletion config/crd/bases/v2.edp.epam.com_codebases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,14 @@ spec:
description: Specifies a current state of Codebase.
type: string
webHookID:
description: Stores ID of webhook which was created for a codebase.
description: |-
Stores ID of webhook which was created for a codebase.
Deprecated: Because the webhook id can be more than just an integer. Use WebHookRef instead.
type: integer
webHookRef:
description: WebHookRef stores unique reference to webhook which was
created for a codebase.
type: string
required:
- action
- available
Expand Down
8 changes: 8 additions & 0 deletions controllers/codebase/codebase_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"reflect"
"strconv"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -162,6 +163,12 @@ func (r *ReconcileCodebase) Reconcile(ctx context.Context, request reconcile.Req
}

func (r *ReconcileCodebase) updateFinishStatus(ctx context.Context, c *codebaseApi.Codebase) error {
// Set WebHookRef from WebHookID for backward compatibility.
webHookRef := c.Status.WebHookRef
if webHookRef == "" && c.Status.WebHookID != 0 {
webHookRef = strconv.Itoa(c.Status.WebHookID)
}

c.Status = codebaseApi.CodebaseStatus{
Status: util.StatusFinished,
Available: true,
Expand All @@ -173,6 +180,7 @@ func (r *ReconcileCodebase) updateFinishStatus(ctx context.Context, c *codebaseA
FailureCount: 0,
Git: c.Status.Git,
WebHookID: c.Status.WebHookID,
WebHookRef: webHookRef,
GitWebUrl: c.Status.GitWebUrl,
}

Expand Down
8 changes: 8 additions & 0 deletions controllers/codebase/service/chain/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package chain
import (
"context"
"fmt"
"strconv"

metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -12,6 +13,12 @@ import (
)

func setIntermediateSuccessFields(ctx context.Context, c client.Client, cb *codebaseApi.Codebase, action codebaseApi.ActionType) error {
// Set WebHookRef from WebHookID for backward compatibility.
webHookRef := cb.Status.WebHookRef
if webHookRef == "" && cb.Status.WebHookID != 0 {
webHookRef = strconv.Itoa(cb.Status.WebHookID)
}

cb.Status = codebaseApi.CodebaseStatus{
Status: util.StatusInProgress,
Available: false,
Expand All @@ -23,6 +30,7 @@ func setIntermediateSuccessFields(ctx context.Context, c client.Client, cb *code
FailureCount: cb.Status.FailureCount,
Git: cb.Status.Git,
WebHookID: cb.Status.WebHookID,
WebHookRef: webHookRef,
GitWebUrl: cb.Status.GitWebUrl,
}

Expand Down
8 changes: 4 additions & 4 deletions controllers/codebase/service/chain/delete_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func (s *DeleteWebHook) ServeRequest(ctx context.Context, codebase *codebaseApi.

log.Info("Start deleting webhook...")

if codebase.Status.WebHookID == 0 {
log.Info("Webhook ID is empty. Skip deleting webhook.")
if codebase.Status.GetWebHookRef() == "" {
log.Info("Webhook ref is empty. Skip deleting webhook.")

return nil
}
Expand All @@ -59,7 +59,7 @@ func (s *DeleteWebHook) ServeRequest(ctx context.Context, codebase *codebaseApi.
return nil
}

gitProvider, err := gitprovider.NewProvider(gitServer, s.restyClient)
gitProvider, err := gitprovider.NewProvider(gitServer, s.restyClient, string(secret.Data[util.GitServerSecretTokenField]))
if err != nil {
log.Error(err, "Failed to delete webhook: unable to create git provider")

Expand All @@ -74,7 +74,7 @@ func (s *DeleteWebHook) ServeRequest(ctx context.Context, codebase *codebaseApi.
gitHost,
string(secret.Data[util.GitServerSecretTokenField]),
projectID,
codebase.Status.WebHookID,
codebase.Status.GetWebHookRef(),
)
if err != nil {
if errors.Is(err, gitprovider.ErrWebHookNotFound) {
Expand Down
16 changes: 12 additions & 4 deletions controllers/codebase/service/chain/put_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"os"
"strconv"

"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
Expand All @@ -23,7 +24,7 @@ type PutProject struct {
client client.Client
git git.Git
gerrit gerrit.Client
gitProjectProvider func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error)
gitProjectProvider func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error)
}

var (
Expand All @@ -35,7 +36,7 @@ func NewPutProject(
c client.Client,
g git.Git,
gerritProvider gerrit.Client,
gitProjectProvider func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error),
gitProjectProvider func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error),
) *PutProject {
return &PutProject{client: c, git: g, gerrit: gerritProvider, gitProjectProvider: gitProjectProvider}
}
Expand Down Expand Up @@ -280,7 +281,7 @@ func (h *PutProject) createGitThirdPartyProject(ctx context.Context, gitServer *

log.Info("Start creating project in git provider")

gitProvider, err := h.gitProjectProvider(gitServer)
gitProvider, err := h.gitProjectProvider(gitServer, gitProviderToken)
if err != nil {
return fmt.Errorf("failed to create git provider: %w", err)
}
Expand Down Expand Up @@ -355,7 +356,7 @@ func (h *PutProject) setDefaultBranch(

log.Info("Set default branch in git provider")

gitProvider, err := h.gitProjectProvider(gitServer)
gitProvider, err := h.gitProjectProvider(gitServer, gitProviderToken)
if err != nil {
return fmt.Errorf("failed to create git provider: %w", err)
}
Expand Down Expand Up @@ -480,6 +481,12 @@ func (h *PutProject) notEmptyProjectProvisioning(ctx context.Context, codebase *
}

func setFailedFields(c *codebaseApi.Codebase, a codebaseApi.ActionType, message string) {
// Set WebHookRef from WebHookID for backward compatibility.
webHookRef := c.Status.WebHookRef
if webHookRef == "" && c.Status.WebHookID != 0 {
webHookRef = strconv.Itoa(c.Status.WebHookID)
}

c.Status = codebaseApi.CodebaseStatus{
Status: util.StatusFailed,
Available: false,
Expand All @@ -492,6 +499,7 @@ func setFailedFields(c *codebaseApi.Codebase, a codebaseApi.ActionType, message
FailureCount: c.Status.FailureCount,
Git: c.Status.Git,
WebHookID: c.Status.WebHookID,
WebHookRef: webHookRef,
GitWebUrl: c.Status.GitWebUrl,
}
}
32 changes: 16 additions & 16 deletions controllers/codebase/service/chain/put_project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ func TestPutProject_ServeRequest(t *testing.T) {
Namespace: defaultNs,
},
}
defaultGitProvider := func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
return func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
defaultGitProvider := func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return gitprovidermock.NewMockGitProjectProvider(t), nil
}
}
Expand All @@ -94,7 +94,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
objects []client.Object
gitClient func(t *testing.T) git.Git
gerritClient func(t *testing.T) gerrit.Client
gitProvider func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error)
gitProvider func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error)
wantErr require.ErrorAssertionFunc
wantStatus func(t *testing.T, status *codebaseApi.CodebaseStatus)
}{
Expand Down Expand Up @@ -898,7 +898,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return gerritmocks.NewMockClient(t)
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
mock := gitprovidermock.NewMockGitProjectProvider(t)

mock.On("ProjectExists", testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Expand All @@ -908,7 +908,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
On("SetDefaultBranch", testify.Anything, testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Return(nil)

return func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
return func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return mock, nil
}
},
Expand Down Expand Up @@ -954,7 +954,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return gerritmocks.NewMockClient(t)
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
mock := gitprovidermock.NewMockGitProjectProvider(t)

mock.On("ProjectExists", testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Expand All @@ -964,7 +964,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
On("SetDefaultBranch", testify.Anything, testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Return(nil)

return func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
return func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return mock, nil
}
},
Expand Down Expand Up @@ -1013,7 +1013,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return gerritmocks.NewMockClient(t)
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
mock := gitprovidermock.NewMockGitProjectProvider(t)

mock.On("ProjectExists", testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Expand All @@ -1023,7 +1023,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
On("SetDefaultBranch", testify.Anything, testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Return(nil)

return func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
return func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return mock, nil
}
},
Expand Down Expand Up @@ -1069,7 +1069,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return gerritmocks.NewMockClient(t)
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
mock := gitprovidermock.NewMockGitProjectProvider(t)

mock.On("ProjectExists", testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Expand All @@ -1079,7 +1079,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
On("SetDefaultBranch", testify.Anything, testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Return(nil)

return func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
return func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return mock, nil
}
},
Expand Down Expand Up @@ -1125,7 +1125,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return gerritmocks.NewMockClient(t)
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
mock := gitprovidermock.NewMockGitProjectProvider(t)

mock.On("ProjectExists", testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Expand All @@ -1135,7 +1135,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
On("SetDefaultBranch", testify.Anything, testify.Anything, testify.Anything, testify.Anything, testify.Anything).
Return(errors.New("failed to set default branch"))

return func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
return func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return mock, nil
}
},
Expand Down Expand Up @@ -1164,7 +1164,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return nil
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return nil
},
wantErr: require.NoError,
Expand Down Expand Up @@ -1192,7 +1192,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return nil
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return nil
},
wantErr: require.NoError,
Expand Down Expand Up @@ -1220,7 +1220,7 @@ func TestPutProject_ServeRequest(t *testing.T) {
gerritClient: func(t *testing.T) gerrit.Client {
return nil
},
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer) (gitprovider.GitProjectProvider, error) {
gitProvider: func(t *testing.T) func(gitServer *codebaseApi.GitServer, token string) (gitprovider.GitProjectProvider, error) {
return nil
},
wantErr: require.NoError,
Expand Down
Loading

0 comments on commit 6902508

Please sign in to comment.