Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
for BitBucketServer by allowing to pass a CM holding trusted certificates. Refactors implementation for GitLab.

Signed-off-by: asjervanasten <asjer94@live.com>
  • Loading branch information
appiepollo14 committed Jul 9, 2024
1 parent eca1f21 commit bfd485b
Show file tree
Hide file tree
Showing 23 changed files with 2,231 additions and 1,023 deletions.
41 changes: 38 additions & 3 deletions applicationset/generators/pull_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,19 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
}
if generatorConfig.GitLab != nil {
providerConfig := generatorConfig.GitLab
var caCerts []byte
var prErr error
if providerConfig.CAConfigMapKeyRef != nil {
caCerts, prErr = g.getConfigMapData(ctx, providerConfig.CAConfigMapKeyRef, applicationSetInfo.Namespace)
if prErr != nil {
return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", prErr)
}
}
token, err := g.getSecretRef(ctx, providerConfig.TokenRef, applicationSetInfo.Namespace)
if err != nil {
return nil, fmt.Errorf("error fetching Secret token: %w", err)
}
return pullrequest.NewGitLabService(ctx, token, providerConfig.API, providerConfig.Project, providerConfig.Labels, providerConfig.PullRequestState, g.scmRootCAPath, providerConfig.Insecure)
return pullrequest.NewGitLabService(ctx, token, providerConfig.API, providerConfig.Project, providerConfig.Labels, providerConfig.PullRequestState, g.scmRootCAPath, providerConfig.Insecure, caCerts)
}
if generatorConfig.Gitea != nil {
providerConfig := generatorConfig.Gitea
Expand All @@ -145,14 +153,22 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
}
if generatorConfig.BitbucketServer != nil {
providerConfig := generatorConfig.BitbucketServer
var caCerts []byte
var prErr error
if providerConfig.CAConfigMapKeyRef != nil {
caCerts, prErr = g.getConfigMapData(ctx, providerConfig.CAConfigMapKeyRef, applicationSetInfo.Namespace)
if prErr != nil {
return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", prErr)
}
}
if providerConfig.BasicAuth != nil {
password, err := g.getSecretRef(ctx, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace)
if err != nil {
return nil, fmt.Errorf("error fetching Secret token: %w", err)
}
return pullrequest.NewBitbucketServiceBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.Repo)
return pullrequest.NewBitbucketServiceBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts)
} else {
return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo)
return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts)
}
}
if generatorConfig.Bitbucket != nil {
Expand Down Expand Up @@ -225,3 +241,22 @@ func (g *PullRequestGenerator) getSecretRef(ctx context.Context, ref *argoprojio
}
return string(tokenBytes), nil
}

func (g *PullRequestGenerator) getConfigMapData(ctx context.Context, ref *argoprojiov1alpha1.ConfigMapKeyRef, namespace string) ([]byte, error) {
if ref == nil {
return nil, nil
}

configMap := &corev1.ConfigMap{}
err := g.client.Get(ctx, client.ObjectKey{Name: ref.ConfigMapName, Namespace: namespace}, configMap)
if err != nil {
return nil, err
}

data, ok := configMap.Data[ref.Key]
if !ok {
return nil, fmt.Errorf("key %s not found in ConfigMap %s", ref.Key, configMap.Name)
}

return []byte(data), nil
}
67 changes: 67 additions & 0 deletions applicationset/generators/pull_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,73 @@ func TestPullRequestGetSecretRef(t *testing.T) {
}
}

func TestPullRequestGetConfigMapData(t *testing.T) {
configMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "test-configmap", Namespace: "test"},
Data: map[string]string{
"my-data": "configmap-data",
},
}
gen := &PullRequestGenerator{client: fake.NewClientBuilder().WithObjects(configMap).Build()}
ctx := context.Background()

