Skip to content

Commit 0b6d495

Browse files
author
Moritz Clasmeier
committed
Merge branch 'main' into backup/mc/new-config-2
2 parents f154aa4 + 3c34a42 commit 0b6d495

8 files changed

Lines changed: 104 additions & 54 deletions

File tree

cmd/deploy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ func deployValidate(components component.Component, deploySettings *deployer.Con
534534
return errors.New("using Konflux images while deploying operator via OLM is not supported")
535535
}
536536
clusterType := env.GetCurrentClusterType()
537-
if clusterType != types.ClusterTypeInfraOpenShift4 {
537+
if !clusterType.IsOpenShift() {
538538
return fmt.Errorf("--konflux flag is only supported on OpenShift 4 clusters (current cluster type: %s)", clusterType.String())
539539
}
540540
}

internal/deployer/deploy_via_operator.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ func (d *Deployer) ensureOperatorDeployed(ctx context.Context) error {
5656
}
5757

5858
// Detect current operator deployment mode
59-
operatorExists, currentMode := d.detectOperatorDeploymentMode(ctx)
59+
operatorExists, currentMode, err := d.detectOperatorDeploymentMode(ctx)
60+
if err != nil {
61+
return fmt.Errorf("detecting operator deployment mode: %w", err)
62+
}
6063
needsDeployment := false
6164
needsTeardown := false
6265

internal/deployer/operator.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"github.com/stackrox/roxie/internal/env"
1818
"github.com/stackrox/roxie/internal/k8s"
1919
"github.com/stackrox/roxie/internal/ocihelper"
20-
"github.com/stackrox/roxie/internal/types"
2120
)
2221

