Skip to content

Commit c0b2a27

Browse files
committed
Fix customServiceConfig bug <Jira: OSPRH-10696>
1 parent e634c08 commit c0b2a27

File tree

8 files changed

+188
-88
lines changed

8 files changed

+188
-88
lines changed

controllers/ironic_controller.go

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import (
4949
"sigs.k8s.io/controller-runtime/pkg/builder"
5050
"sigs.k8s.io/controller-runtime/pkg/client"
5151
"sigs.k8s.io/controller-runtime/pkg/handler"
52+
"sigs.k8s.io/controller-runtime/pkg/predicate"
5253
"sigs.k8s.io/controller-runtime/pkg/reconcile"
5354

5455
batchv1 "k8s.io/api/batch/v1"
@@ -218,6 +219,52 @@ func (r *IronicReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
218219

219220
// SetupWithManager sets up the controller with the Manager.
220221
func (r *IronicReconciler) SetupWithManager(mgr ctrl.Manager) error {
222+
// watch for configmap where the CM owner label AND the CR.Spec.ManagingCrName label matches
223+
configMapFn := func(ctx context.Context, o client.Object) []reconcile.Request {
224+
Log := r.GetLogger(ctx)
225+
226+
result := []reconcile.Request{}
227+
228+
// get all API CRs
229+
apis := &ironicv1.IronicInspectorList{}
230+
listOpts := []client.ListOption{
231+
client.InNamespace(o.GetNamespace()),
232+
}
233+
if err := r.Client.List(
234+
ctx,
235+
apis,
236+
listOpts...); err != nil {
237+
238+
Log.Error(err, "Unable to retrieve API CRs %v")
239+
return nil
240+
}
241+
242+
label := o.GetLabels()
243+
// TODO: Just trying to verify that the CM is owned by this CR's managing CR
244+
if l, ok := label[labels.GetOwnerNameLabelSelector(
245+
labels.GetGroupLabel(ironic.ServiceName))]; ok {
246+
for _, cr := range apis.Items {
247+
// return reconcil event for the CR where the CM owner label
248+
// AND the parentIronicName matches
249+
if l == ironicv1.GetOwningIronicName(&cr) {
250+
// return namespace and Name of CR
251+
name := client.ObjectKey{
252+
Namespace: o.GetNamespace(),
253+
Name: cr.Name,
254+
}
255+
Log.Info(fmt.Sprintf(
256+
"ConfigMap object %s and CR %s marked with label: %s",
257+
o.GetName(), cr.Name, l))
258+
result = append(
259+
result, reconcile.Request{NamespacedName: name})
260+
}
261+
}
262+
}
263+
if len(result) > 0 {
264+
return result
265+
}
266+
return nil
267+
}
221268
return ctrl.NewControllerManagedBy(mgr).
222269
For(&ironicv1.Ironic{}).
223270
Owns(&ironicv1.IronicConductor{}).
@@ -228,10 +275,13 @@ func (r *IronicReconciler) SetupWithManager(mgr ctrl.Manager) error {
228275
Owns(&mariadbv1.MariaDBAccount{}).
229276
Owns(&batchv1.Job{}).
230277
Owns(&corev1.Secret{}).
231-
Owns(&corev1.ConfigMap{}).
232278
Owns(&corev1.ServiceAccount{}).
233279
Owns(&rbacv1.Role{}).
234280
Owns(&rbacv1.RoleBinding{}).
281+
Watches(
282+
&corev1.ConfigMap{},
283+
handler.EnqueueRequestsFromMapFunc(configMapFn),
284+
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{})).
235285
Watches(&keystonev1.KeystoneAPI{},
236286
handler.EnqueueRequestsFromMapFunc(r.findObjectForSrc),
237287
builder.WithPredicates(keystonev1.KeystoneAPIStatusChangedPredicate)).
@@ -539,6 +589,10 @@ func (r *IronicReconciler) reconcileNormal(ctx context.Context, instance *ironic
539589
}
540590
}
541591

592+
if instance.Spec.IronicAPI.CustomServiceConfig == "" {
593+
instance.Spec.IronicAPI.CustomServiceConfig = instance.Spec.IronicSpecCore.CustomServiceConfig
594+
}
595+
542596
// deploy ironic-api
543597
ironicAPI, op, err := r.apiDeploymentCreateOrUpdate(instance, &keystoneEndpoints)
544598
if err != nil {
@@ -935,8 +989,8 @@ func (r *IronicReconciler) generateServiceConfigMaps(
935989
// all other files get placed into /etc/ironic to allow overwrite of e.g. policy.json
936990
// TODO: make sure custom.conf can not be overwritten
937991
customData := map[string]string{
938-
common.CustomServiceConfigFileName: instance.Spec.CustomServiceConfig,
939-
"my.cnf": db.GetDatabaseClientConfig(tlsCfg), //(mschuppert) for now just get the default my.cnf
992+
"01-ironic-custom.conf": instance.Spec.CustomServiceConfig,
993+
"my.cnf": db.GetDatabaseClientConfig(tlsCfg), //(mschuppert) for now just get the default my.cnf
940994

941995
}
942996
for key, data := range instance.Spec.DefaultConfigOverwrite {

controllers/ironicapi_controller.go

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -224,43 +224,6 @@ func (r *IronicAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
224224

225225
// SetupWithManager sets up the controller with the Manager.
226226
func (r *IronicAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error {
227-
// watch for configmap where the CM owner label AND the CR.Spec.ManagingCrName label matches
228-
configMapFn := func(ctx context.Context, o client.Object) []reconcile.Request {
229-
Log := r.GetLogger(ctx)
230-
231-
result := []reconcile.Request{}
232-
233-
// get all API CRs
234-
apis := &ironicv1.IronicAPIList{}
235-
listOpts := []client.ListOption{
236-
client.InNamespace(o.GetNamespace()),
237-
}
238-
if err := r.Client.List(ctx, apis, listOpts...); err != nil {
239-
Log.Error(err, "Unable to retrieve API CRs %v")
240-
return nil
241-
}
242-
243-
label := o.GetLabels()
244-
// TODO: Just trying to verify that the CM is owned by this CR's managing CR
245-
if l, ok := label[labels.GetOwnerNameLabelSelector(labels.GetGroupLabel(ironic.ServiceName))]; ok {
246-
for _, cr := range apis.Items {
247-
// return reconcil event for the CR where the CM owner label AND the parentIronicName matches
248-
if l == ironicv1.GetOwningIronicName(&cr) {
249-
// return namespace and Name of CR
250-
name := client.ObjectKey{
251-
Namespace: o.GetNamespace(),
252-
Name: cr.Name,
253-
}
254-
Log.Info(fmt.Sprintf("ConfigMap object %s and CR %s marked with label: %s", o.GetName(), cr.Name, l))
255-
result = append(result, reconcile.Request{NamespacedName: name})
256-
}
257-
}
258-
}
259-
if len(result) > 0 {
260-
return result
261-
}
262-
return nil
263-
}
264227

265228
// index passwordSecretField
266229
if err := mgr.GetFieldIndexer().IndexField(ctx, &ironicv1.IronicAPI{}, passwordSecretField, func(rawObj client.Object) []string {
@@ -332,9 +295,6 @@ func (r *IronicAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Man
332295
Owns(&corev1.ServiceAccount{}).
333296
Owns(&rbacv1.Role{}).
334297
Owns(&rbacv1.RoleBinding{}).
335-
// watch the config CMs we don't own
336-
Watches(&corev1.ConfigMap{},
337-
handler.EnqueueRequestsFromMapFunc(configMapFn)).
338298
Watches(
339299
&corev1.Secret{},
340300
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
@@ -351,8 +311,36 @@ func (r *IronicAPIReconciler) findObjectsForSrc(ctx context.Context, src client.
351311

352312
l := log.FromContext(ctx).WithName("Controllers").WithName("IronicAPI")
353313

314+
crList := &ironicv1.IronicAPIList{}
315+
listOpts := []client.ListOption{client.InNamespace(src.GetNamespace())}
316+
317+
if err := r.List(ctx, crList, listOpts...); err != nil {
318+
l.Error(err, "Unable to retrieve Conductor CRs %v")
319+
} else {
320+
label := src.GetLabels()
321+
// TODO: Just trying to verify that the Secret is owned by this CR's managing CR
322+
if lbl, ok := label[labels.GetOwnerNameLabelSelector(labels.GetGroupLabel(ironic.ServiceName))]; ok {
323+
for _, item := range crList.Items {
324+
// return reconcile event for the CR where the Secret owner label AND the parentIronicName matches
325+
if lbl == ironicv1.GetOwningIronicName(&item) {
326+
// return Namespace and Name of CR
327+
l.Info(fmt.Sprintf("input source %s changed, reconcile: %s - %s", src.GetName(), item.GetName(), item.GetNamespace()))
328+
329+
requests = append(requests,
330+
reconcile.Request{
331+
NamespacedName: types.NamespacedName{
332+
Name: item.GetName(),
333+
Namespace: item.GetNamespace(),
334+
},
335+
},
336+
)
337+
338+
}
339+
}
340+
}
341+
}
342+
354343
for _, field := range ironicAPIWatchFields {
355-
crList := &ironicv1.IronicAPIList{}
356344
listOps := &client.ListOptions{
357345
FieldSelector: fields.OneTermEqualSelector(field, src.GetName()),
358346
Namespace: src.GetNamespace(),
@@ -662,6 +650,31 @@ func (r *IronicAPIReconciler) reconcileNormal(ctx context.Context, instance *iro
662650
//
663651
// check for required OpenStack secret holding passwords for service/admin user and add hash to the vars map
664652
//
653+
654+
// Get secrets by Namespace and Label that we need to hash
655+
labelSelectorMap := map[string]string{}
656+
lbl := labels.GetOwnerNameLabelSelector(labels.GetGroupLabel(ironic.ServiceName))
657+
labelSelectorMap[lbl] = ironicv1.GetOwningIronicName(instance)
658+
secrets, err := secret.GetSecrets(ctx, helper, instance.Namespace, labelSelectorMap)
659+
if err != nil {
660+
Log.Info(fmt.Sprintf("No secrets with label %s found", lbl))
661+
} else {
662+
for _, s := range secrets.Items {
663+
hash, err := secret.Hash(&s)
664+
if err != nil {
665+
Log.Info(fmt.Sprintf("Not able to has secret %s found", s.Name))
666+
instance.Status.Conditions.Set(condition.FalseCondition(
667+
condition.InputReadyCondition,
668+
condition.ErrorReason,
669+
condition.SeverityWarning,
670+
condition.InputReadyErrorMessage,
671+
err.Error()))
672+
return ctrl.Result{}, err
673+
}
674+
configMapVars[s.Name] = env.SetValue(hash)
675+
}
676+
}
677+
665678
ospSecret, hash, err := secret.GetSecret(ctx, helper, instance.Spec.Secret, instance.Namespace)
666679
if err != nil {
667680
if k8s_errors.IsNotFound(err) {

controllers/ironicconductor_controller.go

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -207,43 +207,6 @@ func (r *IronicConductorReconciler) Reconcile(ctx context.Context, req ctrl.Requ
207207

208208
// SetupWithManager sets up the controller with the Manager.
209209
func (r *IronicConductorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error {
210-
// watch for configmap where the CM owner label AND the CR.Spec.ManagingCrName label matches
211-
configMapFn := func(ctx context.Context, o client.Object) []reconcile.Request {
212-
result := []reconcile.Request{}
213-
Log := r.GetLogger(ctx)
214-
215-
// get all API CRs
216-
apis := &ironicv1.IronicConductorList{}
217-
listOpts := []client.ListOption{
218-
client.InNamespace(o.GetNamespace()),
219-
}
220-
if err := r.Client.List(ctx, apis, listOpts...); err != nil {
221-
Log.Error(err, "Unable to retrieve API CRs %v")
222-
return nil
223-
}
224-
225-
label := o.GetLabels()
226-
// TODO: Just trying to verify that the CM is owned by this CR's managing CR
227-
if l, ok := label[labels.GetOwnerNameLabelSelector(labels.GetGroupLabel(ironic.ServiceName))]; ok {
228-
for _, cr := range apis.Items {
229-
// return reconcil event for the CR where the CM owner label AND the parentIronicName matches
230-
if l == ironicv1.GetOwningIronicName(&cr) {
231-
// return namespace and Name of CR
232-
name := client.ObjectKey{
233-
Namespace: o.GetNamespace(),
234-
Name: cr.Name,
235-
}
236-
Log.Info(fmt.Sprintf("ConfigMap object %s and CR %s marked with label: %s", o.GetName(), cr.Name, l))
237-
result = append(result, reconcile.Request{NamespacedName: name})
238-
}
239-
}
240-
}
241-
if len(result) > 0 {
242-
return result
243-
}
244-
return nil
245-
}
246-
247210
// index passwordSecretField
248211
if err := mgr.GetFieldIndexer().IndexField(ctx, &ironicv1.IronicConductor{}, passwordSecretField, func(rawObj client.Object) []string {
249212
// Extract the secret name from the spec, if one is provided
@@ -290,9 +253,6 @@ func (r *IronicConductorReconciler) SetupWithManager(ctx context.Context, mgr ct
290253
Owns(&corev1.ServiceAccount{}).
291254
Owns(&rbacv1.Role{}).
292255
Owns(&rbacv1.RoleBinding{}).
293-
// watch the config CMs we don't own
294-
Watches(&corev1.ConfigMap{},
295-
handler.EnqueueRequestsFromMapFunc(configMapFn)).
296256
Watches(
297257
&corev1.Secret{},
298258
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
@@ -309,6 +269,37 @@ func (r *IronicConductorReconciler) findObjectsForSrc(ctx context.Context, src c
309269

310270
l := log.FromContext(ctx).WithName("Controllers").WithName("IronicConductor")
311271

272+
crList := &ironicv1.IronicConductorList{}
273+
namespace := src.GetNamespace()
274+
listOpts := []client.ListOption{client.InNamespace(namespace)}
275+
276+
if err := r.List(ctx, crList, listOpts...); err != nil {
277+
l.Error(err, "Unable to retrieve Conductor CRs %v")
278+
} else {
279+
label := src.GetLabels()
280+
// TODO: Just trying to verify that the Secret is owned by this CR's managing CR
281+
if lbl, ok := label[labels.GetOwnerNameLabelSelector(labels.GetGroupLabel(ironic.ServiceName))]; ok {
282+
for _, item := range crList.Items {
283+
// return reconcil event for the CR where the Secret owner label AND the parentIronicName matches
284+
if lbl == ironicv1.GetOwningIronicName(&item) {
285+
// return Namespace and Name of CR
286+
l.Info(fmt.Sprintf("input source %s changed, reconcile: %s - %s", src.GetName(), item.GetName(), item.GetNamespace()))
287+
288+
requests = append(
289+
requests,
290+
reconcile.Request{
291+
NamespacedName: k8s_types.NamespacedName{
292+
Name: item.GetName(),
293+
Namespace: item.GetNamespace(),
294+
},
295+
},
296+
)
297+
298+
}
299+
}
300+
}
301+
}
302+
312303
for _, field := range ironicConductorWatchFields {
313304
crList := &ironicv1.IronicConductorList{}
314305
listOps := &client.ListOptions{
@@ -500,6 +491,30 @@ func (r *IronicConductorReconciler) reconcileNormal(ctx context.Context, instanc
500491
//
501492
// check for required OpenStack secret holding passwords for service/admin user and add hash to the vars map
502493
//
494+
495+
// Get secrets by Namespace and Label that we need to hash ...
496+
labelSelectorMap := map[string]string{}
497+
lbl := labels.GetOwnerNameLabelSelector(labels.GetGroupLabel(ironic.ServiceName))
498+
labelSelectorMap[lbl] = ironicv1.GetOwningIronicName(instance)
499+
secrets, err := secret.GetSecrets(ctx, helper, instance.Namespace, labelSelectorMap)
500+
if err != nil {
501+
Log.Info(fmt.Sprintf("No secrets with label %s found", lbl))
502+
} else {
503+
for _, s := range secrets.Items {
504+
hash, err := secret.Hash(&s)
505+
if err != nil {
506+
Log.Info(fmt.Sprintf("Not able to has secret %s not found", s.Name))
507+
instance.Status.Conditions.Set(condition.FalseCondition(
508+
condition.InputReadyCondition,
509+
condition.ErrorReason,
510+
condition.SeverityWarning,
511+
condition.InputReadyErrorMessage,
512+
err.Error()))
513+
return ctrl.Result{}, err
514+
}
515+
configMapVars[s.Name] = env.SetValue(hash)
516+
}
517+
}
503518
ospSecret, hash, err := secret.GetSecret(ctx, helper, instance.Spec.Secret, instance.Namespace)
504519
if err != nil {
505520
if k8s_errors.IsNotFound(err) {

pkg/ironicapi/volumes.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
package ironicapi
22

33
import (
4+
"fmt"
5+
"strings"
6+
47
"github.com/openstack-k8s-operators/ironic-operator/pkg/ironic"
58
corev1 "k8s.io/api/core/v1"
69
)
710

811
// GetVolumes -
912
func GetVolumes(name string) []corev1.Volume {
1013
var config0640AccessMode int32 = 0640
11-
14+
parentName := strings.Replace(name, "-api", "", 1)
1215
apiVolumes := []corev1.Volume{
1316
{
1417
Name: "config-data-custom",
1518
VolumeSource: corev1.VolumeSource{
1619
Secret: &corev1.SecretVolumeSource{
1720
DefaultMode: &config0640AccessMode,
18-
SecretName: name + "-config-data",
21+
SecretName: fmt.Sprintf("%s-config-data", parentName),
1922
},
2023
},
2124
},

pkg/ironicconductor/volumes.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ironicconductor
22

33
import (
44
"fmt"
5+
"strings"
56

67
ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1"
78
"github.com/openstack-k8s-operators/ironic-operator/pkg/ironic"
@@ -11,13 +12,15 @@ import (
1112
// GetVolumes -
1213
func GetVolumes(instance *ironicv1.IronicConductor) []corev1.Volume {
1314
var config0640AccessMode int32 = 0640
15+
parentName := strings.Replace(instance.Name, "-conductor", "", 1)
16+
1417
conductorVolumes := []corev1.Volume{
1518
{
1619
Name: "config-data-custom",
1720
VolumeSource: corev1.VolumeSource{
1821
Secret: &corev1.SecretVolumeSource{
1922
DefaultMode: &config0640AccessMode,
20-
SecretName: fmt.Sprintf("%s-config-data", instance.Name),
23+
SecretName: fmt.Sprintf("%s-config-data", parentName),
2124
},
2225
},
2326
},

0 commit comments

Comments
 (0)