Skip to content
This repository was archived by the owner on Oct 4, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions pkg/controller/gitsource/gitsource_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gitsource
import (
"context"
"github.com/redhat-developer/devconsole-api/pkg/apis/devconsole/v1alpha1"
"github.com/redhat-developer/devconsole-git/pkg/git"
"github.com/redhat-developer/devconsole-git/pkg/git/connection"
gslog "github.com/redhat-developer/devconsole-git/pkg/log"
"k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -81,7 +82,7 @@ func (r *ReconcileGitSource) Reconcile(request reconcile.Request) (reconcile.Res
}
gitSourceLogger := gslog.LogWithGSValues(reqLogger, gitSource)

isDirty := updateStatus(gitSourceLogger, gitSource)
isDirty := updateStatus(gitSourceLogger, r.client, request.Namespace, gitSource)

if isDirty {
err = r.client.Update(context.TODO(), gitSource)
Expand All @@ -100,7 +101,7 @@ func (r *ReconcileGitSource) Reconcile(request reconcile.Request) (reconcile.Res
return reconcile.Result{}, nil
}

func updateStatus(log *gslog.GitSourceLogger, gitSource *v1alpha1.GitSource) (isDirty bool) {
func updateStatus(log *gslog.GitSourceLogger, client client.Client, namespace string, gitSource *v1alpha1.GitSource) (isDirty bool) {

if gitSource.Status.Connection.State != "" {
return false
Expand All @@ -109,15 +110,24 @@ func updateStatus(log *gslog.GitSourceLogger, gitSource *v1alpha1.GitSource) (is
gitSource.Status.State = v1alpha1.Initializing
}

gitSource.Status.Connection = getConnectionStatus(log, gitSource)
gitSource.Status.Connection = getConnectionStatus(log, client, namespace, gitSource)
return true
}

func getConnectionStatus(log *gslog.GitSourceLogger, gitSource *v1alpha1.GitSource) v1alpha1.Connection {
func getConnectionStatus(log *gslog.GitSourceLogger, client client.Client, namespace string, gitSource *v1alpha1.GitSource) v1alpha1.Connection {
if gitSource.Spec.SecretRef == nil {
if validationError := connection.ValidateGitSource(log, gitSource); validationError != nil {
return NewFailedConnection(validationError)
}
return NewConnection("", "", v1alpha1.OK)
}
secret, err := git.NewGitSecret(client, namespace, gitSource)
if err != nil {
return NewConnection(err.Error(), v1alpha1.BadCredentials, v1alpha1.Failed)
}
validationError := connection.ValidateGitSourceWithSecret(log, gitSource, secret)
if validationError != nil {
return NewFailedConnection(validationError)
}
return NewConnection("", "", v1alpha1.OK)
}
Expand Down
128 changes: 127 additions & 1 deletion pkg/controller/gitsource/gitsource_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package gitsource

import (
"context"
"fmt"
"github.com/redhat-developer/devconsole-api/pkg/apis/devconsole/v1alpha1"
"github.com/redhat-developer/devconsole-git/pkg/git/repository"
"github.com/redhat-developer/devconsole-git/pkg/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/h2non/gock.v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
Expand Down Expand Up @@ -73,6 +76,129 @@ func TestReconcileGitSourceConnectionSkip(t *testing.T) {
assertGitSource(t, client, "", v1alpha1.OK, v1alpha1.ConnectionInternalFailure)
}

func TestValidateGitHubInvalidSecret(t *testing.T) {
// given
defer gock.OffAll()
gock.New("https://api.github.com").
Get("/user").
Reply(401)

secret := test.NewSecret(corev1.SecretTypeOpaque, map[string][]byte{"password": []byte("some-token")})
gs := test.NewGitSource(test.WithURL(repoGitHubURL))
gs.Spec.SecretRef = &v1alpha1.SecretRef{Name: test.SecretName}
reconciler, request, client := PrepareClient(test.GitSourceName,
test.RegisterGvkObject(v1alpha1.SchemeGroupVersion, gs),
test.RegisterGvkObject(corev1.SchemeGroupVersion, secret))

//when
_, err := reconciler.Reconcile(request)

// then
require.NoError(t, err)
assertGitSource(t, client, v1alpha1.Initializing, v1alpha1.Failed, v1alpha1.BadCredentials)
}

func TestValidateGitLabSecretAndUnavailableRepo(t *testing.T) {
// given
defer gock.OffAll()
gock.New("https://gitlab.com/").
Get("/api/v4/user").
Reply(200).
BodyString("{}")
gock.New("https://gitlab.com/").
Get(fmt.Sprintf("/api/v4/projects/%s", repoIdentifier)).
Reply(404)

secret := test.NewSecret(corev1.SecretTypeOpaque, map[string][]byte{"password": []byte("some-token")})
gs := test.NewGitSource(test.WithURL("https://gitlab.com/" + repoIdentifier))
gs.Spec.SecretRef = &v1alpha1.SecretRef{Name: test.SecretName}
reconciler, request, client := PrepareClient(test.GitSourceName,
test.RegisterGvkObject(v1alpha1.SchemeGroupVersion, gs),
test.RegisterGvkObject(corev1.SchemeGroupVersion, secret))

//when
_, err := reconciler.Reconcile(request)

// then
require.NoError(t, err)
assertGitSource(t, client, v1alpha1.Initializing, v1alpha1.Failed, v1alpha1.RepoNotReachable)
}

func TestValidateGitHubSecretAndAvailableRepoWithWrongBranch(t *testing.T) {
// given
defer gock.OffAll()
gock.New("https://api.github.com").
Get("/user").
Reply(200)
gock.New("https://api.github.com").
Get(fmt.Sprintf("repos/%s", repoIdentifier)).
Reply(200)
gock.New("https://api.github.com").
Get(fmt.Sprintf("repos/%s/branches/any", repoIdentifier)).
Reply(404)

secret := test.NewSecret(corev1.SecretTypeOpaque, map[string][]byte{
"username": []byte("username"),
"password": []byte("password")})
gs := test.NewGitSource(test.WithURL(repoGitHubURL), test.WithRef("any"))
gs.Spec.SecretRef = &v1alpha1.SecretRef{Name: test.SecretName}
reconciler, request, client := PrepareClient(test.GitSourceName,
test.RegisterGvkObject(v1alpha1.SchemeGroupVersion, gs),
test.RegisterGvkObject(corev1.SchemeGroupVersion, secret))

//when
_, err := reconciler.Reconcile(request)

// then
require.NoError(t, err)
assertGitSource(t, client, v1alpha1.Initializing, v1alpha1.Failed, v1alpha1.BranchNotFound)
}

func TestValidateBitBucketWithCorrectData(t *testing.T) {
// given
defer gock.OffAll()
gock.New("https://api.bitbucket.org/").
Get("/2.0/.*").
Times(3).
Reply(200)

secret := test.NewSecret(corev1.SecretTypeOpaque, map[string][]byte{"password": []byte("some-token")})
gs := test.NewGitSource(test.WithURL("https://bitbucket.org/" + repoIdentifier))
gs.Spec.SecretRef = &v1alpha1.SecretRef{Name: test.SecretName}
reconciler, request, client := PrepareClient(test.GitSourceName,
test.RegisterGvkObject(v1alpha1.SchemeGroupVersion, gs),
test.RegisterGvkObject(corev1.SchemeGroupVersion, secret))

// when
_, err := reconciler.Reconcile(request)

// then
require.NoError(t, err)
assertGitSource(t, client, v1alpha1.Initializing, v1alpha1.OK, "")
}

func TestValidateGenericGit(t *testing.T) {
//given
reset := test.RunBasicSshServer(t, "super-secret")
defer reset()

dummyRepo := test.NewDummyGitRepo(t, repository.Master)
dummyRepo.Commit("main.go")
secret := test.NewSecret(corev1.SecretTypeOpaque, map[string][]byte{"password": []byte("super-secret")})
gs := test.NewGitSource(test.WithURL("ssh://git@localhost:2222" + dummyRepo.Path))
gs.Spec.SecretRef = &v1alpha1.SecretRef{Name: test.SecretName}
reconciler, request, client := PrepareClient(test.GitSourceName,
test.RegisterGvkObject(v1alpha1.SchemeGroupVersion, gs),
test.RegisterGvkObject(corev1.SchemeGroupVersion, secret))

// when
_, err := reconciler.Reconcile(request)

// then
require.NoError(t, err)
assertGitSource(t, client, v1alpha1.Initializing, v1alpha1.OK, "")
}

func PrepareClient(name string, gvkObjects ...test.GvkObject) (*ReconcileGitSource, reconcile.Request, client.Client) {
// Create a fake client to mock API calls.
cl, s := test.PrepareClient(gvkObjects...)
Expand All @@ -93,7 +219,7 @@ func assertGitSource(t *testing.T, client client.Client, gsState v1alpha1.State,

require.NotNil(t, gitSource.Status.Connection)
if reason != "" {
assert.Contains(t, gitSource.Status.Connection.Reason, reason)
assert.Equal(t, gitSource.Status.Connection.Reason, reason)
assert.NotEmpty(t, gitSource.Status.Connection.Error)
} else {
assert.Empty(t, gitSource.Status.Connection.Error)
Expand Down