@@ -19,11 +19,20 @@ package controllers
19
19
import (
20
20
"context"
21
21
"fmt"
22
+ "time"
22
23
23
- kcpclient "github.com/kcp-dev/apimachinery/pkg/client"
24
24
corev1 "k8s.io/api/core/v1"
25
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
26
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
+ "k8s.io/apimachinery/pkg/types"
28
+
29
+ kcpclient "github.com/kcp-dev/apimachinery/pkg/client"
30
+
31
+ "github.com/kcp-dev/logicalcluster"
32
+
25
33
ctrl "sigs.k8s.io/controller-runtime"
26
34
"sigs.k8s.io/controller-runtime/pkg/client"
35
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
27
36
"sigs.k8s.io/controller-runtime/pkg/log"
28
37
)
29
38
@@ -45,6 +54,22 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
45
54
}
46
55
47
56
log .Info ("Get: retrieved configMap" )
57
+ labels := configMap .Labels
58
+
59
+ if labels ["name" ] != "" {
60
+ response := fmt .Sprintf ("hello-%s" , labels ["name" ])
61
+
62
+ if labels ["response" ] != response {
63
+ labels ["response" ] = response
64
+
65
+ // Test Update
66
+ if err := r .Update (ctx , & configMap ); err != nil {
67
+ return ctrl.Result {}, err
68
+ }
69
+ log .Info ("Update: updated configMap" )
70
+ return ctrl.Result {}, nil
71
+ }
72
+ }
48
73
49
74
// Test list
50
75
var configMapList corev1.ConfigMapList
@@ -53,29 +78,63 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
53
78
return ctrl.Result {}, nil
54
79
}
55
80
for _ , cm := range configMapList .Items {
56
- log .Info ("List: got" , "namespace" , cm .Namespace , "name" , cm .Name )
81
+ log .Info ("List: got" , "clusterName" , logicalcluster . From ( & cm ). String (), " namespace" , cm .Namespace , "name" , cm .Name )
57
82
}
58
83
59
- labels := configMap .Labels
60
- if labels == nil {
61
- return ctrl.Result {}, nil
62
- }
63
-
64
- // Test Update
65
- if labels ["name" ] == "" {
66
- return ctrl.Result {}, nil
84
+ // If the configmap has a namespace field, create the corresponding namespace
85
+ nsName , exists := configMap .Data ["namespace" ]
86
+ if exists {
87
+ var namespace corev1.Namespace
88
+ nsKey := client.ObjectKey {
89
+ NamespacedName : types.NamespacedName {Name : nsName },
90
+ Cluster : req .ObjectKey .Cluster ,
91
+ }
92
+
93
+ if err := r .Get (ctx , nsKey , & namespace ); err != nil {
94
+ if ! apierrors .IsNotFound (err ) {
95
+ log .Error (err , "unable to get namespace" )
96
+ return ctrl.Result {}, err
97
+ }
98
+
99
+ // Need to create ns
100
+ namespace .SetName (nsName )
101
+ if err = r .Create (ctx , & namespace ); err != nil {
102
+ log .Error (err , "unable to create namespace" )
103
+ return ctrl.Result {}, err
104
+ }
105
+ log .Info ("Create: created " , "namespace" , nsName )
106
+ return ctrl.Result {RequeueAfter : time .Second * 5 }, nil
107
+ }
108
+ log .Info ("Exists" , "namespace" , nsName )
67
109
}
68
110
69
- response := fmt .Sprintf ("hello-%s" , labels ["name" ])
70
-
71
- if labels ["response" ] == response {
72
- return ctrl.Result {}, nil
73
- }
74
-
75
- labels ["response" ] = response
76
-
77
- if err := r .Update (ctx , & configMap ); err != nil {
78
- return ctrl.Result {}, err
111
+ // If the configmap has a secretData field, create a secret in the same namespace
112
+ // If the secret already exists but is out of sync, it will be non-destructively patched
113
+ secretData , exists := configMap .Data ["secretData" ]
114
+ if exists {
115
+ var secret corev1.Secret
116
+
117
+ secret .SetName (configMap .GetName ())
118
+ secret .SetNamespace (configMap .GetNamespace ())
119
+ secret .SetClusterName (logicalcluster .From (& configMap ).String ())
120
+ secret .SetOwnerReferences ([]metav1.OwnerReference {metav1.OwnerReference {
121
+ Name : configMap .GetName (),
122
+ UID : configMap .GetUID (),
123
+ APIVersion : "v1" ,
124
+ Kind : "ConfigMap" ,
125
+ Controller : func () * bool { x := true ; return & x }(),
126
+ }})
127
+ secret .Data = map [string ][]byte {"dataFromCM" : []byte (secretData )}
128
+
129
+ operationResult , err := controllerutil .CreateOrPatch (ctx , r , & secret , func () error {
130
+ secret .Data ["dataFromCM" ] = []byte (secretData )
131
+ return nil
132
+ })
133
+ if err != nil {
134
+ log .Error (err , "unable to create or patch secret" )
135
+ return ctrl.Result {}, err
136
+ }
137
+ log .Info (string (operationResult ), "secret" , secret .GetName ())
79
138
}
80
139
81
140
return ctrl.Result {}, nil
@@ -84,5 +143,6 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
84
143
func (r * ConfigMapReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
85
144
return ctrl .NewControllerManagedBy (mgr ).
86
145
For (& corev1.ConfigMap {}).
146
+ Owns (& corev1.Secret {}).
87
147
Complete (r )
88
148
}
0 commit comments