Skip to content

Add support for non-OpenShift K8s to managed-gitops, testing via k3d #838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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
77 changes: 77 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Build and test the operator
on:
push:
branches:
- 'main'

pull_request:
branches:
- 'main'

jobs:


test-e2e:
name: Run end-to-end tests
runs-on: ubuntu-latest
strategy:
matrix:
k3s-version: [ v1.27.1 ]
steps:
# - name: Public IP
# id: ip
# uses: haythem/[email protected]

# - name: See IP Addresses
# run: |
# echo ${{ steps.ip.outputs.ipv4 }}
# echo ${{ steps.ip.outputs.ipv6 }}

- name: Install k3d
run: |
set -x
curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
sudo mkdir -p $HOME/.kube && sudo chown -R runner $HOME/.kube
k3d cluster create --servers 3 --image rancher/k3s:${{ matrix.k3s-version }}-k3s1
kubectl version
k3d version

- name: Checkout code
uses: actions/checkout@v4

- name: Setup Golang
uses: actions/setup-go@v5
with:
go-version-file: tests-e2e/go.mod

- name: GH actions workaround - Kill XSP4 process
run: |
sudo pkill mono || true

- name: Restore go build cache
uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}

- name: Add /usr/local/bin to PATH
run: |
echo "/usr/local/bin" >> $GITHUB_PATH

- name: Run the tests
run: |
set -o pipefail
make download-deps

make setup-e2e-local-k8s

kubectl port-forward svc/argocd-server -n gitops-service-argocd 51212:443 &

ARGO_CD_SERVER_ADDR=127.0.0.1:51212 make start-e2e &

GITHUB_K3D=true OVERRIDE_APISERVER_ADDR_SOURCE="0.0.0.0" OVERRIDE_APISERVER_ADDR_DEST="kubernetes.default.svc" make test-e2e

make e2e-reset
pkill go
pkill main

5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -141,7 +141,8 @@ install-argocd-openshift: kustomize ## Using OpenShift GitOps, install Argo CD t
PATH=$(MAKEFILE_ROOT)/bin:$(PATH) $(MAKEFILE_ROOT)/manifests/scripts/openshift-argo-deploy/deploy.sh

install-argocd-k8s: ## (Non-OpenShift): Install Argo CD to the gitops-service-argocd namespace
ARGO_CD_VERSION=$(ARGO_CD_VERSION) manifests/scripts/k8s-argo-deploy/deploy.sh
ARGO_CD_VERSION=$(ARGO_CD_VERSION) ./argocd.sh install
# manifests/scripts/k8s-argo-deploy/deploy.sh

uninstall-argocd: ## Uninstall Argo CD from gitops-service-argocd namespace (from either OpenShift or K8s)
kubectl delete namespace "$(ARGO_CD_NAMESPACE)" || true
@@ -197,6 +198,8 @@ test: test-backend test-backend-shared test-cluster-agent test-appstudio-control

setup-e2e-openshift: install-argocd-openshift devenv-k8s-e2e ## Setup steps for E2E tests to run with Openshift CI

setup-e2e-local-k8s: install-argocd-k8s devenv-docker reset-db ## Setup steps for E2E tests to run with Local Openshift Cluster

setup-e2e-local: install-argocd-openshift devenv-docker reset-db ## Setup steps for E2E tests to run with Local Openshift Cluster

start-e2e: ## Start the managed gitops processes for E2E tests.
37 changes: 34 additions & 3 deletions argocd.sh
Original file line number Diff line number Diff line change
@@ -4,6 +4,15 @@ ARGO_CD_VERSION="${ARGO_CD_VERSION:-stable}"
ARGO_CD_NAMESPACE="${ARGO_CD_NAMESPACE:-gitops-service-argocd}"
ARGO_CD_PORT="${ARGO_CD_PORT:-4000}"


SCRIPT_PATH="$(
cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit
pwd -P
)"

export ROOT_PATH=$SCRIPT_PATH


# This script installs ArgoCD vanilla according to https://argo-cd.readthedocs.io/en/stable/getting_started/

# Checks if a binary is present on the local system
@@ -16,19 +25,36 @@ exit_if_binary_not_installed() {
done
}

# Install Argo CD to target namespace, using kustomize.
# - Kustomize ensures that the ClusterRoleBindings are pointing to the ServiceAccount in the proper namespace.
build_argo_cd_manifests() {
KUSTOMIZE_TMP_DIR=$(mktemp -d)
cp -r $ROOT_PATH/manifests/k8s-argo-cd/* $KUSTOMIZE_TMP_DIR

mv $KUSTOMIZE_TMP_DIR/kustomization.yaml $KUSTOMIZE_TMP_DIR/kustomization.yaml.old

cat $KUSTOMIZE_TMP_DIR/kustomization.yaml.old | ARGO_CD_NAMESPACE=$ARGO_CD_NAMESPACE ARGO_CD_VERSION=$ARGO_CD_VERSION envsubst > $KUSTOMIZE_TMP_DIR/kustomization.yaml

}

# Install 'ArgoCD Web UI' in your Kubernetes cluster
if [ "$1" = "install" ]; then
exit_if_binary_not_installed "kubectl"
exit_if_binary_not_installed "kustomize"

if kubectl -n "$ARGO_CD_NAMESPACE" get pods | grep argocd-server | grep '1/1' | grep 'Running' &>/dev/null; then
echo "ArgoCD is already running..."
echo "Skipping ArgoCD setup."
exit 1
exit 0
fi

# Apply the argo-cd-route manifest
kubectl create namespace "$ARGO_CD_NAMESPACE" || true
kubectl apply -n "$ARGO_CD_NAMESPACE" -f https://raw.githubusercontent.com/argoproj/argo-cd/$ARGO_CD_VERSION/manifests/install.yaml

# Build and apply the Argo CD manifests
build_argo_cd_manifests

kustomize build $KUSTOMIZE_TMP_DIR | kubectl apply -f -

# Get the secret
counter=0
@@ -104,5 +130,10 @@ fi
# Remove 'ArgoCD Web UI' from your Kubernetes cluster
if [ "$1" = "remove" ]; then
exit_if_binary_not_installed "kubectl"
kubectl delete -n "$ARGO_CD_NAMESPACE" -f https://raw.githubusercontent.com/argoproj/argo-cd/$ARGO_CD_VERSION/manifests/install.yaml
exit_if_binary_not_installed "kustomize"

build_argo_cd_manifests

kustomize build $KUSTOMIZE_TMP_DIR | kubectl delete -f -
kubectl delete namespace "$ARGO_CD_NAMESPACE" || true
fi
13 changes: 10 additions & 3 deletions cluster-agent/utils/argocd_login_credentials.go
Original file line number Diff line number Diff line change
@@ -4,16 +4,17 @@ import (
"context"
"errors"
"fmt"
"os"
"strings"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"

argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient"
"github.com/argoproj/argo-cd/v2/util/grpc"
"github.com/go-logr/logr"
"github.com/golang/protobuf/ptypes/empty"
routev1 "github.com/openshift/api/route/v1"
"k8s.io/apimachinery/pkg/util/intstr"

sharedutil "github.com/redhat-appstudio/managed-gitops/backend-shared/util"
logutil "github.com/redhat-appstudio/managed-gitops/backend-shared/util/log"
@@ -221,9 +222,14 @@ func (cs *CredentialService) getCredentialsFromNamespace(req credentialRequest,
return nil, nil, errors.New("no Argo CD admin passwords found in " + req.namespaceName)
}

var serverHostName string

// Retrieve the Argo CD host name from the Route
serverHostName := ""
{

argoCDServerAddrEnvVar := strings.TrimSpace(os.Getenv("ARGO_CD_SERVER_ADDR"))
if len(argoCDServerAddrEnvVar) > 0 {
serverHostName = argoCDServerAddrEnvVar
} else {

routeList := &routev1.RouteList{}

@@ -249,6 +255,7 @@ func (cs *CredentialService) getCredentialsFromNamespace(req credentialRequest,

}
}

if serverHostName == "" {
return nil, nil, errors.New("Unable to locate Route in " + req.namespaceName)
}
29 changes: 29 additions & 0 deletions manifests/k8s-argo-cd/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- https://raw.githubusercontent.com/argoproj/argo-cd/$ARGO_CD_VERSION/manifests/install.yaml

namespace: $ARGO_CD_NAMESPACE

patchesStrategicMerge:
- |-
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argocd-application-controller
subjects:
- kind: ServiceAccount
name: argocd-application-controller
namespace: $ARGO_CD_NAMESPACE

- |-
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argocd-server
subjects:
- kind: ServiceAccount
name: argocd-server
namespace: $ARGO_CD_NAMESPACE

2 changes: 1 addition & 1 deletion tests-e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -3,5 +3,5 @@ cover.out
vendor
bin
coverage.out

ginkgo.report

2 changes: 1 addition & 1 deletion tests-e2e/Makefile
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ help: ## Display this help.

.PHONY: test
test: ## Run E2E tests.
ENABLE_APPPROJECT_ISOLATION="true" DEV_ONLY_ALLOW_NON_TLS_CONNECTION_TO_POSTGRESQL=true go test -v -p=1 -timeout=100m -race -count=1 -coverprofile=coverage.out ./...
ENABLE_APPPROJECT_ISOLATION="true" DEV_ONLY_ALLOW_NON_TLS_CONNECTION_TO_POSTGRESQL=true go test -v -p=1 -timeout=100m -race -count=1 -coverprofile=coverage.out ./core/ ./argocd/

# go-get-tool will 'go install' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
2 changes: 2 additions & 0 deletions tests-e2e/argocd/argocd_gitopsengine_instance_test.go
Original file line number Diff line number Diff line change
@@ -31,6 +31,8 @@ var _ = Describe("ArgoCD instance via GitOpsEngineInstance Operations Test", fun

It("ensures that a standalone ArgoCD gets created successfully when an operation CR of resource-type GitOpsEngineInstance is created", func() {

fixture.SkipIfArgoCDOperandRequired()

dbq, err := db.NewUnsafePostgresDBQueries(true, true)
Expect(err).ToNot(HaveOccurred())
defer dbq.CloseDatabase()
3 changes: 3 additions & 0 deletions tests-e2e/argocd/argocd_instance_test.go
Original file line number Diff line number Diff line change
@@ -44,6 +44,9 @@ var _ = Describe("Standalone ArgoCD instance E2E tests", func() {
})

testStandaloneArgoCD := func(testUpdate bool) {

fixture.SkipIfArgoCDOperandRequired()

By("creating ArgoCD resource")
ctx := context.Background()
log := log.FromContext(ctx)
10 changes: 10 additions & 0 deletions tests-e2e/argocd/queryscoped_cluster_secrets_test.go
Original file line number Diff line number Diff line change
@@ -138,6 +138,11 @@ var _ = Describe("Argo CD Application tests", func() {

func(clusterScoped bool) {

if fixture.IsGitHubK3D() {
Skip("when running on GitHub CI via K3d, we don't have an API endpoint IP we can use, so skip")
return
}

createServiceAccountsAndSecretsForTest(clusterScoped)

for _, userName := range users {
@@ -203,6 +208,11 @@ var _ = Describe("Argo CD Application tests", func() {

DescribeTable("ensure users cannot deploy to another user's namespace, when using different Argo CD cluster secrets for each user, each with a query parameter", func(clusterScoped bool) {

if fixture.IsGitHubK3D() {
Skip("when running on GitHub CI via K3d, we don't have an API endpoint IP we can use, so skip")
return
}

createServiceAccountsAndSecretsForTest(clusterScoped)

Expect(users).To(HaveLen(2))
12 changes: 0 additions & 12 deletions tests-e2e/core/gitopsdeployment_status_test.go
Original file line number Diff line number Diff line change
@@ -46,18 +46,6 @@ var _ = Describe("GitOpsDeployment Status Tests", func() {
Status: managedgitopsv1alpha1.HeathStatusCodeHealthy,
},
},
{
Group: "route.openshift.io",
Version: "v1",
Kind: "Route",
Namespace: fixture.GitOpsServiceE2ENamespace,
Name: name,
Status: managedgitopsv1alpha1.SyncStatusCodeSynced,
Health: &managedgitopsv1alpha1.HealthStatus{
Status: managedgitopsv1alpha1.HeathStatusCodeHealthy,
Message: "Route is healthy",
},
},
{
Group: "",
Version: "v1",
15 changes: 12 additions & 3 deletions tests-e2e/core/gitopsdeployment_syncrun_test.go
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ import (
)

var _ = Describe("GitOpsDeploymentSyncRun E2E tests", func() {

Context("Create, update and delete GitOpsDeploymentSyncRun", func() {

var (
@@ -65,10 +66,14 @@ var _ = Describe("GitOpsDeploymentSyncRun E2E tests", func() {
})

AfterEach(func() {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(argocdCR), argocdCR)
Expect(err == nil || apierr.IsNotFound(err)).To(BeTrue())

removeCustomHealthCheckForDeployment(ctx, k8sClient, argocdCR)
if fixture.IsArgoCDOperandAvailable() {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(argocdCR), argocdCR)
Expect(err == nil || apierr.IsNotFound(err)).To(BeTrue())

removeCustomHealthCheckForDeployment(ctx, k8sClient, argocdCR)
}

})

It("creating a new GitOpsDeploymentSyncRun should sync an Argo CD Application", func() {
@@ -197,6 +202,8 @@ var _ = Describe("GitOpsDeploymentSyncRun E2E tests", func() {
})

It("deleting the GitOpsDeploymentSyncRun should terminate a running Sync operation", func() {
fixture.SkipIfArgoCDOperandRequired()

gitOpsDeploymentResource = gitopsDeplFixture.BuildGitOpsDeploymentResource("test-deply-with-presync",
"https://github.com/managed-gitops-test-data/deployment-presync-hook", "guestbook",
managedgitopsv1alpha1.GitOpsDeploymentSpecType_Manual)
@@ -314,6 +321,8 @@ var _ = Describe("GitOpsDeploymentSyncRun E2E tests", func() {

It("should sync if the previous sync operation is terminated", func() {

fixture.SkipIfArgoCDOperandRequired()

gitOpsDeploymentResource = gitopsDeplFixture.BuildGitOpsDeploymentResource("test-deply-with-presync",
"https://github.com/managed-gitops-test-data/deployment-presync-hook", "guestbook",
managedgitopsv1alpha1.GitOpsDeploymentSpecType_Manual)
12 changes: 0 additions & 12 deletions tests-e2e/core/gitopsdeployment_test.go
Original file line number Diff line number Diff line change
@@ -76,18 +76,6 @@ var _ = Describe("GitOpsDeployment E2E tests", func() {
Status: managedgitopsv1alpha1.HeathStatusCodeHealthy,
},
},
{
Group: "route.openshift.io",
Version: "v1",
Kind: "Route",
Namespace: fixture.GitOpsServiceE2ENamespace,
Name: name,
Status: managedgitopsv1alpha1.SyncStatusCodeSynced,
Health: &managedgitopsv1alpha1.HealthStatus{
Status: managedgitopsv1alpha1.HeathStatusCodeHealthy,
Message: "Route is healthy",
},
},
{
Group: "",
Version: "v1",
6 changes: 5 additions & 1 deletion tests-e2e/core/managed_environment_status_test.go
Original file line number Diff line number Diff line change
@@ -43,8 +43,12 @@ var _ = Describe("Managed Environment Status E2E tests", func() {
Expect(managedEnv.Status.Conditions).To(HaveLen(1))
condition := managedEnv.Status.Conditions[0]
Expect(condition.Status).To(Equal(metav1.ConditionFalse))
Expect(condition.Reason).To(Equal(string(managedgitopsv1alpha1.ConditionReasonUnableToCreateClient)))
Expect(condition.Reason).To(Or(
Equal(string(managedgitopsv1alpha1.ConditionReasonUnableToCreateClient)),
Equal(string(managedgitopsv1alpha1.ConditionReasonUnableToInstallServiceAccount)),
))
Expect(condition.Message).To(ContainSubstring("no such host"))

})

It("should have a connection status condition of False when the credentials are missing a required field", func() {
69 changes: 4 additions & 65 deletions tests-e2e/core/managed_environment_test.go
Original file line number Diff line number Diff line change
@@ -2,8 +2,6 @@ package core

import (
"context"
"fmt"
"os"
"time"

"github.com/argoproj/argo-cd/v2/common"
@@ -14,7 +12,6 @@ import (
"github.com/redhat-appstudio/managed-gitops/backend-shared/util"
"github.com/redhat-appstudio/managed-gitops/tests-e2e/fixture"
"github.com/redhat-appstudio/managed-gitops/tests-e2e/fixture/k8s"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/client"

appv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
@@ -183,7 +180,7 @@ var _ = Describe("GitOpsDeployment Managed Environment E2E tests", func() {

By("creating the GitOpsDeploymentManagedEnvironment and Secret")

_, apiServerURL, err := extractKubeConfigValues()
_, apiServerURL, err := fixture.ExtractKubeConfigValues()
Expect(err).ToNot(HaveOccurred())

kubeConfigContents := k8s.GenerateKubeConfig(apiServerURL, fixture.GitOpsServiceE2ENamespace, tokenSecret)
@@ -319,7 +316,7 @@ var _ = Describe("GitOpsDeployment Managed Environment E2E tests", func() {

By("creating the GitOpsDeploymentManagedEnvironment")

_, apiServerURL, err := extractKubeConfigValues()
_, apiServerURL, err := fixture.ExtractKubeConfigValues()
Expect(err).ToNot(HaveOccurred())

// Set the tokenSecret to be "" to intentionally fail
@@ -407,7 +404,7 @@ var _ = Describe("GitOpsDeployment Managed Environment E2E tests", func() {

By("creating the GitOpsDeploymentManagedEnvironment")

_, apiServerURL, err := extractKubeConfigValues()
_, apiServerURL, err := fixture.ExtractKubeConfigValues()
Expect(err).ToNot(HaveOccurred())

kubeConfigContents := k8s.GenerateKubeConfig(apiServerURL, fixture.GitOpsServiceE2ENamespace, tokenSecret)
@@ -524,7 +521,7 @@ var _ = Describe("GitOpsDeployment Managed Environment E2E tests", func() {

By("creating the GitOpsDeploymentManagedEnvironment and its Secret, using that service account token")

_, apiServerURL, err := extractKubeConfigValues()
_, apiServerURL, err := fixture.ExtractKubeConfigValues()
Expect(err).ToNot(HaveOccurred())

kubeConfigContents := k8s.GenerateKubeConfig(apiServerURL, newNamespace.Name, tokenSecret)
@@ -981,61 +978,3 @@ var _ = Describe("GitOpsDeployment Managed Environment E2E tests", func() {

})
})

// extractKubeConfigValues returns contents of k8s config from $KUBE_CONFIG, plus server api url (and error)
func extractKubeConfigValues() (string, string, error) {

loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()

config, err := loadingRules.Load()
if err != nil {
return "", "", err
}

context, ok := config.Contexts[config.CurrentContext]
if !ok || context == nil {
return "", "", fmt.Errorf("no context")
}

cluster, ok := config.Clusters[context.Cluster]
if !ok || cluster == nil {
return "", "", fmt.Errorf("no cluster")
}

var kubeConfigDefault string

paths := loadingRules.Precedence
{

for _, path := range paths {

GinkgoWriter.Println("Attempting to read kube config from", path)

// homeDir, err := os.UserHomeDir()
// if err != nil {
// return "", "", err
// }

_, err = os.Stat(path)
if err != nil {
GinkgoWriter.Println("Unable to resolve path", path, err)
} else {
// Success
kubeConfigDefault = path
break
}

}

if kubeConfigDefault == "" {
return "", "", fmt.Errorf("unable to retrieve kube config path")
}
}

kubeConfigContents, err := os.ReadFile(kubeConfigDefault)
if err != nil {
return "", "", err
}

return string(kubeConfigContents), cluster.Server, nil
}
113 changes: 109 additions & 4 deletions tests-e2e/fixture/fixture.go
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ import (
apps "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
apiexts "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -60,7 +61,7 @@ const (
// EnableNamespaceBackedArgoCD: When enabled, this will ensure that certain tests/fixtures add the managed-by label to Namespace. This allows the gitops-service-argocd instance to manage them.
//
// When Argo CD is running in cluster-scoped mode (i.e. due to concerns with performance issues when Argo CD is running in namespace-scoped mode), this field should be set to false.
EnableNamespaceBackedArgoCD = true
EnableNamespaceBackedArgoCD = false
)

// EnsureCleanSlateNonKCPVirtualWorkspace should be called before every E2E tests:
@@ -459,6 +460,49 @@ func removeAllFinalizers(k8sClient client.Client, obj client.Object) error {
return nil
}

func isArgoCDClusterScoped(argoCDNamespaceParam string, clientConfig *rest.Config) (bool, error) {

k8sClient, err := GetKubeClient(clientConfig)
if err != nil {
return false, err
}

saList := &corev1.ServiceAccountList{}

if err := k8sClient.List(context.Background(), saList, &client.ListOptions{Namespace: argoCDNamespaceParam}); err != nil {
return false, err
}

crbList := &rbacv1.ClusterRoleBindingList{}
if err := k8sClient.List(context.Background(), crbList); err != nil {
return false, err
}

// For each ClusterRoleBinding
for _, crbItem := range crbList.Items {

// For each Subject of the Binding
for _, subject := range crbItem.Subjects {

// Return true if there exists a subject pointing to one of the ServiceAccounts
// in the Argo CD namepace.
if subject.Namespace == argoCDNamespaceParam {

for _, sa := range saList.Items {

if sa.Name == subject.Name {
return true, nil
}
}

}
}
}

return false, nil

}

func EnsureDestinationNamespaceExists(namespaceParam string, argoCDNamespaceParam string, clientConfig *rest.Config) error {

kubeClientSet, err := kubernetes.NewForConfig(clientConfig)
@@ -490,7 +534,7 @@ func EnsureDestinationNamespaceExists(namespaceParam string, argoCDNamespacePara
// We used to wait here, prior to moving to Cluster Scoped Argo CD
// eg. Call: waitForArgoCDToProcessNamespace(namespaceParam, argoCDNamespaceParam, kubeClientSet)
if EnableNamespaceBackedArgoCD {
if err := waitForArgoCDToProcessNamespace(namespaceParam, argoCDNamespaceParam, kubeClientSet); err != nil {
if err := waitForArgoCDToProcessNamespace(namespaceParam, argoCDNamespaceParam, kubeClientSet, clientConfig); err != nil {
return fmt.Errorf("unable to wait for Argo CD to process namespace: %w", err)
}
}
@@ -501,7 +545,11 @@ func EnsureDestinationNamespaceExists(namespaceParam string, argoCDNamespacePara
// Wait for Argo CD to process the namespace, before we exit:
// - This helps us avoid a race condition where the namespace is created, but Argo CD has not yet
// set up proper roles for it.
func waitForArgoCDToProcessNamespace(namespaceParam string, argoCDNamespaceParam string, kubeClientSet *kubernetes.Clientset) error {
func waitForArgoCDToProcessNamespace(namespaceParam string, argoCDNamespaceParam string, kubeClientSet *kubernetes.Clientset, clientConfig *rest.Config) error {

if isClusterScoped, err := isArgoCDClusterScoped(argoCDNamespaceParam, clientConfig); isClusterScoped || err != nil {
return err
}

// Wait for Argo CD to process the namespace, before we exit:
// - This helps us avoid a race condition where the namespace is created, but Argo CD has not yet
@@ -822,6 +870,10 @@ func GetKubeClient(config *rest.Config) (client.Client, error) {
return nil, err
}

if err := apiexts.AddToScheme(scheme); err != nil {
return nil, err
}

err = codereadytoolchainv1alpha1.AddToScheme(scheme)
if err != nil {
return nil, err
@@ -878,6 +930,10 @@ func GetE2ETestUserWorkspaceKubeClient() (client.Client, error) {
return k8sClient, nil
}

func IsGitHubK3D() bool {
return strings.TrimSpace(strings.ToLower(os.Getenv("GITHUB_K3D"))) == "true"
}

// IsRunningInStonesoupEnvironment returns true if the tests are running in a Stonesoup environment, false otherwise
func IsRunningInStonesoupEnvironment() bool {
// Stonesoup environment is bootstrapped by an AppOfApps Gitops Deployment.
@@ -953,5 +1009,54 @@ func ExtractKubeConfigValues() (string, string, error) {
return "", "", err
}

return string(kubeConfigContents), cluster.Server, nil
serverValRes := cluster.Server
kubeConfigContentsRes := string(kubeConfigContents)

// Allow overriding of the API Server URL via env var, to allow testing in quirky network configurations
overrideAPIServiceAddrSrc := strings.TrimSpace(os.Getenv("OVERRIDE_APISERVER_ADDR_SOURCE"))
if len(overrideAPIServiceAddrSrc) > 0 {
overrideAPIServiceAddrDest := strings.TrimSpace(os.Getenv("OVERRIDE_APISERVER_ADDR_DEST"))

serverValRes = strings.ReplaceAll(serverValRes, overrideAPIServiceAddrSrc, overrideAPIServiceAddrDest)
kubeConfigContentsRes = strings.ReplaceAll(kubeConfigContentsRes, overrideAPIServiceAddrSrc, overrideAPIServiceAddrDest)
}

fmt.Println("JGW", kubeConfigContentsRes)

return kubeConfigContentsRes, serverValRes, nil
}

// SkipIfArgoCDOperandRequired will cause a test to be skipped if the ArgoCD
// CustomResourceDefinition is not installed (because OpenShift GitOps Operator is not installed.)
func SkipIfArgoCDOperandRequired() {

available := IsArgoCDOperandAvailable()

if !available {
Skip("Skipping as ArgoCD CustomResourceDefinition is not installed, which is required for test.")
}

}

func IsArgoCDOperandAvailable() bool {

k8sConfig, err := GetServiceProviderWorkspaceKubeConfig()
Expect(err).ToNot(HaveOccurred())

k8sClient, err := GetKubeClient(k8sConfig)
Expect(err).ToNot(HaveOccurred())

crdList := &apiexts.CustomResourceDefinitionList{}
err = k8sClient.List(context.Background(), crdList)
Expect(err).ToNot(HaveOccurred())

argoCDCRFound := false
for _, crd := range crdList.Items {
if crd.Spec.Names.Kind == "ArgoCD" {
argoCDCRFound = true
}
}

return argoCDCRFound

}
2 changes: 1 addition & 1 deletion tests-e2e/go.mod
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ require (
github.com/redhat-appstudio/managed-gitops/backend v0.0.0-00010101000000-000000000000
github.com/redhat-appstudio/managed-gitops/backend-shared v0.0.0
github.com/redhat-appstudio/managed-gitops/cluster-agent v0.0.0
k8s.io/apiextensions-apiserver v0.31.2
k8s.io/apimachinery v0.31.0
k8s.io/client-go v12.0.0+incompatible
sigs.k8s.io/controller-runtime v0.19.0
@@ -183,7 +184,6 @@ require (
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.31.0
k8s.io/apiextensions-apiserver v0.31.2 // indirect
k8s.io/component-base v0.31.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect