Skip to content

Commit d87661f

Browse files
authored
Merge pull request #1 from sttts/sttts-kcp-0.17.move.tests
Cleanup
2 parents e71e393 + 8616d54 commit d87661f

File tree

7 files changed

+149
-207
lines changed

7 files changed

+149
-207
lines changed

examples/kcp/config/main.go

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"os"
21+
2022
kcpclienthelper "github.com/kcp-dev/apimachinery/v2/pkg/client"
2123
apisv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/apis/v1alpha1"
2224
"github.com/kcp-dev/kcp/sdk/apis/core"
2325
corev1alpha1 "github.com/kcp-dev/kcp/sdk/apis/core/v1alpha1"
2426
tenancyv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/tenancy/v1alpha1"
2527
"github.com/kcp-dev/logicalcluster/v3"
26-
"k8s.io/apimachinery/pkg/runtime"
2728
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2829
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
2930
"k8s.io/client-go/rest"
@@ -34,8 +35,8 @@ import (
3435

3536
"github.com/kcp-dev/controller-runtime/examples/kcp/config/consumers"
3637
"github.com/kcp-dev/controller-runtime/examples/kcp/config/widgets"
37-
"github.com/kcp-dev/controller-runtime/examples/kcp/config/widgets/resources"
38-
"sigs.k8s.io/controller-runtime/pkg/log"
38+
widgetresources "github.com/kcp-dev/controller-runtime/examples/kcp/config/widgets/resources"
39+
ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
3940
)
4041

