Skip to content

Commit 9c5f041

Browse files
authored
Merge branch 'master' into fix-intellij-idea-integration
2 parents 2b2bcb3 + c4bdd09 commit 9c5f041

14 files changed

Lines changed: 1098 additions & 68 deletions

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ COPY controllers/ controllers/
1616
COPY common/ common/
1717
COPY version/ version/
1818

19-
# Build
20-
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager ./cmd/main.go
19+
# Build - Use TARGETARCH to build for the correct architecture
20+
ARG TARGETARCH
21+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -a -o manager ./cmd/main.go
2122

2223
# Use distroless as minimal base image to package the manager binary
2324
# Refer to https://github.com/GoogleContainerTools/distroless for more details

Makefile

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ IMG ?= $(IMAGE):$(VERSION)
6565
# Set the Operator SDK version to use.
6666
# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit.
6767
OPERATOR_SDK_VERSION ?= v1.35.0
68-
68+
# Set the path to Operator SDK - OPERATOR_SDK_VERSION will be ignored.
69+
OPERATOR_SDK ?= bin/operator-sdk
6970

7071
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
7172
ifeq (,$(shell go env GOBIN))
@@ -131,19 +132,6 @@ test-e2e: manifests generate fmt vet ## Run e2e tests.
131132
test-metrics:
132133
go test -timeout 30m ./test/e2e -ginkgo.focus="Argo CD metrics controller" -coverprofile cover.out -ginkgo.v
133134

134-
.PHONY: operator-sdk
135-
OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk
136-
operator-sdk: ## Download operator-sdk locally if necessary.
137-
ifeq (,$(wildcard $(OPERATOR_SDK)))
138-
@{ \
139-
set -e ;\
140-
mkdir -p $(dir $(OPERATOR_SDK)) ;\
141-
OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \
142-
curl -sSLo $(OPERATOR_SDK) https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$${OS}_$${ARCH} ;\
143-
chmod +x $(OPERATOR_SDK) ;\
144-
}
145-
endif
146-
147135
.PHONY: test-route
148136
test-route:
149137
go test -timeout 30m ./test/e2e -ginkgo.focus="Argo CD ConsoleLink controller" -coverprofile cover.out -ginkgo.v
@@ -211,7 +199,7 @@ build: generate fmt vet ## Build manager binary.
211199

212200
.PHONY: run
213201
run: manifests generate fmt vet ## Run a controller from your host.
214-
CLUSTER_SCOPED_ARGO_ROLLOUTS_NAMESPACES=argo-rollouts,test-rom-ns-1,rom-ns-1,openshift-gitops ARGOCD_CLUSTER_CONFIG_NAMESPACES="openshift-gitops, argocd-e2e-cluster-config, argocd-test-impersonation-1-046, argocd-agent-principal-1-051, argocd-agent-agent-1-052, appset-argocd, appset-old-ns, appset-new-ns, ns-hosting-principal, ns-hosting-managed-agent, ns-hosting-autonomous-agent" REDIS_CONFIG_PATH="build/redis" go run ./cmd/main.go
202+
CLUSTER_SCOPED_ARGO_ROLLOUTS_NAMESPACES=argo-rollouts,test-rom-ns-1,rom-ns-1,openshift-gitops ARGOCD_CLUSTER_CONFIG_NAMESPACES="openshift-gitops, argocd-e2e-cluster-config, argocd-test-impersonation-1-046, argocd-agent-principal-1-051, argocd-agent-agent-1-052, appset-argocd, appset-old-ns, appset-new-ns, ns-hosting-principal, ns-hosting-managed-agent, ns-hosting-autonomous-agent, appset-argocd-clusterrole" REDIS_CONFIG_PATH="build/redis" go run ./cmd/main.go
215203

216204
.PHONY: docker-build
217205
docker-build: test ## Build container image with the manager.
@@ -223,27 +211,17 @@ docker-push: ## Push container image with the manager.
223211

224212
##@ Build Dependencies
225213