cases := []struct {
name, namespace, data string
ref *argoprojiov1alpha1.ConfigMapKeyRef
hasError bool
}{
{
name: "valid ref",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "my-data"},
namespace: "test",
data: "configmap-data",
hasError: false,
},
{
name: "nil ref",
ref: nil,
namespace: "test",
data: "",
hasError: false,
},
{
name: "wrong name",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "other", Key: "my-data"},
namespace: "test",
data: "",
hasError: true,
},
{
name: "wrong key",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "other-data"},
namespace: "test",
data: "",
hasError: true,
},
{
name: "wrong namespace",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "my-data"},
namespace: "other",
data: "",
hasError: true,
},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
data, err := gen.getConfigMapData(ctx, c.ref, c.namespace)
if c.hasError {
require.Error(t, err)
} else {
require.NoError(t, err)
}
if !c.hasError {
assert.Equal(t, c.data, string(data))
}
})
}
}

func TestAllowedSCMProviderPullRequest(t *testing.T) {
cases := []struct {
name string
Expand Down
43 changes: 39 additions & 4 deletions applicationset/generators/scm_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,20 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
return nil, fmt.Errorf("scm provider: %w", err)
}
} else if providerConfig.Gitlab != nil {
token, err := g.getSecretRef(ctx, providerConfig.Gitlab.TokenRef, applicationSetInfo.Namespace)
providerConfig := providerConfig.Gitlab
var caCerts []byte
var scmError error
if providerConfig.CAConfigMapKeyRef != nil {
caCerts, scmError = g.getConfigMapData(ctx, providerConfig.CAConfigMapKeyRef, applicationSetInfo.Namespace)
if scmError != nil {
return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", scmError)
}
}
token, err := g.getSecretRef(ctx, providerConfig.TokenRef, applicationSetInfo.Namespace)
if err != nil {
return nil, fmt.Errorf("error fetching Gitlab token: %w", err)
}
provider, err = scm_provider.NewGitlabProvider(ctx, providerConfig.Gitlab.Group, token, providerConfig.Gitlab.API, providerConfig.Gitlab.AllBranches, providerConfig.Gitlab.IncludeSubgroups, providerConfig.Gitlab.WillIncludeSharedProjects(), providerConfig.Gitlab.Insecure, g.scmRootCAPath, providerConfig.Gitlab.Topic)
provider, err = scm_provider.NewGitlabProvider(ctx, providerConfig.Group, token, providerConfig.API, providerConfig.AllBranches, providerConfig.IncludeSubgroups, providerConfig.WillIncludeSharedProjects(), providerConfig.Insecure, g.scmRootCAPath, providerConfig.Topic, caCerts)
if err != nil {
return nil, fmt.Errorf("error initializing Gitlab service: %w", err)
}
Expand All @@ -165,15 +174,22 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
}
} else if providerConfig.BitbucketServer != nil {
providerConfig := providerConfig.BitbucketServer
var caCerts []byte
var scmError error
if providerConfig.CAConfigMapKeyRef != nil {
caCerts, scmError = g.getConfigMapData(ctx, providerConfig.CAConfigMapKeyRef, applicationSetInfo.Namespace)
if scmError != nil {
return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", scmError)
}
}
if providerConfig.BasicAuth != nil {
password, err := g.getSecretRef(ctx, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace)
if err != nil {
return nil, fmt.Errorf("error fetching Secret token: %w", err)
}
provider, scmError = scm_provider.NewBitbucketServerProviderBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.AllBranches)
provider, scmError = scm_provider.NewBitbucketServerProviderBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts)
} else {
provider, scmError = scm_provider.NewBitbucketServerProviderNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.AllBranches)
provider, scmError = scm_provider.NewBitbucketServerProviderNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts)
}
if scmError != nil {
return nil, fmt.Errorf("error initializing Bitbucket Server service: %w", scmError)
Expand Down Expand Up @@ -270,6 +286,25 @@ func (g *SCMProviderGenerator) getSecretRef(ctx context.Context, ref *argoprojio
return string(tokenBytes), nil
}

func (g *SCMProviderGenerator) getConfigMapData(ctx context.Context, ref *argoprojiov1alpha1.ConfigMapKeyRef, namespace string) ([]byte, error) {
if ref == nil {
return nil, nil
}

configMap := &corev1.ConfigMap{}
err := g.client.Get(ctx, client.ObjectKey{Name: ref.ConfigMapName, Namespace: namespace}, configMap)
if err != nil {
return nil, err
}

data, ok := configMap.Data[ref.Key]
if !ok {
return nil, fmt.Errorf("key %s not found in ConfigMap %s", ref.Key, configMap.Name)
}

return []byte(data), nil
}

func (g *SCMProviderGenerator) githubProvider(ctx context.Context, github *argoprojiov1alpha1.SCMProviderGeneratorGithub, applicationSetInfo *argoprojiov1alpha1.ApplicationSet) (scm_provider.SCMProviderService, error) {
if github.AppSecretName != "" {
auth, err := g.GitHubApps.GetAuthSecret(ctx, github.AppSecretName)
Expand Down
68 changes: 68 additions & 0 deletions applicationset/generators/scm_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,74 @@ func TestSCMProviderGetSecretRef(t *testing.T) {
}
}

func TestSCMProviderGetConfigMapData(t *testing.T) {
configMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "test-configmap", Namespace: "test"},
Data: map[string]string{
"my-data": "configmap-data",
},
}
gen := &SCMProviderGenerator{client: fake.NewClientBuilder().WithObjects(configMap).Build()}
ctx := context.Background()

cases := []struct {
name, namespace, data string
ref *argoprojiov1alpha1.ConfigMapKeyRef
hasError bool
}{
{
name: "valid ref",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "my-data"},
namespace: "test",
data: "configmap-data",
hasError: false,
},
{
name: "nil ref",
ref: nil,
namespace: "test",
data: "",
hasError: false,
},
{
name: "wrong name",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "other", Key: "my-data"},
namespace: "test",
data: "",
hasError: true,
},
{
name: "wrong key",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "other-data"},
namespace: "test",
data: "",
hasError: true,
},
{
name: "wrong namespace",
ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "my-data"},
namespace: "other",
data: "",
hasError: true,
},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
data, err := gen.getConfigMapData(ctx, c.ref, c.namespace)
if c.hasError {
require.Error(t, err)
} else {
require.NoError(t, err)
}
if !c.hasError {
assert.Equal(t, c.data, string(data))
}
})
}
}