4142
// config is bootstrap set of assets for the controller-runtime examples.
@@ -49,16 +50,11 @@ import (
4950
// done by the platform operator to enable service providers to deploy their
5051
// controllers.
5152

52-
var (
53-
scheme = runtime.NewScheme()
54-
)
55-
5653
func init() {
57-
utilruntime.Must(tenancyv1alpha1.AddToScheme(scheme))
58-
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
59-
utilruntime.Must(corev1alpha1.AddToScheme(scheme))
60-
utilruntime.Must(apisv1alpha1.AddToScheme(scheme))
61-
54+
utilruntime.Must(tenancyv1alpha1.AddToScheme(clientgoscheme.Scheme))
55+
utilruntime.Must(clientgoscheme.AddToScheme(clientgoscheme.Scheme))
56+
utilruntime.Must(corev1alpha1.AddToScheme(clientgoscheme.Scheme))
57+
utilruntime.Must(apisv1alpha1.AddToScheme(clientgoscheme.Scheme))
6258
}
6359

6460
var (
@@ -73,44 +69,45 @@ func main() {
7369
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
7470

7571
ctx := ctrl.SetupSignalHandler()
76-
log := log.FromContext(ctx)
72+
log := ctrllog.FromContext(ctx)
7773

7874
restConfig, err := config.GetConfigWithContext("base")
7975
if err != nil {
8076
log.Error(err, "unable to get config")
77+
os.Exit(1)
8178
}
8279

8380
restCopy := rest.CopyConfig(restConfig)
8481
restRoot := rest.AddUserAgent(kcpclienthelper.SetCluster(restCopy, core.RootCluster.Path()), "bootstrap-root")
85-
clientRoot, err := client.New(restRoot, client.Options{
86-
Scheme: scheme,
87-
})
82+
rootClient, err := client.New(restRoot, client.Options{})
8883
if err != nil {
8984
log.Error(err, "unable to create client")
85+
os.Exit(1)
9086
}
9187

9288
restCopy = rest.CopyConfig(restConfig)
9389
restWidgets := rest.AddUserAgent(kcpclienthelper.SetCluster(restCopy, clusterName), "bootstrap-widgets")
94-
clientWidgets, err := client.New(restWidgets, client.Options{
95-
Scheme: scheme,
96-
})
90+
widgetsClient, err := client.New(restWidgets, client.Options{})
9791
if err != nil {
9892
log.Error(err, "unable to create client")
93+
os.Exit(1)
9994
}
10095

101-
err = widgets.Bootstrap(ctx, clientRoot)
96+
err = widgets.Bootstrap(ctx, rootClient)
10297
if err != nil {
10398
log.Error(err, "failed to bootstrap widgets")
99+
os.Exit(1)
104100
}
105101

106-
err = resources.Bootstrap(ctx, clientWidgets)
102+
err = widgetresources.Bootstrap(ctx, widgetsClient)
107103
if err != nil {
108104
log.Error(err, "failed to bootstrap resources")
105+
os.Exit(1)
109106
}
110107

111-
err = consumers.Bootstrap(ctx, clientRoot)
108+
err = consumers.Bootstrap(ctx, rootClient)
112109
if err != nil {
113110
log.Error(err, "failed to bootstrap consumers")
111+
os.Exit(1)
114112
}
115-
116113
}

examples/kcp/controllers/configmap_controller.go renamed to examples/kcp/controllers/configmap/reconciler.go

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package controllers
17+
package configmap
1818

1919
import (
2020
"context"
2121
"fmt"
22-
"time"
2322

2423
corev1 "k8s.io/api/core/v1"
2524
apierrors "k8s.io/apimachinery/pkg/api/errors"
2625
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726
"k8s.io/apimachinery/pkg/types"
27+
"sigs.k8s.io/controller-runtime/pkg/kcp"
2828

2929
ctrl "sigs.k8s.io/controller-runtime"
3030
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -33,68 +33,63 @@ import (
3333
"sigs.k8s.io/controller-runtime/pkg/log"
3434
)
3535

36-
type ConfigMapReconciler struct {
37-
client.Client
36+
type Reconciler struct {
37+
Client client.Client
3838
}
3939

40-
func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
40+
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
4141
log := log.FromContext(ctx).WithValues("cluster", req.ClusterName)
4242

4343
// Test get
44-
var configMap corev1.ConfigMap
45-
if err := r.Client.Get(ctx, req.NamespacedName, &configMap); err != nil {
44+
var cm corev1.ConfigMap
45+
if err := r.Client.Get(ctx, req.NamespacedName, &cm); err != nil {
4646
log.Error(err, "unable to get configmap")
4747
return ctrl.Result{}, nil
4848
}
4949

5050
log.Info("Get: retrieved configMap")
51-
labels := configMap.Labels
51+
if cm.Labels["name"] != "" {
52+
response := fmt.Sprintf("hello-%s", cm.Labels["name"])
5253

53-
if labels["name"] != "" {
54-
response := fmt.Sprintf("hello-%s", labels["name"])
55-
56-
if labels["response"] != response {
57-
labels["response"] = response
54+
if cm.Labels["response"] != response {
55+
cm.Labels["response"] = response
5856

5957
// Test Update
60-
if err := r.Client.Update(ctx, &configMap); err != nil {
58+
if err := r.Client.Update(ctx, &cm); err != nil {
6159
return ctrl.Result{}, err
6260
}
61+
6362
log.Info("Update: updated configMap")
6463
return ctrl.Result{}, nil
6564
}
6665
}
6766

6867
// Test list
69-
var configMapList corev1.ConfigMapList
70-
if err := r.Client.List(ctx, &configMapList); err != nil {
68+
var cms corev1.ConfigMapList
69+
if err := r.Client.List(ctx, &cms); err != nil {
7170
log.Error(err, "unable to list configmaps")
7271
return ctrl.Result{}, nil
7372
}
74-
log.Info("List: got", "itemCount", len(configMapList.Items))
73+
log.Info("List: got", "itemCount", len(cms.Items))
7574
found := false
76-
for _, cm := range configMapList.Items {
75+
for _, other := range cms.Items {
7776
cluster, ok := kontext.ClusterFrom(ctx)
7877
if !ok {
79-
log.Info("List: got", "clusterName", cluster.String(), "namespace", cm.Namespace, "name", cm.Name)
80-
} else {
81-
if cm.Name == configMap.Name && cm.Namespace == configMap.Namespace {
82-
if found {
83-
return ctrl.Result{}, fmt.Errorf("there should be listed only one configmap with the given name '%s' for the given namespace '%s' when the clusterName is not available", cm.Name, cm.Namespace)
84-
}
85-
found = true
86-
log.Info("Found in listed configmaps", "namespace", cm.Namespace, "name", cm.Name)
78+
log.Info("List: got", "clusterName", cluster.String(), "namespace", other.Namespace, "name", other.Name)
79+
} else if other.Name == cm.Name && other.Namespace == cm.Namespace {
80+
if found {
81+
return ctrl.Result{}, fmt.Errorf("there should be listed only one configmap with the given name '%s' for the given namespace '%s' when the clusterName is not available", cm.Name, cm.Namespace)
8782
}
83+
found = true
84+
log.Info("Found in listed configmaps", "namespace", cm.Namespace, "name", cm.Name)
8885
}
8986
}
9087

9188
// If the configmap has a namespace field, create the corresponding namespace
92-
nsName, exists := configMap.Data["namespace"]
89+
nsName, exists := cm.Data["namespace"]
9390
if exists {
9491
var namespace corev1.Namespace
95-
nsKey := types.NamespacedName{Name: nsName}
96-
97-
if err := r.Client.Get(ctx, nsKey, &namespace); err != nil {
92+
if err := r.Client.Get(ctx, types.NamespacedName{Name: nsName}, &namespace); err != nil {
9893
if !apierrors.IsNotFound(err) {
9994
log.Error(err, "unable to get namespace")
10095
return ctrl.Result{}, err
@@ -107,29 +102,28 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
107102
return ctrl.Result{}, err
108103
}
109104
log.Info("Create: created ", "namespace", nsName)
110-
return ctrl.Result{RequeueAfter: time.Second * 5}, nil
105+
return ctrl.Result{Requeue: true}, nil
111106
}
112107
log.Info("Exists", "namespace", nsName)
113108
}
114109

115110
// If the configmap has a secretData field, create a secret in the same namespace
116111
// If the secret already exists but is out of sync, it will be non-destructively patched
117-
secretData, exists := configMap.Data["secretData"]
112+
secretData, exists := cm.Data["secretData"]
118113
if exists {
119114
var secret corev1.Secret
120-
121-
secret.SetName(configMap.GetName())
122-
secret.SetNamespace(configMap.GetNamespace())
123-
secret.SetOwnerReferences([]metav1.OwnerReference{metav1.OwnerReference{
124-
Name: configMap.GetName(),
125-
UID: configMap.GetUID(),
115+
secret.SetName(cm.GetName())
116+
secret.SetNamespace(cm.GetNamespace())
117+
secret.SetOwnerReferences([]metav1.OwnerReference{{
118+
Name: cm.GetName(),
119+
UID: cm.GetUID(),
126120
APIVersion: "v1",
127121
Kind: "ConfigMap",
128122
Controller: func() *bool { x := true; return &x }(),
129123
}})
130124
secret.Data = map[string][]byte{"dataFromCM": []byte(secretData)}
131125

132-
operationResult, err := controllerutil.CreateOrPatch(ctx, r, &secret, func() error {
126+
operationResult, err := controllerutil.CreateOrPatch(ctx, r.Client, &secret, func() error {
133127
secret.Data["dataFromCM"] = []byte(secretData)
134128
return nil
135129
})
@@ -143,9 +137,9 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
143137
return ctrl.Result{}, nil
144138
}
145139

146-
func (r *ConfigMapReconciler) SetupWithManager(mgr ctrl.Manager) error {
140+
func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
147141
return ctrl.NewControllerManagedBy(mgr).
148142
For(&corev1.ConfigMap{}).
149143
Owns(&corev1.Secret{}).
150-
Complete(WithClusterInContext(r))
144+
Complete(kcp.WithClusterInContext(r))
151145
}

examples/kcp/controllers/widget_controller.go renamed to examples/kcp/controllers/widget/reconciler.go

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,81 +14,70 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package controllers
17+
package widget
1818

1919
import (
2020
"context"
2121

2222
"k8s.io/apimachinery/pkg/api/errors"
23-
"k8s.io/apimachinery/pkg/runtime"
2423
ctrl "sigs.k8s.io/controller-runtime"
2524
"sigs.k8s.io/controller-runtime/pkg/client"
25+
"sigs.k8s.io/controller-runtime/pkg/kcp"
2626
"sigs.k8s.io/controller-runtime/pkg/log"
2727

2828
datav1alpha1 "github.com/kcp-dev/controller-runtime/examples/kcp/apis/v1alpha1"
2929
)
3030

31-
// WidgetReconciler reconciles a Widget object
32-
type WidgetReconciler struct {
33-
client.Client
34-
Scheme *runtime.Scheme
31+
// Reconciler reconciles a Widget object
32+
type Reconciler struct {
33+
Client client.Client
3534
}
3635

3736
// Reconcile TODO
38-
func (r *WidgetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
39-
logger := log.FromContext(ctx)
37+
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
38+
log := log.FromContext(ctx)
4039

4140
// Include the clusterName from req.ObjectKey in the logger, similar to the namespace and name keys that are already
4241
// there.
43-
logger = logger.WithValues("clusterName", req.ClusterName)
42+
log = log.WithValues("clusterName", req.ClusterName)
4443

4544
// You probably wouldn't need to do this, but if you wanted to list all instances across all logical clusters:
4645
var allWidgets datav1alpha1.WidgetList
4746
if err := r.Client.List(ctx, &allWidgets); err != nil {
4847
return ctrl.Result{}, err
4948
}
5049

51-
logger.Info("Listed all widgets across all workspaces", "count", len(allWidgets.Items))
50+
log.Info("Listed all widgets across all workspaces", "count", len(allWidgets.Items))
5251

53-
logger.Info("Getting widget")
52+
log.Info("Getting widget")
5453
var w datav1alpha1.Widget
5554
if err := r.Client.Get(ctx, req.NamespacedName, &w); err != nil {
5655
if errors.IsNotFound(err) {
5756
// Normal - was deleted
5857
return ctrl.Result{}, nil
5958
}
60-
6159
return ctrl.Result{}, err
6260
}
6361

64-
logger.Info("Listing all widgets in the current logical cluster")
62+
log.Info("Listing all widgets in the current logical cluster")
6563
var list datav1alpha1.WidgetList
6664
if err := r.Client.List(ctx, &list); err != nil {
6765
return ctrl.Result{}, err
6866
}
6967

70-
numWidgets := len(list.Items)
71-
if numWidgets == w.Status.Total {
72-
logger.Info("No need to patch because the widget status is already correct")
73-
return ctrl.Result{}, nil
74-
}
75-
76-
logger.Info("Patching widget status to store total widget count in the current logical cluster")
77-
original := w.DeepCopy()
78-
patch := client.MergeFrom(original)
79-
80-
w.Status.Total = numWidgets
81-
82-
if err := r.Client.Status().Patch(ctx, &w, patch); err != nil {
68+
log.Info("Patching widget status to store total widget count in the current logical cluster")
69+
orig := w.DeepCopy()
70+
w.Status.Total = len(list.Items)
71+
if err := r.Client.Status().Patch(ctx, &w, client.MergeFromWithOptions(orig, client.MergeFromWithOptimisticLock{})); err != nil {
8372
return ctrl.Result{}, err
8473
}
8574

8675
return ctrl.Result{}, nil
8776
}
8877

8978
// SetupWithManager sets up the controller with the Manager.
90-
func (r *WidgetReconciler) SetupWithManager(mgr ctrl.Manager) error {
79+
func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
9180
return ctrl.NewControllerManagedBy(mgr).
9281
For(&datav1alpha1.Widget{}).
93-
Complete(WithClusterInContext(r))
82+
Complete(kcp.WithClusterInContext(r))
9483
}

0 commit comments

Comments
 (0)