Skip to content

Commit 1eed549

Browse files
committed
fixup
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
1 parent c86e99f commit 1eed549

File tree

4 files changed

+141
-5
lines changed

4 files changed

+141
-5
lines changed

controllers/usernamespace/pvc2sync_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2019-20255 Red Hat, Inc.
2+
// Copyright (c) 2019-2025 Red Hat, Inc.
33
// This program and the accompanying materials are made
44
// available under the terms of the Eclipse Public License 2.0
55
// which is available at https://www.eclipse.org/legal/epl-2.0/

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ma//
1+
//
22
// Copyright (c) 2019-2025 Red Hat, Inc.
33
// This program and the accompanying materials are made
44
// available under the terms of the Eclipse Public License 2.0
Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@
1010
// Red Hat, Inc. - initial API and implementation
1111
//
1212

13-
package utils
13+
package sync
1414

1515
import (
1616
"context"
1717
"fmt"
1818
"reflect"
1919

20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
"k8s.io/apimachinery/pkg/types"
22+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
23+
2024
ctrl "sigs.k8s.io/controller-runtime"
2125

2226
"k8s.io/apimachinery/pkg/api/errors"
@@ -29,29 +33,74 @@ var (
2933
)
3034

3135
type Syncer interface {
36+
// Create creates object.
37+
// Return true if a new object is created, otherwise returns false.
38+
// Returns error if object cannot be created otherwise returns nil.
39+
Create(context context.Context, blueprint client.Object, owner metav1.Object) (bool, error)
40+
// CreateIgnoreIfExists creates object.
41+
// Return true if a new object is created or object already exists, otherwise returns false.
42+
// Returns error if object cannot be created otherwise returns nil.
43+
CreateIgnoreIfExists(context context.Context, blueprint client.Object, owner metav1.Object) (bool, error)
3244
// Get gets object.
3345
// Returns true if object exists otherwise returns false.
3446
// Returns error if object cannot be retrieved otherwise returns nil.
35-
Get(key client.ObjectKey, objectMeta client.Object) (bool, error)
36-
// Delete does delete object by key.
47+
Get(context context.Context, key client.ObjectKey, objectMeta client.Object) (bool, error)
48+
// GetClusterScoped gets cluster scoped object by name
49+
// Returns true if object exists otherwise returns false.
50+
// Returns error if object cannot be retrieved otherwise returns nil.
51+
GetClusterScoped(context context.Context, name string, objectMeta client.Object) (bool, error)
52+
// Delete deletes object by key.
3753
// Returns true if object deleted or not found otherwise returns false.
3854
// Returns error if object cannot be deleted otherwise returns nil.
3955
Delete(context context.Context, key client.ObjectKey, objectMeta client.Object) (bool, error)
56+
// DeleteClusterClusterScoped deletes cluster scoped object by name.
57+
// Returns true if object deleted or not found otherwise returns false.
58+
// Returns error if object cannot be deleted otherwise returns nil.
59+
DeleteClusterClusterScoped(context context.Context, name string, objectMeta client.Object) (bool, error)
4060
}
4161

4262
type ObjSyncer struct {
4363
syncer Syncer
4464
cli client.Client
65+
scheme *runtime.Scheme
66+
}
67+
68+
func (s ObjSyncer) Create(context context.Context, blueprint client.Object, owner metav1.Object) (bool, error) {
69+
if owner != nil {
70+
if err := controllerutil.SetControllerReference(owner, blueprint, s.scheme); err != nil {
71+
return false, fmt.Errorf("failed to set controller reference: %w", err)
72+
}
73+
}
74+
75+
return s.doCreate(context, blueprint, false)
76+
}
77+
78+
func (s ObjSyncer) CreateIgnoreIfExists(context context.Context, blueprint client.Object, owner metav1.Object) (bool, error) {
79+
if owner != nil {
80+
if err := controllerutil.SetControllerReference(owner, blueprint, s.scheme); err != nil {
81+
return false, fmt.Errorf("failed to set controller reference: %w", err)
82+
}
83+
}
84+
85+
return s.doCreate(context, blueprint, true)
4586
}
4687

4788
func (s ObjSyncer) Get(context context.Context, key client.ObjectKey, objectMeta client.Object) (bool, error) {
4889
return s.doGetIgnoreNotFound(context, key, objectMeta)
4990
}
5091

92+
func (s ObjSyncer) GetClusterScoped(context context.Context, name string, objectMeta client.Object) (bool, error) {
93+
return s.doGetIgnoreNotFound(context, types.NamespacedName{Name: name}, objectMeta)
94+
}
95+
5196
func (s ObjSyncer) Delete(context context.Context, key client.ObjectKey, objectMeta client.Object) (bool, error) {
5297
return s.deleteByKeyIgnoreNotFound(context, key, objectMeta)
5398
}
5499

100+
func (s ObjSyncer) DeleteClusterClusterScoped(context context.Context, name string, objectMeta client.Object) (bool, error) {
101+
return s.deleteByKeyIgnoreNotFound(context, types.NamespacedName{Name: name}, objectMeta)
102+
}
103+
55104
// deleteByKeyIgnoreNotFound deletes object by key.
56105
// Returns true if object deleted or not found otherwise returns false.
57106
// Returns error if object cannot be deleted otherwise returns nil.
@@ -107,6 +156,29 @@ func (s ObjSyncer) doGetIgnoreNotFound(
107156
}
108157
}
109158