func TestSCMProviderGenerateParams(t *testing.T) {
cases := []struct {
name string
Expand Down
15 changes: 10 additions & 5 deletions applicationset/services/pull_request/bitbucket_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package pull_request
import (
"context"
"fmt"
"net/http"

bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
log "github.com/sirupsen/logrus"
Expand All @@ -20,7 +21,7 @@ type BitbucketService struct {

var _ PullRequestService = (*BitbucketService)(nil)

func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url, projectKey, repositorySlug string) (PullRequestService, error) {
func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) {
bitbucketConfig := bitbucketv1.NewConfiguration(url)
// Avoid the XSRF check
bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check")
Expand All @@ -30,15 +31,19 @@ func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url,
UserName: username,
Password: password,
})
return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug)
return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug, scmRootCAPath, insecure, caCerts)
}

func NewBitbucketServiceNoAuth(ctx context.Context, url, projectKey, repositorySlug string) (PullRequestService, error) {
return newBitbucketService(ctx, bitbucketv1.NewConfiguration(url), projectKey, repositorySlug)
func NewBitbucketServiceNoAuth(ctx context.Context, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) {
return newBitbucketService(ctx, bitbucketv1.NewConfiguration(url), projectKey, repositorySlug, scmRootCAPath, insecure, caCerts)
}

func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey, repositorySlug string) (PullRequestService, error) {
func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) {
bitbucketConfig.BasePath = utils.NormalizeBitbucketBasePath(bitbucketConfig.BasePath)
tlsConfig := utils.GetTlsConfig(scmRootCAPath, insecure, caCerts)
bitbucketConfig.HTTPClient = &http.Client{Transport: &http.Transport{
TLSClientConfig: tlsConfig,
}}
bitbucketClient := bitbucketv1.NewAPIClient(ctx, bitbucketConfig)

return &BitbucketService{
Expand Down
Loading

0 comments on commit bfd485b

Please sign in to comment.