2322
const (
@@ -202,7 +201,7 @@ func (d *Deployer) getOperatorBundleImage() string {
202201

203202
// ensureKonfluxImageRewriting configures image rewriting for Konflux images
204203
func (d *Deployer) ensureKonfluxImageRewriting(ctx context.Context) error {
205-
if env.GetCurrentClusterType() != types.ClusterTypeInfraOpenShift4 {
204+
if !env.GetCurrentClusterType().IsOpenShift() {
206205
return errors.New("image rewriting for Konflux is only supported on OpenShift4 clusters")
207206
}
208207

@@ -290,7 +289,7 @@ func (d *Deployer) applyImageContentSourcePolicy(ctx context.Context) error {
290289

291290
// removeKonfluxImageRewriting removes the ImageContentSourcePolicy for Konflux images if it exists
292291
func (d *Deployer) removeKonfluxImageRewriting(ctx context.Context) error {
293-
if env.GetCurrentClusterType() != types.ClusterTypeInfraOpenShift4 {
292+
if !env.GetCurrentClusterType().IsOpenShift() {
294293
return nil
295294
}
296295

@@ -643,7 +642,10 @@ func (d *Deployer) teardownOperatorNonOLM(ctx context.Context) error {
643642

644643
// teardownOperator removes the operator if it exists, detecting the deployment mode automatically.
645644
func (d *Deployer) teardownOperator(ctx context.Context) error {
646-
operatorExists, operatorMode := d.detectOperatorDeploymentMode(ctx)
645+
operatorExists, operatorMode, err := d.detectOperatorDeploymentMode(ctx)
646+
if err != nil {
647+
return fmt.Errorf("detecting operator deployment mode: %w", err)
648+
}
647649
if !operatorExists {
648650
d.logger.Dim("No operator deployment found, skipping operator teardown")
649651
return nil

internal/deployer/operator_olm.go

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -335,35 +335,34 @@ func (d *Deployer) waitForCSVSuccess(ctx context.Context) error {
335335

336336
// detectOperatorDeploymentMode detects how the operator is currently deployed.
337337
// Returns (operatorExists bool, isOLM OperatorDeploymentMode)
338-
func (d *Deployer) detectOperatorDeploymentMode(ctx context.Context) (bool, OperatorDeploymentMode) {
338+
func (d *Deployer) detectOperatorDeploymentMode(ctx context.Context) (bool, OperatorDeploymentMode, error) {
339+
const olmOwnerLabel = "olm.owner"
340+
339341
// First, check if a Subscription exists (OLM-specific resource)
340342
_, err := d.runKubectl(ctx, k8s.KubectlOptions{
341343
Args: []string{"get", "subscription", subscriptionName, "-n", operatorNamespace},
342344
})
343345
if err == nil {
344-
return true, OperatorModeOLM
346+
return true, OperatorModeOLM, nil
345347
}
346348

347-
// If no subscription, check if operator deployment exists.
348-
_, err = d.runKubectl(ctx, k8s.KubectlOptions{
349-
Args: []string{"get", "deployment", operatorDeploymentName, "-n", operatorNamespace},
350-
})
351-
if err == nil {
352-
// Deployment exists - check if it has OLM owner labels.
353-
result, err := d.runKubectl(ctx, k8s.KubectlOptions{
354-
Args: []string{"get", "deployment", operatorDeploymentName, "-n", operatorNamespace, "-o", "jsonpath={.metadata.labels}"},
355-
})
356-
// TODO(ROX-34499): This is not very robust. Better retrieve a specific label in the `get`
357-
// command?
358-
if err == nil && strings.Contains(result.Stdout, "olm.owner") {
359-
return true, OperatorModeOLM
360-
}
361-
// Deployment exists without OLM labels = non-OLM deployment.
362-
return true, OperatorModeNonOLM
349+
// If no subscription, check if operator deployment exists/if it has the expected OLM label.
350+
labelValue, err := k8s.RetrieveClusterResourceLabel(ctx, d.logger, operatorNamespace, "deployment", operatorDeploymentName, olmOwnerLabel)
351+
if k8s.IsResourceNotFound(err) {
352+
// No operator deployment found.
353+
return false, OperatorModeNonOLM, nil
354+
}
355+
if err != nil {
356+
return false, OperatorModeNonOLM, err
357+
}
358+
359+
if labelValue == "" {
360+
// Deployment exists without OLM labels -> non-OLM deployment.
361+
return true, OperatorModeNonOLM, nil
363362
}
364363

365-
// No operator found.
366-
return false, OperatorModeNonOLM
364+
// Label set -> OLM deployment.
365+
return true, OperatorModeOLM, nil
367366
}
368367

369368
// teardownOperatorOLM removes the operator when installed via OLM.

internal/env/env.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -147,22 +147,12 @@ func DetectClusterType(config KubeConfig, apiResources []string) types.ClusterTy
147147
return types.ClusterTypeInfraGKE
148148
}
149149

150-
// Minikube clusters typically have context name "minikube".
151-
if contextLower == "minikube" || strings.HasPrefix(contextLower, "minikube-") {
152-
return types.ClusterTypeMinikube
153-
}
154-
155-
// Check for OpenShift 4 clusters by examining the server hostname.
156-
if serverURL := getServerURL(config); serverURL != "" {
157-
if parsedURL, err := url.Parse(serverURL); err == nil {
158-
hostname := parsedURL.Hostname()
159-
if strings.HasSuffix(hostname, ".ocp.infra.rox.systems") {
160-
// Further verify it's OpenShift 4 by checking the API resources
161-
if isOpenShift4(apiResources) {
162-
return types.ClusterTypeInfraOpenShift4
163-
}
164-
}
150+
// Check for OpenShift 4 clusters.
151+
if isOpenShift4(apiResources) {
152+
if isInfraOpenShift4(config) {
153+
return types.ClusterTypeInfraOpenShift4
165154
}
155+
return types.ClusterTypeOpenShift4
166156
}
167157

168158
// K3s clusters often have "k3s" in the context name
@@ -184,6 +174,19 @@ func DetectClusterType(config KubeConfig, apiResources []string) types.ClusterTy
184174
return types.ClusterTypeUnknown
185175
}
186176

177+
func isInfraOpenShift4(config KubeConfig) bool {
178+
serverURL := getServerURL(config)
179+
if serverURL == "" {
180+
return false
181+
}
182+
parsedURL, err := url.Parse(serverURL)
183+
if err != nil {
184+
return false
185+
}
186+
hostname := parsedURL.Hostname()
187+
return strings.HasSuffix(hostname, ".ocp.infra.rox.systems")
188+
}
189+
187190
// getServerURL retrieves the server URL from the KubeConfig
188191
func getServerURL(config KubeConfig) string {
189192
if len(config.Clusters) == 0 {

internal/env/env_test.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package env
33
import (
44
"testing"
55

6+
"github.com/stretchr/testify/assert"
7+
68
"github.com/stackrox/roxie/internal/types"
79
)
810

@@ -42,7 +44,7 @@ func TestDetectClusterType_GKE_ExactMatch(t *testing.T) {
4244
}
4345
}
4446

45-
func TestDetectClusterType_OpenShift4(t *testing.T) {
47+
func TestDetectClusterType_InfraOpenShift4(t *testing.T) {
4648
config := KubeConfig{
4749
CurrentContext: "admin",
4850
Clusters: []KubeCluster{
@@ -60,31 +62,28 @@ func TestDetectClusterType_OpenShift4(t *testing.T) {
6062
}
6163

6264
result := DetectClusterType(config, apiResources)
63-
if result != types.ClusterTypeInfraOpenShift4 {
64-
t.Errorf("DetectClusterType() = %v (%s), want %v", result, result.String(), types.ClusterTypeInfraOpenShift4)
65-
}
65+
assert.Equal(t, types.ClusterTypeInfraOpenShift4, result)
6666
}
6767

68-
func TestDetectClusterType_OpenShift4_WrongHostname(t *testing.T) {
68+
func TestDetectClusterType_OpenShift4(t *testing.T) {
6969
config := KubeConfig{
70-
CurrentContext: "admin",
70+
CurrentContext: "some-context-name",
7171
Clusters: []KubeCluster{
7272
{
73-
Name: "openshift-cluster",
74-
Server: "https://api.my-cluster.example.com:6443",
73+
Name: "some-other-name",
74+
Server: "https://my-cluster.example.com:6443",
7575
},
7676
},
7777
}
7878
apiResources := []string{
7979
"pods",
8080
"services",
8181
"clusterversions.config.openshift.io",
82+
"clusteroperators.config.openshift.io",
8283
}
8384

8485
result := DetectClusterType(config, apiResources)
85-
if result != types.ClusterTypeUnknown {
86-
t.Errorf("DetectClusterType() = %v (%s), want %v", result, result.String(), types.ClusterTypeUnknown)
87-
}
86+
assert.Equal(t, types.ClusterTypeOpenShift4, result)
8887
}
8988

9089
func TestDetectClusterType_OpenShift4_NoAPIResources(t *testing.T) {
@@ -295,8 +294,13 @@ func TestClusterTypeString(t *testing.T) {
295294
want: "GKE",
296295
},
297296
{
298-
name: "types.ClusterTypeInfraOpenShift4",
297+
name: "InfraOpenShift4",
299298
clusterType: types.ClusterTypeInfraOpenShift4,
299+
want: "OpenShift4 (infra)",
300+
},
301+
{
302+
name: "OpenShift4",
303+
clusterType: types.ClusterTypeOpenShift4,
300304
want: "OpenShift4",
301305
},
302306
{

internal/k8s/resource.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func RetrieveResourceFromCluster(ctx context.Context, log *logger.Logger, namesp
6464

6565
// IsResourceNotFound checks if an error is a resource not found error.
6666
func IsResourceNotFound(err error) bool {
67-
return err == ErrResourceNotFound
67+
return errors.Is(err, ErrResourceNotFound)
6868
}
6969

7070
// ResourceNotOwnedByName checks if the given unstructured object does not have an owner reference with the specified owner name.
@@ -80,3 +80,33 @@ func ResourceNotOwnedByName(obj *unstructured.Unstructured, ownerName string) bo
8080
}
8181
return true
8282
}
83+
84+
// RetrieveClusterResourceLabel retrieves the specified label from a Kubernetes resource from the cluster.
85+
//
86+
// Parameters: Same as for RetrieveResourceFromCluster, plus
87+
// - label: The label to retrieve.
88+
//
89+
// Returns:
90+
// - string: the label value -- if the label is not found, an empty string is returned without error.
91+
// - error: nil if successful, error otherwise (including ErrResourceNotFound for not found resources)
92+
func RetrieveClusterResourceLabel(ctx context.Context, log *logger.Logger, namespace, resourceType, resourceName, label string) (string, error) {
93+
u, err := RetrieveResourceFromCluster(ctx, log, namespace, resourceType, resourceName)
94+
if err != nil {
95+
return "", fmt.Errorf("retrieving resource %s/%s from namespace %s: %w", resourceType, resourceName, namespace, err)
96+
}
97+
98+
val, found, err := unstructured.NestedFieldCopy(u.Object, "metadata", "labels", label)
99+
if err != nil {
100+
return "", fmt.Errorf("extracting label value: %w", err)
101+
}
102+
if !found {
103+
return "", nil
104+
}
105+
106+
valStr, ok := val.(string)
107+
if !ok {
108+
return "", fmt.Errorf("unexpected type for label %q (%T)", label, val)
109+
}
110+
111+
return valStr, nil
112+
}

internal/types/cluster_type.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const (
1010
ClusterTypeInfraGKE
1111
// ClusterTypeInfraOpenShift4 represents an OpenShift 4 cluster
1212
ClusterTypeInfraOpenShift4
13+
// Generic OpenShift4 cluster (e.g. for prow CI)
14+
ClusterTypeOpenShift4
1315
// ClusterTypeKind represents a Kind (Kubernetes in Docker) cluster
1416
ClusterTypeKind
1517
// ClusterTypeMinikube represents a Minikube cluster
@@ -20,12 +22,18 @@ const (
2022
ClusterTypeCRC
2123
)
2224

25+
func (ct ClusterType) IsOpenShift() bool {
26+
return ct == ClusterTypeInfraOpenShift4 || ct == ClusterTypeOpenShift4
27+
}
28+
2329
// String returns the string representation of a ClusterType
2430
func (ct ClusterType) String() string {
2531
switch ct {
2632
case ClusterTypeInfraGKE:
2733
return "GKE"
2834
case ClusterTypeInfraOpenShift4:
35+
return "OpenShift4 (infra)"
36+
case ClusterTypeOpenShift4:
2937
return "OpenShift4"
3038
case ClusterTypeKind:
3139
return "Kind"
@@ -48,5 +56,6 @@ func AllClusterTypes() []ClusterType {
4856
ClusterTypeK3s,
4957
ClusterTypeCRC,
5058
ClusterTypeInfraOpenShift4,
59+
ClusterTypeOpenShift4,
5160
}
5261
}

0 commit comments

Comments
 (0)