226-
## Location to install dependencies to
227-
LOCALBIN ?= $(shell pwd)/bin
228-
$(LOCALBIN):
229-
mkdir -p $(LOCALBIN)
214+
# Do not use OPERATOR_SDK variable not to overwrite the user provided path
215+
bin/operator-sdk:
216+
mkdir -p bin
217+
curl -sSLo bin/operator-sdk \
218+
https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$(shell go env GOOS)_$(shell go env GOARCH)
219+
chmod +x bin/operator-sdk
230220

221+
# Install to bin/operator-sdk unless already there or explicit OPERATOR_SDK provided
231222
.PHONY: operator-sdk
232-
OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk
233-
operator-sdk: ## Download operator-sdk locally if necessary.
234-
ifeq (,$(wildcard $(OPERATOR_SDK)))
235-
ifeq (,$(shell which operator-sdk 2>/dev/null))
236-
@{ \
237-
set -e ;\
238-
mkdir -p $(dir $(OPERATOR_SDK)) ;\
239-
OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \
240-
curl -sSLo $(OPERATOR_SDK) https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$${OS}_$${ARCH} ;\
241-
chmod +x $(OPERATOR_SDK) ;\
242-
}
243-
else
244-
OPERATOR_SDK = $(shell which operator-sdk)
245-
endif
246-
endif
223+
operator-sdk: $(OPERATOR_SDK)
224+
@$(OPERATOR_SDK) version
247225

248226
ifndef ignore-not-found
249227
ignore-not-found = false
@@ -368,7 +346,7 @@ gosec: go_sec
368346
.PHONY: lint
369347
lint: golangci_lint
370348
$(GOLANGCI_LINT) --version
371-
GOMAXPROCS=2 $(GOLANGCI_LINT) run --fix --verbose --timeout 300s
349+
$(GOLANGCI_LINT) run --fix --verbose --timeout 300s
372350

373351

374352
GO_SEC = $(shell pwd)/bin/gosec
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Enhancing OpenShift Lightspeed with Custom Knowledge
2+
3+
## Overview
4+
This guide explains how to extend the intelligence of OpenShift Lightspeed by integrating specialized knowledge for Argo CD, the Argo CD Operator, and the GitOps Operator. By configuring a custom Retrieval-Augmented Generation (RAG) database, you ensure the service provides precise, context-aware assistance for your GitOps queries.
5+
6+
The OpenShift Lightspeed service leverages Large Language Models (LLMs) to provide intelligent, context-aware responses. To ensure the model has deep expertise in your specific environment, you can use the Bring Your Own (BYO) Knowledge tool to integrate a Retrieval-Augmented Generation (RAG) database.
7+
8+
By connecting this database, you bridge the gap between general AI knowledge and specific technical documentation, ensuring more accurate troubleshooting and configuration advice.
9+
10+
11+
## Pre-packaged Knowledge for GitOps
12+
We have curated and optimized specialized knowledge sets for the following components:
13+
14+
* ArgoCD
15+
* ArgoCD Operator
16+
* Red Hat OpenShift GitOps Operator
17+
* ArgoCD Agent
18+
19+
This knowledge is packaged into a container [image](https://quay.io/devtools_gitops/argocd_lightspeed_byok:v0.0.4) and can be configured in Lightspeed using the instructions below.
20+
21+
## Prerequisites
22+
23+
* You are logged in to the OpenShift Container Platform web console as a user account that has permission to create a cluster-scoped custom resource (CR) file, such as a user with the cluster-admin role.
24+
* You have an LLM provider available for use with the OpenShift Lightspeed Service.
25+
* You have installed and configured the [OpenShift Lightspeed Operator](https://docs.redhat.com/en/documentation/red_hat_openshift_lightspeed/1.0/html/configure/ols-configuring-openshift-lightspeed).
26+
27+
Modify the OLSconfig CR to deploy the pre-packaged RAG database alongside the existing one:
28+
29+
* In the OpenShift Container Platform web console, click Operators >> Installed Operators.
30+
* Select All Projects in the Project dropdown at the top of the screen.
31+
* Click OpenShift Lightspeed Operator.
32+
* Click OLSConfig, then click the cluster configuration instance in the list.
33+
* Click the YAML tab.
34+
* Insert the spec.ols.rag yaml code:
35+
Example OLSconfig CR file
36+
37+
```bash
38+
apiVersion: ols.openshift.io/v1alpha1
39+
kind: OLSConfig
40+
metadata:
41+
name: cluster
42+
spec:
43+
ols:
44+
rag:
45+
- image: quay.io/devtools_gitops/argocd_lightspeed_byok:v0.0.4
46+
```
47+
48+
Note: Where image specifies the tag for the image that is present in the image registry so that the OpenShift Lightspeed Operator can access the custom content.
49+
* Click Save.

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ go 1.25.5
55
require (
66
github.com/argoproj-labs/argo-rollouts-manager v0.0.8-0.20260224121037-1824164aac67
77
github.com/argoproj-labs/argocd-image-updater v1.1.1
8-
github.com/argoproj-labs/argocd-operator v0.17.0-rc1.0.20260227080902-0433a07294f8
9-
github.com/argoproj/argo-cd/v3 v3.3.0
8+
github.com/argoproj-labs/argocd-operator v0.17.0-rc1.0.20260304133241-fd7fd59a2b0b
9+
github.com/argoproj/argo-cd/v3 v3.3.2
1010
github.com/argoproj/gitops-engine v0.7.1-0.20251217140045-5baed5604d2d
1111
github.com/go-logr/logr v1.4.3
1212
github.com/google/go-cmp v0.7.0

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ github.com/argoproj-labs/argo-rollouts-manager v0.0.8-0.20260224121037-1824164aa
3939
github.com/argoproj-labs/argo-rollouts-manager v0.0.8-0.20260224121037-1824164aac67/go.mod h1:WPyZkNHZjir/OTt8mrRwcUZKe1euHrHPJsRv1Wp/F/0=
4040
github.com/argoproj-labs/argocd-image-updater v1.1.1 h1:7YDaR3WX2NMsDKp0wN7TRaRRHaVHQ94tSybi2P99MGk=
4141
github.com/argoproj-labs/argocd-image-updater v1.1.1/go.mod h1:gMHiNrGNwNSt4ljf0ykcnmNvXBk/NJ+Z17AnZVe7V7I=
42-
github.com/argoproj-labs/argocd-operator v0.17.0-rc1.0.20260227080902-0433a07294f8 h1:MZH+YNGfucyny7tX2Fs4aNNQgeOuu9Gi7MtjS3L4R1U=
43-
github.com/argoproj-labs/argocd-operator v0.17.0-rc1.0.20260227080902-0433a07294f8/go.mod h1:3/Y9YWMU+DHC+onOQVXPAxrNkoBAGZD+UQui9BgJBjY=
44-
github.com/argoproj/argo-cd/v3 v3.3.0 h1:9UlruTd5cC/MyvorTXgAIblfZTy63MF5FYvvoAaUvwU=
45-
github.com/argoproj/argo-cd/v3 v3.3.0/go.mod h1:5VAfe0s/a4VY5GmAIFK76FtW6xn7zAcLmaw25bOL/2g=
42+
github.com/argoproj-labs/argocd-operator v0.17.0-rc1.0.20260304133241-fd7fd59a2b0b h1:HxyuUUBlSPwKWSvLHnCibtR4Yz3Z6qpEm5wSi3a5oIw=
43+
github.com/argoproj-labs/argocd-operator v0.17.0-rc1.0.20260304133241-fd7fd59a2b0b/go.mod h1:J1/kP2zzXbKU5Austr4Eg3qAilMtRyQX8yu0/ALUzD0=
44+
github.com/argoproj/argo-cd/v3 v3.3.2 h1:kVHBj5Z0Wm2D6s69l0q6lC/WH5tc4E1peXgEEOPrLLU=
45+
github.com/argoproj/argo-cd/v3 v3.3.2/go.mod h1:5VAfe0s/a4VY5GmAIFK76FtW6xn7zAcLmaw25bOL/2g=
4646
github.com/argoproj/gitops-engine v0.7.1-0.20251217140045-5baed5604d2d h1:iUJYrbSvpV9n8vyl1sBt1GceM60HhHfnHxuzcm5apDg=
4747
github.com/argoproj/gitops-engine v0.7.1-0.20251217140045-5baed5604d2d/go.mod h1:PauXVUVcfiTgC+34lDdWzPS101g4NpsUtDAjFBnWf94=
4848
github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5 h1:YBoLSjpoaJXaXAldVvBRKJuOPvIXz9UOv6S96gMJM/Q=

test/openshift/e2e/ginkgo/fixture/application/fixture.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package application
22

33
import (
4+
"fmt"
5+
"regexp"
6+
47
. "github.com/onsi/gomega"
58
"github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils"
69
"k8s.io/client-go/util/retry"
@@ -83,6 +86,40 @@ func HaveSyncStatusCode(expected appv1alpha1.SyncStatusCode) matcher.GomegaMatch
8386

8487
}
8588

89+
func HaveNoConditions() matcher.GomegaMatcher {
90+
return expectedCondition(func(app *appv1alpha1.Application) bool {
91+
count := len(app.Status.Conditions)
92+
if count == 0 {
93+
return true
94+
}
95+
96+
GinkgoWriter.Printf("HaveNoConditions - have: %+v\n", app.Status.Conditions)
97+
return false
98+
})
99+
}
100+
101+
func HaveConditionMatching(conditionType appv1alpha1.ApplicationConditionType, messagePattern string) matcher.GomegaMatcher {
102+
pattern := regexp.MustCompile(messagePattern)
103+
104+
return expectedCondition(func(app *appv1alpha1.Application) bool {
105+
conditions := app.Status.Conditions
106+
var found []string
107+
for _, condition := range conditions {
108+
found = append(found, fmt.Sprintf(" - %s/%s", condition.Type, condition.Message))
109+
110+
if condition.Type == conditionType && pattern.MatchString(condition.Message) {
111+
return true
112+
}
113+
}
114+
115+
GinkgoWriter.Printf("HaveConditionMatching - expected: %s/%s; current(%d):\n", conditionType, messagePattern, len(conditions))
116+
for _, f := range found {
117+
GinkgoWriter.Println(f)
118+
}
119+
return false
120+
})
121+
}
122+
86123
// Update will keep trying to update object until it succeeds, or times out.
87124
func Update(obj *appv1alpha1.Application, modify func(*appv1alpha1.Application)) {
88125
k8sClient, _ := utils.GetE2ETestKubeClient()

test/openshift/e2e/ginkgo/fixture/argocd/fixture.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,32 +191,33 @@ func HaveExternalAuthenticationCondition(expected metav1.Condition) matcher.Gome
191191
func HaveCondition(condition metav1.Condition) matcher.GomegaMatcher {
192192
return fetchArgoCD(func(argocd *argov1beta1api.ArgoCD) bool {
193193

194-
if len(argocd.Status.Conditions) != 1 {
195-
GinkgoWriter.Println("HaveCondition: length is zero")
194+
length := len(argocd.Status.Conditions)
195+
if length != 1 {
196+
GinkgoWriter.Printf("HaveCondition: length is %d\n", length)
196197
return false
197198
}
198199

199200
instanceCondition := argocd.Status.Conditions[0]
200201

201-
GinkgoWriter.Println("HaveCondition - Message:", instanceCondition.Message, condition.Message)
202+
GinkgoWriter.Printf("HaveCondition - Message: '%s' / actual: '%s'\n", condition.Message, instanceCondition.Message)
202203
if instanceCondition.Message != condition.Message {
203204
GinkgoWriter.Println("HaveCondition: message does not match")
204205
return false
205206
}
206207

207-
GinkgoWriter.Println("HaveCondition - Reason:", instanceCondition.Reason, condition.Reason)
208+
GinkgoWriter.Printf("HaveCondition - Reason: '%s' / actual: '%s'\n", condition.Reason, instanceCondition.Reason)
208209
if instanceCondition.Reason != condition.Reason {
209210
GinkgoWriter.Println("HaveCondition: reason does not match")
210211
return false
211212
}
212213

213-
GinkgoWriter.Println("HaveCondition - Status:", instanceCondition.Status, condition.Status)
214+
GinkgoWriter.Printf("HaveCondition - Status: '%s' / actual: '%s'\n", condition.Status, instanceCondition.Status)
214215
if instanceCondition.Status != condition.Status {
215216
GinkgoWriter.Println("HaveCondition: status does not match")
216217
return false
217218
}
218219

219-
GinkgoWriter.Println("HaveCondition - Type:", instanceCondition.Type, condition.Type)
220+
GinkgoWriter.Printf("HaveCondition - Type: '%s' / actual: '%s'\n", condition.Type, instanceCondition.Type)
220221
if instanceCondition.Type != condition.Type {
221222
GinkgoWriter.Println("HaveCondition: type does not match")
222223
return false

test/openshift/e2e/ginkgo/fixture/clusterrole/fixture.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package clusterrole
22

33
import (
44
"context"
5+
"reflect"
56

67
. "github.com/onsi/ginkgo/v2"
78
. "github.com/onsi/gomega"
@@ -32,6 +33,13 @@ func Update(obj *rbacv1.ClusterRole, modify func(*rbacv1.ClusterRole)) {
3233

3334
}
3435

36+
func HaveRules(expectedRules []rbacv1.PolicyRule) matcher.GomegaMatcher {
37+
return fetchRole(func(cr *rbacv1.ClusterRole) bool {
38+
GinkgoWriter.Println("HaveRules - Expected:", expectedRules, "/ Actual:", cr.Rules)
39+
return reflect.DeepEqual(expectedRules, cr.Rules)
40+
})
41+
}
42+
3543
// This is intentionally NOT exported, for now. Create another function in this file/package that calls this function, and export that.
3644
//
3745
//nolint:unused

test/openshift/e2e/ginkgo/fixture/k8s/fixture.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,23 @@ func NotHaveLabelWithValue(key string, value string) matcher.GomegaMatcher {
9898
// ExistByName checks if the given k8s resource exists, when retrieving it by name/namespace.
9999
// - It does NOT check if the resource content matches. It only checks that a resource of that type and name exists.
100100
func ExistByName() matcher.GomegaMatcher {
101+
return ExistByNameWithClient(nil)
102+
}
101103

102-
return WithTransform(func(k8sObject client.Object) bool {
103-
k8sClient, _, err := utils.GetE2ETestKubeClientWithError()
104-
if err != nil {
105-
GinkgoWriter.Println(err)
106-
return false
107-
}
104+
// ExistByNameWithClient checks if the given k8s resource exists, when retrieving it by name/namespace.
105+
// - It does NOT check if the resource content matches. It only checks that a resource of that type and name exists.
106+
//
107+
// NOTE: you probably want to instead use ExistByName()
108+
func ExistByNameWithClient(k8sClient client.Client) matcher.GomegaMatcher {
109+
if k8sClient == nil {
110+
var err error
111+
k8sClient, _, err = utils.GetE2ETestKubeClientWithError()
112+
Expect(err).ToNot(HaveOccurred())
113+
Expect(k8sClient).ShouldNot(BeNil())
114+
}
108115

109-
err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(k8sObject), k8sObject)
116+
return WithTransform(func(k8sObject client.Object) bool {
117+
err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(k8sObject), k8sObject)
110118
if err != nil {
111119
GinkgoWriter.Println("Object does not exists in ExistByName:", k8sObject.GetName(), err)
112120
} else {

test/openshift/e2e/ginkgo/parallel/1-031_validate_toolchain_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ var _ = Describe("GitOps Operator Parallel E2E Tests", func() {
8585
It("verifies that toolchain versions have the expected values", func() {
8686

8787
// These variables need to be maintained according to the component matrix: https://spaces.redhat.com/display/GITOPS/GitOps+Component+Matrix
88-
expected_kustomizeVersion := "v5.8.0"
88+
expected_kustomizeVersion := "v5.8.1"
8989
expected_helmVersion := "v3.19.4"
90-
expected_argocdVersion := "v3.3.0"
90+
expected_argocdVersion := "v3.3.2"
9191

9292
var expected_dexVersion string
9393
var expected_redisVersion string

0 commit comments

Comments
 (0)