159+
// doCreate creates object.
160+
// Returns true if object created or already exists otherwise returns false.
161+
// Return error if object cannot be created otherwise returns nil.
162+
func (s ObjSyncer) doCreate(
163+
context context.Context,
164+
blueprint client.Object,
165+
ignoreIfAlreadyExists bool,
166+
) (bool, error) {
167+
if err := s.cli.Create(context, blueprint); err == nil {
168+
syncLog.Info("Object created", "namespace", blueprint.GetNamespace(), "kind", GetObjectType(blueprint), "name", blueprint.GetName())
169+
return true, nil
170+
} else if errors.IsAlreadyExists(err) {
171+
if ignoreIfAlreadyExists {
172+
syncLog.Info("Object already exists, ignoring", "namespace", blueprint.GetNamespace(), "kind", GetObjectType(blueprint), "name", blueprint.GetName())
173+
return true, nil
174+
} else {
175+
return false, err
176+
}
177+
} else {
178+
return false, err
179+
}
180+
}
181+
110182
func GetObjectType(obj interface{}) string {
111183
objType := reflect.TypeOf(obj).String()
112184
if reflect.TypeOf(obj).Kind().String() == "ptr" {

pkg/common/sync/sync_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// Copyright (c) 2019-2025 Red Hat, Inc.
3+
// This program and the accompanying materials are made
4+
// available under the terms of the Eclipse Public License 2.0
5+
// which is available at https://www.eclipse.org/legal/epl-2.0/
6+
//
7+
// SPDX-License-Identifier: EPL-2.0
8+
//
9+
// Contributors:
10+
// Red Hat, Inc. - initial API and implementation
11+
//
12+
13+
package sync
14+
15+
import (
16+
"context"
17+
18+
"github.com/eclipse-che/che-operator/pkg/common/test"
19+
"github.com/stretchr/testify/assert"
20+
"k8s.io/apimachinery/pkg/runtime"
21+
"k8s.io/apimachinery/pkg/types"
22+
23+
"testing"
24+
25+
corev1 "k8s.io/api/core/v1"
26+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
)
28+
29+
func TestGetExistedObject(t *testing.T) {
30+
ctx := test.GetDeployContext(nil, []runtime.Object{
31+
&corev1.ConfigMap{
32+
TypeMeta: metav1.TypeMeta{
33+
Kind: "ConfigMap",
34+
APIVersion: "v1",
35+
},
36+
ObjectMeta: metav1.ObjectMeta{
37+
Name: "test",
38+
Namespace: "eclipse-che",
39+
},
40+
},
41+
})
42+
syncer := ObjSyncer{
43+
cli: ctx.ClusterAPI.Client,
44+
scheme: ctx.ClusterAPI.Scheme,
45+
}
46+
47+
cm := &corev1.ConfigMap{}
48+
exists, err := syncer.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, cm)
49+
assert.NoError(t, err)
50+
assert.True(t, exists)
51+
}
52+
53+
func TestGetNotExistedObject(t *testing.T) {
54+
ctx := test.GetDeployContext(nil, []runtime.Object{})
55+
syncer := ObjSyncer{
56+
cli: ctx.ClusterAPI.Client,
57+
scheme: ctx.ClusterAPI.Scheme,
58+
}
59+
60+
cm := &corev1.ConfigMap{}
61+
exists, err := syncer.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, cm)
62+
assert.NoError(t, err)
63+
assert.False(t, exists)
64+
}

0 commit comments

Comments
 (0)