gitrepo: Add support for specifying proxy per `GitRepository`
Add `.spec.proxySecretRef.name` to the `GitRepository` API to allow referencing a secret containing the proxy settings to be used for all remote Git operations for the particular `GitRepository` object. It takes precedence over any proxy configured through enviornment variables. Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
This commit is contained in:
parent
6901379b73
commit
944f4cfa10
11
Makefile
11
Makefile
|
|
@ -63,11 +63,11 @@ endif
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build: check-deps ## Build manager binary
|
build: ## Build manager binary
|
||||||
go build $(GO_STATIC_FLAGS) -o $(BUILD_DIR)/bin/manager main.go
|
go build $(GO_STATIC_FLAGS) -o $(BUILD_DIR)/bin/manager main.go
|
||||||
|
|
||||||
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
|
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
|
||||||
test: install-envtest test-api check-deps ## Run all tests
|
test: install-envtest test-api ## Run all tests
|
||||||
HTTPS_PROXY="" HTTP_PROXY="" \
|
HTTPS_PROXY="" HTTP_PROXY="" \
|
||||||
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
|
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
|
||||||
GIT_CONFIG_GLOBAL=/dev/null \
|
GIT_CONFIG_GLOBAL=/dev/null \
|
||||||
|
|
@ -76,7 +76,7 @@ test: install-envtest test-api check-deps ## Run all tests
|
||||||
$(GO_TEST_ARGS) \
|
$(GO_TEST_ARGS) \
|
||||||
-coverprofile cover.out
|
-coverprofile cover.out
|
||||||
|
|
||||||
test-ctrl: install-envtest test-api check-deps ## Run controller tests
|
test-ctrl: install-envtest test-api ## Run controller tests
|
||||||
HTTPS_PROXY="" HTTP_PROXY="" \
|
HTTPS_PROXY="" HTTP_PROXY="" \
|
||||||
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
|
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
|
||||||
GIT_CONFIG_GLOBAL=/dev/null \
|
GIT_CONFIG_GLOBAL=/dev/null \
|
||||||
|
|
@ -85,11 +85,6 @@ test-ctrl: install-envtest test-api check-deps ## Run controller tests
|
||||||
-v ./internal/controller \
|
-v ./internal/controller \
|
||||||
-coverprofile cover.out
|
-coverprofile cover.out
|
||||||
|
|
||||||
check-deps:
|
|
||||||
ifeq ($(shell uname -s),Darwin)
|
|
||||||
if ! command -v pkg-config &> /dev/null; then echo "pkg-config is required"; exit 1; fi
|
|
||||||
endif
|
|
||||||
|
|
||||||
test-api: ## Run api tests
|
test-api: ## Run api tests
|
||||||
cd api; go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
|
cd api; go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,11 @@ type GitRepositorySpec struct {
|
||||||
// +optional
|
// +optional
|
||||||
Verification *GitRepositoryVerification `json:"verify,omitempty"`
|
Verification *GitRepositoryVerification `json:"verify,omitempty"`
|
||||||
|
|
||||||
|
// ProxySecretRef specifies the Secret containing the proxy configuration
|
||||||
|
// to use while communicating with the Git server.
|
||||||
|
// +optional
|
||||||
|
ProxySecretRef *meta.LocalObjectReference `json:"proxySecretRef,omitempty"`
|
||||||
|
|
||||||
// Ignore overrides the set of excluded patterns in the .sourceignore format
|
// Ignore overrides the set of excluded patterns in the .sourceignore format
|
||||||
// (which is the same as .gitignore). If not provided, a default will be used,
|
// (which is the same as .gitignore). If not provided, a default will be used,
|
||||||
// consult the documentation for your version to find out what those are.
|
// consult the documentation for your version to find out what those are.
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,11 @@ func (in *GitRepositorySpec) DeepCopyInto(out *GitRepositorySpec) {
|
||||||
*out = new(GitRepositoryVerification)
|
*out = new(GitRepositoryVerification)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.ProxySecretRef != nil {
|
||||||
|
in, out := &in.ProxySecretRef, &out.ProxySecretRef
|
||||||
|
*out = new(meta.LocalObjectReference)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
if in.Ignore != nil {
|
if in.Ignore != nil {
|
||||||
in, out := &in.Ignore, &out.Ignore
|
in, out := &in.Ignore, &out.Ignore
|
||||||
*out = new(string)
|
*out = new(string)
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,16 @@ spec:
|
||||||
description: Interval at which to check the GitRepository for updates.
|
description: Interval at which to check the GitRepository for updates.
|
||||||
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
|
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
|
||||||
type: string
|
type: string
|
||||||
|
proxySecretRef:
|
||||||
|
description: ProxySecretRef specifies the Secret containing the proxy
|
||||||
|
configuration to use while communicating with the Git server.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name of the referent.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
recurseSubmodules:
|
recurseSubmodules:
|
||||||
description: RecurseSubmodules enables the initialization of all submodules
|
description: RecurseSubmodules enables the initialization of all submodules
|
||||||
within the GitRepository as cloned from the URL, using their default
|
within the GitRepository as cloned from the URL, using their default
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,21 @@ signature(s).</p>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
<code>proxySecretRef</code><br>
|
||||||
|
<em>
|
||||||
|
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
|
||||||
|
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>ProxySecretRef specifies the Secret containing the proxy configuration
|
||||||
|
to use while communicating with the Git server.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
<code>ignore</code><br>
|
<code>ignore</code><br>
|
||||||
<em>
|
<em>
|
||||||
string
|
string
|
||||||
|
|
@ -593,6 +608,21 @@ signature(s).</p>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
<code>proxySecretRef</code><br>
|
||||||
|
<em>
|
||||||
|
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
|
||||||
|
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>ProxySecretRef specifies the Secret containing the proxy configuration
|
||||||
|
to use while communicating with the Git server.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
<code>ignore</code><br>
|
<code>ignore</code><br>
|
||||||
<em>
|
<em>
|
||||||
string
|
string
|
||||||
|
|
|
||||||
|
|
@ -439,6 +439,55 @@ GitRepository, and changes to the resource or in the Git repository will not
|
||||||
result in a new Artifact. When the field is set to `false` or removed, it will
|
result in a new Artifact. When the field is set to `false` or removed, it will
|
||||||
resume.
|
resume.
|
||||||
|
|
||||||
|
### Proxy secret reference
|
||||||
|
|
||||||
|
`.spec.proxySecretRef.name` is an optional field used to specify the name of a
|
||||||
|
Secret that contains the proxy settings for the object. These settings are used
|
||||||
|
for all remote Git operations related to the GitRepository.
|
||||||
|
The Secret can contain three keys:
|
||||||
|
|
||||||
|
- `address`, to specify the address of the proxy server. This is a required key.
|
||||||
|
- `username`, to specify the username to use if the proxy server is protected by
|
||||||
|
basic authentication. This is an optional key.
|
||||||
|
- `password`, to specify the password to use if the proxy server is protected by
|
||||||
|
basic authentication. This is an optional key.
|
||||||
|
|
||||||
|
The proxy server must be either HTTP/S or SOCKS5. You can use a SOCKS5 proxy
|
||||||
|
with a HTTP/S Git repository url.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: http-proxy
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
address: http://proxy.com
|
||||||
|
username: mandalorian
|
||||||
|
password: grogu
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ssh-proxy
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
address: socks5://proxy.com
|
||||||
|
username: mandalorian
|
||||||
|
password: grogu
|
||||||
|
```
|
||||||
|
|
||||||
|
Proxying can also be configured in the source-controller Deployment directly by
|
||||||
|
using the standard environment variables such as `HTTPS_PROXY`, `ALL_PROXY`, etc.
|
||||||
|
|
||||||
|
`.spec.proxySecretRef.name` takes precedence over all environment variables.
|
||||||
|
|
||||||
### Recurse submodules
|
### Recurse submodules
|
||||||
|
|
||||||
`.spec.recurseSubmodules` is an optional field to enable the initialization of
|
`.spec.recurseSubmodules` is an optional field to enable the initialization of
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
|
|
||||||
securejoin "github.com/cyphar/filepath-securejoin"
|
securejoin "github.com/cyphar/filepath-securejoin"
|
||||||
"github.com/fluxcd/pkg/runtime/logger"
|
"github.com/fluxcd/pkg/runtime/logger"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
|
@ -473,24 +474,19 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
conditions.Delete(obj, sourcev1.SourceVerifiedCondition)
|
conditions.Delete(obj, sourcev1.SourceVerifiedCondition)
|
||||||
}
|
}
|
||||||
|
|
||||||
var authData map[string][]byte
|
var proxyOpts *transport.ProxyOptions
|
||||||
if obj.Spec.SecretRef != nil {
|
if obj.Spec.ProxySecretRef != nil {
|
||||||
// Attempt to retrieve secret
|
var err error
|
||||||
name := types.NamespacedName{
|
proxyOpts, err = r.getProxyOpts(ctx, obj.Spec.ProxySecretRef.Name, obj.GetNamespace())
|
||||||
Namespace: obj.GetNamespace(),
|
if err != nil {
|
||||||
Name: obj.Spec.SecretRef.Name,
|
|
||||||
}
|
|
||||||
var secret corev1.Secret
|
|
||||||
if err := r.Client.Get(ctx, name, &secret); err != nil {
|
|
||||||
e := serror.NewGeneric(
|
e := serror.NewGeneric(
|
||||||
fmt.Errorf("failed to get secret '%s': %w", name.String(), err),
|
fmt.Errorf("failed to configure proxy options: %w", err),
|
||||||
sourcev1.AuthenticationFailedReason,
|
sourcev1.AuthenticationFailedReason,
|
||||||
)
|
)
|
||||||
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
|
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
|
||||||
// Return error as the world as observed may change
|
// Return error as the world as observed may change
|
||||||
return sreconcile.ResultEmpty, e
|
return sreconcile.ResultEmpty, e
|
||||||
}
|
}
|
||||||
authData = secret.Data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := url.Parse(obj.Spec.URL)
|
u, err := url.Parse(obj.Spec.URL)
|
||||||
|
|
@ -503,14 +499,14 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
return sreconcile.ResultEmpty, e
|
return sreconcile.ResultEmpty, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure authentication strategy to access the source
|
authOpts, err := r.getAuthOpts(ctx, obj, *u)
|
||||||
authOpts, err := git.NewAuthOptions(*u, authData)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e := serror.NewGeneric(
|
e := serror.NewGeneric(
|
||||||
fmt.Errorf("failed to configure authentication options: %w", err),
|
fmt.Errorf("failed to configure authentication options: %w", err),
|
||||||
sourcev1.AuthenticationFailedReason,
|
sourcev1.AuthenticationFailedReason,
|
||||||
)
|
)
|
||||||
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
|
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
|
||||||
|
// Return error as the world as observed may change
|
||||||
return sreconcile.ResultEmpty, e
|
return sreconcile.ResultEmpty, e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -536,7 +532,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
// Persist the ArtifactSet.
|
// Persist the ArtifactSet.
|
||||||
*includes = *artifacts
|
*includes = *artifacts
|
||||||
|
|
||||||
c, err := r.gitCheckout(ctx, obj, authOpts, dir, true)
|
c, err := r.gitCheckout(ctx, obj, authOpts, proxyOpts, dir, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sreconcile.ResultEmpty, err
|
return sreconcile.ResultEmpty, err
|
||||||
}
|
}
|
||||||
|
|
@ -578,7 +574,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
|
|
||||||
// If we can't skip the reconciliation, checkout again without any
|
// If we can't skip the reconciliation, checkout again without any
|
||||||
// optimization.
|
// optimization.
|
||||||
c, err := r.gitCheckout(ctx, obj, authOpts, dir, false)
|
c, err := r.gitCheckout(ctx, obj, authOpts, proxyOpts, dir, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sreconcile.ResultEmpty, err
|
return sreconcile.ResultEmpty, err
|
||||||
}
|
}
|
||||||
|
|
@ -606,6 +602,60 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
|
||||||
return sreconcile.ResultSuccess, nil
|
return sreconcile.ResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getProxyOpts fetches the secret containing the proxy settings, constructs a
|
||||||
|
// transport.ProxyOptions object using those settings and then returns it.
|
||||||
|
func (r *GitRepositoryReconciler) getProxyOpts(ctx context.Context, proxySecretName,
|
||||||
|
proxySecretNamespace string) (*transport.ProxyOptions, error) {
|
||||||
|
proxyData, err := r.getSecretData(ctx, proxySecretName, proxySecretNamespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get proxy secret '%s/%s': %w", proxySecretNamespace, proxySecretName, err)
|
||||||
|
}
|
||||||
|
address, ok := proxyData["address"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("invalid proxy secret '%s/%s': key 'address' is missing", proxySecretNamespace, proxySecretName)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyOpts := &transport.ProxyOptions{
|
||||||
|
URL: string(address),
|
||||||
|
Username: string(proxyData["username"]),
|
||||||
|
Password: string(proxyData["password"]),
|
||||||
|
}
|
||||||
|
return proxyOpts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getAuthOpts fetches the secret containing the auth options (if specified),
|
||||||
|
// constructs a git.AuthOptions object using those options along with the provided
|
||||||
|
// URL and returns it.
|
||||||
|
func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1.GitRepository, u url.URL) (*git.AuthOptions, error) {
|
||||||
|
var authData map[string][]byte
|
||||||
|
if obj.Spec.SecretRef != nil {
|
||||||
|
var err error
|
||||||
|
authData, err = r.getSecretData(ctx, obj.Spec.SecretRef.Name, obj.GetNamespace())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get secret '%s/%s': %w", obj.GetNamespace(), obj.Spec.SecretRef.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure authentication strategy to access the source
|
||||||
|
authOpts, err := git.NewAuthOptions(u, authData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return authOpts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GitRepositoryReconciler) getSecretData(ctx context.Context, name, namespace string) (map[string][]byte, error) {
|
||||||
|
key := types.NamespacedName{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
var secret corev1.Secret
|
||||||
|
if err := r.Client.Get(ctx, key, &secret); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return secret.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
// reconcileArtifact archives a new Artifact to the Storage, if the current
|
// reconcileArtifact archives a new Artifact to the Storage, if the current
|
||||||
// (Status) data on the object does not match the given.
|
// (Status) data on the object does not match the given.
|
||||||
//
|
//
|
||||||
|
|
@ -776,8 +826,8 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patc
|
||||||
|
|
||||||
// gitCheckout builds checkout options with the given configurations and
|
// gitCheckout builds checkout options with the given configurations and
|
||||||
// performs a git checkout.
|
// performs a git checkout.
|
||||||
func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
|
func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context, obj *sourcev1.GitRepository,
|
||||||
obj *sourcev1.GitRepository, authOpts *git.AuthOptions, dir string, optimized bool) (*git.Commit, error) {
|
authOpts *git.AuthOptions, proxyOpts *transport.ProxyOptions, dir string, optimized bool) (*git.Commit, error) {
|
||||||
// Configure checkout strategy.
|
// Configure checkout strategy.
|
||||||
cloneOpts := repository.CloneConfig{
|
cloneOpts := repository.CloneConfig{
|
||||||
RecurseSubmodules: obj.Spec.RecurseSubmodules,
|
RecurseSubmodules: obj.Spec.RecurseSubmodules,
|
||||||
|
|
@ -807,6 +857,9 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context,
|
||||||
if authOpts.Transport == git.HTTP {
|
if authOpts.Transport == git.HTTP {
|
||||||
clientOpts = append(clientOpts, gogit.WithInsecureCredentialsOverHTTP())
|
clientOpts = append(clientOpts, gogit.WithInsecureCredentialsOverHTTP())
|
||||||
}
|
}
|
||||||
|
if proxyOpts != nil {
|
||||||
|
clientOpts = append(clientOpts, gogit.WithProxy(*proxyOpts))
|
||||||
|
}
|
||||||
|
|
||||||
gitReader, err := gogit.NewClient(dir, authOpts, clientOpts...)
|
gitReader, err := gogit.NewClient(dir, authOpts, clientOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"github.com/go-git/go-git/v5/config"
|
"github.com/go-git/go-git/v5/config"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/go-git/go-git/v5/plumbing/object"
|
"github.com/go-git/go-git/v5/plumbing/object"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||||
"github.com/go-git/go-git/v5/storage/memory"
|
"github.com/go-git/go-git/v5/storage/memory"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
sshtestdata "golang.org/x/crypto/ssh/testdata"
|
sshtestdata "golang.org/x/crypto/ssh/testdata"
|
||||||
|
|
@ -1619,6 +1620,78 @@ func TestGitRepositoryReconciler_verifyCommitSignature(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGitRepositoryReconciler_getProxyOpts(t *testing.T) {
|
||||||
|
invalidProxy := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "invalid-proxy",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"url": []byte("https://example.com"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
validProxy := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "valid-proxy",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"address": []byte("https://example.com"),
|
||||||
|
"username": []byte("user"),
|
||||||
|
"password": []byte("pass"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
clientBuilder := fakeclient.NewClientBuilder().
|
||||||
|
WithScheme(testEnv.GetScheme()).
|
||||||
|
WithObjects(invalidProxy, validProxy)
|
||||||
|
|
||||||
|
r := &GitRepositoryReconciler{
|
||||||
|
Client: clientBuilder.Build(),
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
secret string
|
||||||
|
err string
|
||||||
|
proxyOpts *transport.ProxyOptions
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "non-existent secret",
|
||||||
|
secret: "non-existent",
|
||||||
|
err: "failed to get proxy secret 'default/non-existent': ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid proxy secret",
|
||||||
|
secret: "invalid-proxy",
|
||||||
|
err: "invalid proxy secret 'default/invalid-proxy': key 'address' is missing",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid proxy secret",
|
||||||
|
secret: "valid-proxy",
|
||||||
|
proxyOpts: &transport.ProxyOptions{
|
||||||
|
URL: "https://example.com",
|
||||||
|
Username: "user",
|
||||||
|
Password: "pass",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
opts, err := r.getProxyOpts(context.TODO(), tt.secret, "default")
|
||||||
|
if opts != nil {
|
||||||
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
|
g.Expect(opts).To(Equal(tt.proxyOpts))
|
||||||
|
} else {
|
||||||
|
g.Expect(err).To(HaveOccurred())
|
||||||
|
g.Expect(err.Error()).To(ContainSubstring(tt.err))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGitRepositoryReconciler_ConditionsUpdate(t *testing.T) {
|
func TestGitRepositoryReconciler_ConditionsUpdate(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue