Skip to content
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
7 changes: 4 additions & 3 deletions bundle/manifests/argoproj.io_argocds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7542,7 +7542,7 @@ spec:
keycloak:
description: |-
Keycloak contains the configuration for Argo CD keycloak authentication
Deprecated: This field is planned for removal in a future release and will no longer be supported.
Removed: This field is no longer supported and the related functionality has been removed.
properties:
host:
description: Host is the hostname to use for Ingress/Route
Expand Down Expand Up @@ -28719,8 +28719,9 @@ spec:
type: array
type: object
keycloak:
description: Keycloak contains the configuration for Argo CD keycloak
authentication
description: |-
Keycloak contains the configuration for Argo CD keycloak authentication
Removed: This field is no longer supported and the related functionality has been removed.
properties:
host:
description: Host is the hostname to use for Ingress/Route
Expand Down
7 changes: 4 additions & 3 deletions config/crd/bases/argoproj.io_argocds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7531,7 +7531,7 @@ spec:
keycloak:
description: |-
Keycloak contains the configuration for Argo CD keycloak authentication
Deprecated: This field is planned for removal in a future release and will no longer be supported.
Removed: This field is no longer supported and the related functionality has been removed.
properties:
host:
description: Host is the hostname to use for Ingress/Route
Expand Down Expand Up @@ -28708,8 +28708,9 @@ spec:
type: array
type: object
keycloak:
description: Keycloak contains the configuration for Argo CD keycloak
authentication
description: |-
Keycloak contains the configuration for Argo CD keycloak authentication
Removed: This field is no longer supported and the related functionality has been removed.
properties:
host:
description: Host is the hostname to use for Ingress/Route
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.24.4

require (
github.com/argoproj-labs/argo-rollouts-manager v0.0.6-0.20250731075119-a100fc1d88b8
github.com/argoproj-labs/argocd-operator v0.14.0-rc1.0.20250808153852-5135028d6978
github.com/argoproj-labs/argocd-operator v0.14.0-rc1.0.20250812131727-80f37522108a
github.com/argoproj/argo-cd/v3 v3.1.0-rc2
github.com/argoproj/gitops-engine v0.7.1-0.20250617174952-093aef0dad58
github.com/go-logr/logr v1.4.3
Expand Down Expand Up @@ -111,7 +111,6 @@ require (
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/openshift/client-go v0.0.0-20200325131901-f7baeb993edb // indirect
github.com/patrickmn/go-cache v2.1.1-0.20191004192108-46f407853014+incompatible // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
Expand Down
223 changes: 2 additions & 221 deletions go.sum

Large diffs are not rendered by default.

244 changes: 0 additions & 244 deletions test/e2e/gitopsservice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,19 @@ package e2e
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"io"
"net/http"
"net/url"
"os/exec"
"path/filepath"
"reflect"
"strings"
"time"

b64 "encoding/base64"
"encoding/json"

argoapp "github.com/argoproj-labs/argocd-operator/api/v1beta1"
"github.com/argoproj-labs/argocd-operator/common"
"github.com/argoproj-labs/argocd-operator/controllers/argoutil"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
osappsv1 "github.com/openshift/api/apps/v1"
configv1 "github.com/openshift/api/config/v1"
routev1 "github.com/openshift/api/route/v1"
templatev1 "github.com/openshift/api/template/v1"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
pipelinesv1alpha1 "github.com/redhat-developer/gitops-operator/api/v1alpha1"
gitopscommon "github.com/redhat-developer/gitops-operator/common"
Expand Down Expand Up @@ -79,14 +69,6 @@ var _ = Describe("GitOpsServiceController", func() {
// update .sso.provider = keycloak to enable RHSSO for default Argo CD instance.
// update verifyTLS = false to ensure operator(when run locally) can create RHSSO resources.
argoCDInstance.Spec.DisableAdmin = true
insecure := false
// remove dex configuration, only one SSO is supported.
argoCDInstance.Spec.SSO = &argoapp.ArgoCDSSOSpec{
Provider: "keycloak",
Keycloak: &argoapp.ArgoCDKeycloakSpec{
VerifyTLS: &insecure,
},
}

err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
updatedInstance := &argoapp.ArgoCD{}
Expand All @@ -95,7 +77,6 @@ var _ = Describe("GitOpsServiceController", func() {
return err
}
updatedInstance.Spec.DisableAdmin = argoCDInstance.Spec.DisableAdmin
updatedInstance.Spec.SSO = argoCDInstance.Spec.SSO
return k8sClient.Update(context.TODO(), updatedInstance)
})
Expect(err).NotTo(HaveOccurred())
Expand Down Expand Up @@ -633,176 +614,6 @@ var _ = Describe("GitOpsServiceController", func() {
})
})

Context("Verify RHSSO installation", func() {
namespace := argoCDNamespace
It("Template instance is created", func() {
tInstance := &templatev1.TemplateInstance{}
checkIfPresent(types.NamespacedName{Name: defaultTemplateIdentifier, Namespace: namespace}, tInstance)
})

It("Keycloak deployment is created", func() {
Eventually(func() error {
dc := osappsv1.DeploymentConfig{}
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: defaultKeycloakIdentifier, Namespace: namespace}, &dc)
if err != nil {
return err
}
got := dc.Status.AvailableReplicas
want := int32(1)
if got != want {
return fmt.Errorf("expected %d, got %d", want, got)
}
return nil
}, timeout, interval).ShouldNot(HaveOccurred())
})

It("Keycloak service is created", func() {
svc := &corev1.Service{}
checkIfPresent(types.NamespacedName{Name: defaultKeycloakIdentifier, Namespace: namespace}, svc)
})

It("Keycloak service route is created", func() {
route := &routev1.Route{}
checkIfPresent(types.NamespacedName{Name: defaultKeycloakIdentifier, Namespace: namespace}, route)
})
})

Context("Verify RHSSO configuration", func() {
namespace := argoCDNamespace

It("Verify RHSSO Realm creation", func() {
By("get keycloak URL and credentials")
route := &routev1.Route{}
checkIfPresent(types.NamespacedName{Name: defaultKeycloakIdentifier, Namespace: namespace}, route)

secret := &corev1.Secret{}
checkIfPresent(types.NamespacedName{Name: rhssosecret, Namespace: namespace}, secret)

userEnc := b64.URLEncoding.EncodeToString(secret.Data["SSO_USERNAME"])
user, _ := b64.URLEncoding.DecodeString(userEnc)

passEnc := b64.URLEncoding.EncodeToString(secret.Data["SSO_PASSWORD"])
pass, _ := b64.URLEncoding.DecodeString(passEnc)

By("get auth token from kaycloak")
accessURL := fmt.Sprintf("https://%s%s", route.Spec.Host, authURL)
argoRealmURL := fmt.Sprintf("https://%s%s", route.Spec.Host, realmURL)

accessToken, err := getAccessToken(string(user), string(pass), accessURL)
Expect(err).NotTo(HaveOccurred())

By("create a new https request to verify Realm creation")
client := http.Client{}
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
request, err := http.NewRequest("GET", argoRealmURL, nil)
Expect(err).NotTo(HaveOccurred())
request.Header.Set("Content-Type", "application/json")
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))

By("verify RHSSO realm creation and check if HTTP GET returns 200 ")
response, err := client.Do(request)
Expect(err).NotTo(HaveOccurred())
defer response.Body.Close()

By("verify reponse")
b, err := io.ReadAll(response.Body)
Expect(err).NotTo(HaveOccurred())

m := make(map[string]interface{})
err = json.Unmarshal(b, &m)
Expect(err).NotTo(HaveOccurred())

Expect(m["realm"]).To(Equal("argocd"))
Expect(m["registrationFlow"]).To(Equal("registration"))
Expect(m["browserFlow"]).To(Equal("browser"))
Expect(m["clientAuthenticationFlow"]).To(Equal("clients"))
Expect(m["directGrantFlow"]).To(Equal("direct grant"))
Expect(m["loginWithEmailAllowed"]).To(BeTrue())

idps := m["identityProviders"].([]interface{})
idp := idps[0].(map[string]interface{})

Expect(idp["alias"]).To(Equal("openshift-v4"))
Expect(idp["displayName"]).To(Equal("Login with OpenShift"))
Expect(idp["providerId"]).To(Equal("openshift-v4"))
Expect(idp["firstBrokerLoginFlowAlias"]).To(Equal("first broker login"))
})

It("Verify OIDC Configuration is created", func() {
Eventually(func() error {
cm := &corev1.ConfigMap{}
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: argoCDConfigMapName, Namespace: namespace}, cm)
if err != nil {
return err
}
if cm.Data[common.ArgoCDKeyOIDCConfig] == "" {
return fmt.Errorf("expected OIDC configuration to be created")
}
return nil
}, timeout, interval).ShouldNot(HaveOccurred())
})

})

Context("Verify RHSSO uninstallation", func() {
namespace := argoCDNamespace
argocd := &argoapp.ArgoCD{}
It("Remove SSO field from Argo CD CR", func() {

err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: argoCDInstanceName, Namespace: namespace}, argocd)
Expect(err).ToNot(HaveOccurred())

argocd.Spec.SSO = nil
return k8sClient.Update(context.TODO(), argocd)
})
Expect(err).NotTo(HaveOccurred())
})

It("OIDC configuration is removed", func() {
Eventually(func() bool {
cm := &corev1.ConfigMap{}
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: argoCDConfigMapName, Namespace: namespace}, cm)
Expect(err).NotTo(HaveOccurred())
return cm.Data[common.ArgoCDKeyOIDCConfig] == ""
}, timeout, interval).Should(BeTrue())
})

It("Template instance is deleted", func() {
Eventually(func() error {
templateInstance := &templatev1.TemplateInstance{}
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: defaultTemplateIdentifier, Namespace: namespace}, templateInstance)
if kubeerrors.IsNotFound(err) {
return nil
}
return err
}, timeout, interval).ShouldNot(HaveOccurred())
})

It("Add SSO field back and verify reconcilation", func() {
insecure := false
argocd.Spec.SSO = &argoapp.ArgoCDSSOSpec{
Provider: defaultKeycloakIdentifier,
Keycloak: &argoapp.ArgoCDKeycloakSpec{
VerifyTLS: &insecure,
},
}
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
updatedInstance := &argoapp.ArgoCD{}
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: argoCDInstanceName, Namespace: argoCDNamespace}, updatedInstance)
if err != nil {
return err
}
updatedInstance.Spec.SSO = argocd.Spec.SSO
return k8sClient.Update(context.TODO(), updatedInstance)
})
Expect(err).NotTo(HaveOccurred())

templateInstance := &templatev1.TemplateInstance{}
checkIfPresent(types.NamespacedName{Name: defaultTemplateIdentifier, Namespace: namespace}, templateInstance)
})
})

Context("Verify Configuring Infrastructure NodeSelector ", func() {
name := "cluster"
gitopsService := &pipelinesv1alpha1.GitopsService{}
Expand Down Expand Up @@ -889,61 +700,6 @@ var _ = Describe("GitOpsServiceController", func() {

})

type tokenResponse struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
RefreshExpiresIn int `json:"refresh_expires_in"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
NotBeforePolicy int `json:"not-before-policy"`
SessionState string `json:"session_state"`
Error string `json:"error"`
ErrorDescription string `json:"error_description"`
}

func getAccessToken(user, pass, accessURL string) (string, error) {
form := url.Values{}
form.Add("username", user)
form.Add("password", pass)
form.Add("client_id", "admin-cli")
form.Add("grant_type", "password")

client := http.Client{}
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
req, err := http.NewRequest(
"POST",
accessURL,
strings.NewReader(form.Encode()),
)
if err != nil {
return "", err
}

req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := client.Do(req)
if err != nil {
return "", err
}

defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}

tokenRes := &tokenResponse{}
err = json.Unmarshal(body, tokenRes)
if err != nil {
return "", err
}

if tokenRes.Error != "" {
return "", err
}

return tokenRes.AccessToken, nil
}

func runCommandWithOutput(cmdList ...string) (string, string, error) {

// Output the commands to be run, so that if the test fails we can determine why
Expand Down
3 changes: 0 additions & 3 deletions test/e2e/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ const (
consoleLinkName = "argocd"
argoCDInstanceName = "openshift-gitops"
gitopsInstanceName = "cluster"
defaultKeycloakIdentifier = "keycloak"
defaultTemplateIdentifier = "rhsso"
realmURL = "/auth/admin/realms/argocd"
rhssosecret = "keycloak-secret"
clusterConfigEnv = "ARGOCD_CLUSTER_CONFIG_NAMESPACES"
argocdManagedByLabel = "argocd.argoproj.io/managed-by"
timeout = time.Minute * 5
Expand Down
Loading