diff --git a/internal/controllers/terraformpullrequest/controller.go b/internal/controllers/terraformpullrequest/controller.go index ad3ceb48..971dc792 100644 --- a/internal/controllers/terraformpullrequest/controller.go +++ b/internal/controllers/terraformpullrequest/controller.go @@ -9,6 +9,7 @@ import ( "github.com/padok-team/burrito/internal/controllers/terraformpullrequest/comment" "github.com/padok-team/burrito/internal/controllers/terraformpullrequest/github" "github.com/padok-team/burrito/internal/controllers/terraformpullrequest/gitlab" + "github.com/padok-team/burrito/internal/controllers/terraformpullrequest/mock" datastore "github.com/padok-team/burrito/internal/datastore/client" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -83,10 +84,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu } if _, ok := r.Providers[fmt.Sprintf("%s/%s", repository.Namespace, repository.Name)]; !ok { log.Infof("initializing provider for repository %s/%s", repository.Namespace, repository.Name) - r.Providers[fmt.Sprintf("%s/%s", repository.Namespace, repository.Name)], err = r.initializeProvider(ctx, repository) + provider, err := r.initializeProvider(ctx, repository) if err != nil { log.Errorf("could not initialize provider for repository %s: %s", repository.Name, err) - return ctrl.Result{}, err + } else { + r.Providers[fmt.Sprintf("%s/%s", repository.Namespace, repository.Name)] = provider } } state := r.GetState(ctx, pr) @@ -153,8 +155,9 @@ func (r *Reconciler) initializeProvider(ctx context.Context, repository *configv if repository.Spec.Repository.Url == "" { return nil, fmt.Errorf("no repository URL found in TerraformRepository.spec.repository.url, %s", repository.Name) } - - if secret.Data["githubAppId"] != nil && secret.Data["githubAppInstallationId"] != nil && secret.Data["githubAppPrivateKey"] != nil { + if secret.Data["enableMock"] != nil && string(secret.Data["enableMock"]) == "true" { + provider = &mock.Mock{} + } else if secret.Data["githubAppId"] != nil && secret.Data["githubAppInstallationId"] != nil && secret.Data["githubAppPrivateKey"] != nil { provider = &github.Github{ AppId: string(secret.Data["githubAppId"]), AppInstallationId: string(secret.Data["githubAppInstallationId"]), @@ -172,7 +175,7 @@ func (r *Reconciler) initializeProvider(ctx context.Context, repository *configv Url: repository.Spec.Repository.Url, } } else { - return nil, fmt.Errorf("no valid provider credentials found in secret. %s Please provide at least one of the following: , , in the secret referenced in TerraformRepository.spec.repository.secretName, %s", repository.Spec.Repository.SecretName) + return nil, fmt.Errorf("no valid provider credentials found in secret %s. Please provide at least one of the following: , , in the secret referenced in TerraformRepository.spec.repository.secretName", repository.Spec.Repository.SecretName) } err = provider.Init() diff --git a/internal/controllers/terraformpullrequest/controller_test.go b/internal/controllers/terraformpullrequest/controller_test.go index af00c380..1bf0ab67 100644 --- a/internal/controllers/terraformpullrequest/controller_test.go +++ b/internal/controllers/terraformpullrequest/controller_test.go @@ -179,8 +179,7 @@ var _ = Describe("TerraformPullRequest controller", func() { }, }, Spec: configv1alpha1.TerraformPullRequestSpec{ - Provider: "gitlab", - Branch: "test", + Branch: "test", Repository: configv1alpha1.TerraformLayerRepository{ Name: "test-repository", Namespace: "default", diff --git a/internal/controllers/terraformpullrequest/github/provider.go b/internal/controllers/terraformpullrequest/github/provider.go index d60f13c0..33fec279 100644 --- a/internal/controllers/terraformpullrequest/github/provider.go +++ b/internal/controllers/terraformpullrequest/github/provider.go @@ -44,7 +44,10 @@ func (g *Github) IsAPITokenConfigPresent() bool { } func (g *Github) Init() error { - apiUrl, subscription, err := inferBaseURL(g.Url) + apiUrl, subscription, err := inferBaseURL(utils.NormalizeUrl(g.Url)) + if err != nil { + return err + } httpClient := &http.Client{} if g.IsAppConfigPresent() { appId, err := strconv.ParseInt(g.AppId, 10, 64) diff --git a/internal/controllers/terraformpullrequest/gitlab/provider.go b/internal/controllers/terraformpullrequest/gitlab/provider.go index ecd6115a..0ac94654 100644 --- a/internal/controllers/terraformpullrequest/gitlab/provider.go +++ b/internal/controllers/terraformpullrequest/gitlab/provider.go @@ -21,7 +21,7 @@ type Gitlab struct { } func (g *Gitlab) Init() error { - apiUrl, err := inferBaseURL(g.Url) + apiUrl, err := inferBaseURL(utils.NormalizeUrl(g.Url)) if err != nil { return err } diff --git a/internal/controllers/terraformpullrequest/testdata/error-case.yaml b/internal/controllers/terraformpullrequest/testdata/error-case.yaml index 4bb9be35..c7872e67 100644 --- a/internal/controllers/terraformpullrequest/testdata/error-case.yaml +++ b/internal/controllers/terraformpullrequest/testdata/error-case.yaml @@ -8,7 +8,6 @@ metadata: annotations: webhook.terraform.padok.cloud/branch-commit: 04410b5b7d90b82ad658b86564a9aa4bce411ac9 spec: - provider: mock branch: feature-branch id: "42" base: main @@ -26,10 +25,9 @@ metadata: annotations: webhook.terraform.padok.cloud/branch-commit: 04410b5b7d90b82ad658b86564a9aa4bce411ac9 spec: - provider: no-exist branch: feature-branch id: "42" base: main repository: - name: burrito + name: burrito-no-provider namespace: default diff --git a/internal/controllers/terraformpullrequest/testdata/nominal-case.yaml b/internal/controllers/terraformpullrequest/testdata/nominal-case.yaml index 8b283468..3c70193b 100644 --- a/internal/controllers/terraformpullrequest/testdata/nominal-case.yaml +++ b/internal/controllers/terraformpullrequest/testdata/nominal-case.yaml @@ -8,7 +8,6 @@ metadata: annotations: webhook.terraform.padok.cloud/branch-commit: 04410b5b7d90b82ad658b86564a9aa4bce411ac9 spec: - provider: mock branch: feature-branch id: "42" base: main @@ -64,7 +63,6 @@ metadata: annotations: webhook.terraform.padok.cloud/branch-commit: 04410b5b7d90b82ad658b86564a9aa4bce411ac9 spec: - provider: mock branch: feature-branch-2 id: "84" base: main @@ -106,7 +104,6 @@ metadata: annotations: webhook.terraform.padok.cloud/branch-commit: 04410b5b7d90b82ad658b86564a9aa4bce411ac9 spec: - provider: mock branch: feature-branch-3 id: "48" base: main @@ -148,7 +145,6 @@ metadata: annotations: webhook.terraform.padok.cloud/branch-commit: 04410b5b7d90b82ad658b86564a9aa4bce411ac9 spec: - provider: mock branch: update-readme id: "100" base: main diff --git a/internal/controllers/terraformpullrequest/testdata/repository.yaml b/internal/controllers/terraformpullrequest/testdata/repository.yaml index fb641c3f..865f7de6 100644 --- a/internal/controllers/terraformpullrequest/testdata/repository.yaml +++ b/internal/controllers/terraformpullrequest/testdata/repository.yaml @@ -14,3 +14,39 @@ spec: url: git@github.com:padok-team/burrito-examples.git terraform: enabled: true +--- +apiVersion: v1 +kind: Secret +metadata: + name: burrito-repo + namespace: default +type: Opaque +stringData: + enableMock: "true" +--- +apiVersion: config.terraform.padok.cloud/v1alpha1 +kind: TerraformRepository +metadata: + labels: + app.kubernetes.io/instance: in-cluster-burrito + name: burrito-no-provider + namespace: default +spec: + overrideRunnerSpec: + imagePullSecrets: + - name: ghcr-creds + repository: + secretName: burrito-repo-no-provider + url: git@github.com:padok-team/burrito-examples.git + terraform: + enabled: true +--- +apiVersion: v1 +kind: Secret +metadata: + name: burrito-repo-no-provider + namespace: default +type: Opaque +stringData: + username: user + password: password diff --git a/internal/testing/loading.go b/internal/testing/loading.go index c4005dc0..efdbaaed 100644 --- a/internal/testing/loading.go +++ b/internal/testing/loading.go @@ -12,6 +12,7 @@ import ( "github.com/gruntwork-io/go-commons/errors" configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" coordination "k8s.io/api/coordination/v1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" @@ -24,6 +25,7 @@ type Resources struct { Runs []*configv1alpha1.TerraformRun PullRequests []*configv1alpha1.TerraformPullRequest Leases []*coordination.Lease + Secrets []*corev1.Secret } type GenericResource struct { @@ -107,6 +109,13 @@ func LoadResources(client client.Client, path string) { panic(err) } } + for _, r := range resources.Secrets { + deepCopy := r.DeepCopy() + err := client.Create(context.TODO(), deepCopy) + if err != nil { + panic(err) + } + } } func parseResources(path string) (*Resources, error) { @@ -167,6 +176,10 @@ func parseResources(path string) (*Resources, error) { pr := &configv1alpha1.TerraformPullRequest{} err = yaml.Unmarshal([]byte(doc), &pr) resources.PullRequests = append(resources.PullRequests, pr) + case "Secret": + secret := &corev1.Secret{} + err = yaml.Unmarshal([]byte(doc), &secret) + resources.Secrets = append(resources.Secrets, secret) default: continue } diff --git a/internal/webhook/event/event_test.go b/internal/webhook/event/event_test.go index e23ca219..9e006e91 100644 --- a/internal/webhook/event/event_test.go +++ b/internal/webhook/event/event_test.go @@ -108,7 +108,6 @@ var PushEventMultiplePathChanges = event.PushEvent{ } var PullRequestOpenedEventNotAffected = event.PullRequestEvent{ - Provider: "github", URL: "https://github.com/example/repo", Revision: "feature/branch", Base: "main", @@ -118,7 +117,6 @@ var PullRequestOpenedEventNotAffected = event.PullRequestEvent{ } var PullRequestClosedEventNotAffected = event.PullRequestEvent{ - Provider: "github", URL: "https://github.com/example/repo", Revision: "feature/branch", Base: "main", @@ -128,7 +126,6 @@ var PullRequestClosedEventNotAffected = event.PullRequestEvent{ } var PullRequestOpenedEventSingleAffected = event.PullRequestEvent{ - Provider: "github", URL: "https://github.com/padok-team/burrito-examples", Revision: "feature/branch", Base: "main", @@ -138,7 +135,6 @@ var PullRequestOpenedEventSingleAffected = event.PullRequestEvent{ } var PullRequestClosedEventSingleAffected = event.PullRequestEvent{ - Provider: "github", URL: "https://github.com/padok-team/burrito-closed-single-pr", Revision: "feature/branch", Base: "main", @@ -148,7 +144,6 @@ var PullRequestClosedEventSingleAffected = event.PullRequestEvent{ } var PullRequestOpenedEventMultipleAffected = event.PullRequestEvent{ - Provider: "github", URL: "https://github.com/example/other-repo", Revision: "feature/branch", Base: "main", @@ -158,7 +153,6 @@ var PullRequestOpenedEventMultipleAffected = event.PullRequestEvent{ } var PullRequestClosedEventMultipleAffected = event.PullRequestEvent{ - Provider: "github", URL: "https://github.com/padok-team/burrito-closed-multi-pr", Revision: "feature/branch", Base: "main", diff --git a/internal/webhook/event/pullrequest.go b/internal/webhook/event/pullrequest.go index 70ddcc2f..f3db1d25 100644 --- a/internal/webhook/event/pullrequest.go +++ b/internal/webhook/event/pullrequest.go @@ -16,7 +16,6 @@ import ( ) type PullRequestEvent struct { - Provider string URL string Revision string Base string diff --git a/internal/webhook/github/provider.go b/internal/webhook/github/provider.go index 6b61d24f..e829cb98 100644 --- a/internal/webhook/github/provider.go +++ b/internal/webhook/github/provider.go @@ -72,7 +72,6 @@ func (g *Github) GetEvent(p interface{}) (event.Event, error) { return nil, err } e = &event.PullRequestEvent{ - Provider: "github", ID: strconv.FormatInt(payload.PullRequest.Number, 10), URL: utils.NormalizeUrl(payload.Repository.HTMLURL), Revision: payload.PullRequest.Head.Ref, diff --git a/internal/webhook/github/provider_test.go b/internal/webhook/github/provider_test.go index 42c0efc1..c9f7700a 100644 --- a/internal/webhook/github/provider_test.go +++ b/internal/webhook/github/provider_test.go @@ -20,20 +20,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGithub_IsFromProvider(t *testing.T) { - github := github.Github{} - - req, err := http.NewRequest("GET", "/", nil) - assert.NoError(t, err) - req.Header.Set("X-GitHub-Event", "test") - assert.True(t, github.IsFromProvider(req)) - - req, err = http.NewRequest("GET", "/", nil) - assert.NoError(t, err) - req.Header.Set("X-GitLab-Event", "test") - assert.False(t, github.IsFromProvider(req)) -} - func TestGithub_GetEvent_PushEvent(t *testing.T) { payloadFile, err := os.Open("testdata/github-push-main-event.json") if err != nil { @@ -58,7 +44,10 @@ func TestGithub_GetEvent_PushEvent(t *testing.T) { } secret := "test-secret" - github := github.Github{} + github := github.Github{ + Secret: secret, + } + err = github.Init() assert.NoError(t, err) req.Header.Set("X-GitHub-Event", "push") @@ -68,8 +57,9 @@ func TestGithub_GetEvent_PushEvent(t *testing.T) { assert.NoError(t, err) expectedMac := hex.EncodeToString(mac.Sum(nil)) req.Header.Set("X-Hub-Signature", fmt.Sprintf("sha1=%s", expectedMac)) - - evt, err := github.GetEvent(req) + parsed, ok := github.ParseFromProvider(req) + assert.True(t, ok) + evt, err := github.GetEvent(parsed) assert.NoError(t, err) assert.IsType(t, &event.PushEvent{}, evt) @@ -105,7 +95,10 @@ func TestGithub_GetEvent_PullRequestEvent(t *testing.T) { } secret := "test-secret" - github := github.Github{} + github := github.Github{ + Secret: secret, + } + err = github.Init() assert.NoError(t, err) req.Header.Set("X-GitHub-Event", "pull_request") @@ -116,13 +109,14 @@ func TestGithub_GetEvent_PullRequestEvent(t *testing.T) { expectedMac := hex.EncodeToString(mac.Sum(nil)) req.Header.Set("X-Hub-Signature", fmt.Sprintf("sha1=%s", expectedMac)) - evt, err := github.GetEvent(req) + parsed, ok := github.ParseFromProvider(req) + assert.True(t, ok) + evt, err := github.GetEvent(parsed) assert.NoError(t, err) assert.IsType(t, &event.PullRequestEvent{}, evt) pullRequestEvt := evt.(*event.PullRequestEvent) assert.Equal(t, "20", pullRequestEvt.ID) - assert.Equal(t, "github", pullRequestEvt.Provider) assert.Equal(t, "https://github.com/padok-team/burrito-examples", pullRequestEvt.URL) assert.Equal(t, "demo", pullRequestEvt.Revision) assert.Equal(t, "main", pullRequestEvt.Base) diff --git a/internal/webhook/gitlab/provider.go b/internal/webhook/gitlab/provider.go index 684b2ab4..8dc407d6 100644 --- a/internal/webhook/gitlab/provider.go +++ b/internal/webhook/gitlab/provider.go @@ -66,7 +66,6 @@ func (g *Gitlab) GetEvent(p interface{}) (event.Event, error) { case gitlab.MergeRequestEventPayload: log.Infof("parsing Gitlab merge request event payload") e = &event.PullRequestEvent{ - Provider: "gitlab", ID: strconv.Itoa(int(payload.ObjectAttributes.IID)), URL: utils.NormalizeUrl(payload.Project.WebURL), Revision: payload.ObjectAttributes.SourceBranch, diff --git a/internal/webhook/gitlab/provider_test.go b/internal/webhook/gitlab/provider_test.go index f4c9de3e..9b36284d 100644 --- a/internal/webhook/gitlab/provider_test.go +++ b/internal/webhook/gitlab/provider_test.go @@ -16,20 +16,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGilab_IsFromProvider(t *testing.T) { - gitlab := gitlab.Gitlab{} - - req, err := http.NewRequest("GET", "/", nil) - assert.NoError(t, err) - req.Header.Set("X-GitHub-Event", "test") - assert.False(t, gitlab.IsFromProvider(req)) - - req, err = http.NewRequest("GET", "/", nil) - assert.NoError(t, err) - req.Header.Set("X-GitLab-Event", "test") - assert.True(t, gitlab.IsFromProvider(req)) -} - func TestGitlab_GetEvent_PushEvent(t *testing.T) { payloadFile, err := os.Open("testdata/gitlab-push-main-event.json") if err != nil { @@ -54,14 +40,18 @@ func TestGitlab_GetEvent_PushEvent(t *testing.T) { } secret := "test-secret" - gitlab := gitlab.Gitlab{} + gitlab := gitlab.Gitlab{ + Secret: secret, + } err = gitlab.Init() assert.NoError(t, err) req.Header.Set("X-GitLab-Event", "Push Hook") req.Header.Set("X-Gitlab-Token", secret) - evt, err := gitlab.GetEvent(req) + parsed, ok := gitlab.ParseFromProvider(req) + assert.True(t, ok) + evt, err := gitlab.GetEvent(parsed) assert.NoError(t, err) assert.IsType(t, &event.PushEvent{}, evt) @@ -76,7 +66,9 @@ func TestGitlab_GetEvent_PushEvent(t *testing.T) { func TestGitlab_GetEvent_MergeRequestEvent(t *testing.T) { // Test GitLab initialization secret := "test-secret" - gitlab := gitlab.Gitlab{} + gitlab := gitlab.Gitlab{ + Secret: secret, + } err := gitlab.Init() assert.NoError(t, err) @@ -111,13 +103,14 @@ func TestGitlab_GetEvent_MergeRequestEvent(t *testing.T) { req.Header.Set("X-GitLab-Event", "Merge Request Hook") req.Header.Set("X-Gitlab-Token", secret) - evt, err := gitlab.GetEvent(req) + parsed, ok := gitlab.ParseFromProvider(req) + assert.True(t, ok) + evt, err := gitlab.GetEvent(parsed) assert.NoError(t, err) assert.IsType(t, &event.PullRequestEvent{}, evt) pullRequestEvt := evt.(*event.PullRequestEvent) assert.Equal(t, "1", pullRequestEvt.ID) - assert.Equal(t, "gitlab", pullRequestEvt.Provider) assert.Equal(t, "https://example.com/gitlabhq/gitlab-test", pullRequestEvt.URL) assert.Equal(t, "demo", pullRequestEvt.Revision) assert.Equal(t, "main", pullRequestEvt.Base)