Skip to content

Commit 1358307

Browse files
authored
Merge pull request #736 from hidekazuna/update_sync
Update sync logic
2 parents 76f23ba + 4b368a6 commit 1358307

9 files changed

+247
-37
lines changed

api/v1alpha3/openstackmachine_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ type OpenStackMachineSpec struct {
3333
// ProviderID is the unique identifier as specified by the cloud provider.
3434
ProviderID *string `json:"providerID,omitempty"`
3535

36+
// InstanceID is the OpenStack instance ID for this machine.
37+
InstanceID *string `json:"instanceID,omitempty"`
38+
3639
// The name of the secret containing the openstack credentials
3740
// +optional
3841
CloudsSecret *corev1.SecretReference `json:"cloudsSecret"`

api/v1alpha3/openstackmachine_webhook.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ func (r *OpenStackMachine) ValidateUpdate(old runtime.Object) error {
7272
delete(oldOpenStackMachineSpec, "providerID")
7373
delete(newOpenStackMachineSpec, "providerID")
7474

75+
// allow changes to instanceID
76+
delete(oldOpenStackMachineSpec, "instanceID")
77+
delete(newOpenStackMachineSpec, "instanceID")
78+
7579
if !reflect.DeepEqual(oldOpenStackMachineSpec, newOpenStackMachineSpec) {
7680
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "cannot be modified"))
7781
}

api/v1alpha3/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ spec:
9090
If the RootVolume is specified, this will be ignored and use rootVolume
9191
directly.
9292
type: string
93+
instanceID:
94+
description: InstanceID is the OpenStack instance ID for this machine.
95+
type: string
9396
networks:
9497
description: A networks object. Required parameter when there are
9598
multiple networks defined for the tenant. When you do not specify

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ spec:
8282
instance. If the RootVolume is specified, this will be ignored
8383
and use rootVolume directly.
8484
type: string
85+
instanceID:
86+
description: InstanceID is the OpenStack instance ID for this
87+
machine.
88+
type: string
8589
networks:
8690
description: A networks object. Required parameter when there
8791
are multiple networks defined for the tenant. When you do

controllers/helpers.go

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,40 @@ limitations under the License.
1717
package controllers
1818

1919
import (
20+
"strings"
21+
22+
"github.com/go-logr/logr"
2023
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21-
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
24+
"k8s.io/apimachinery/pkg/runtime"
2225
clusterutil "sigs.k8s.io/cluster-api/util"
2326
"sigs.k8s.io/controller-runtime/pkg/event"
2427
"sigs.k8s.io/controller-runtime/pkg/predicate"
2528
)
2629

27-
// TODO: Move to Cluster API
28-
var pausePredicates = predicate.Funcs{
29-
UpdateFunc: func(e event.UpdateEvent) bool {
30-
return !isPaused(nil, e.MetaNew)
31-
},
32-
CreateFunc: func(e event.CreateEvent) bool {
33-
return !isPaused(nil, e.Meta)
34-
},
35-
DeleteFunc: func(e event.DeleteEvent) bool {
36-
return !isPaused(nil, e.Meta)
37-
},
30+
func pausedPredicates(logger logr.Logger) predicate.Funcs {
31+
return predicate.Funcs{
32+
UpdateFunc: func(e event.UpdateEvent) bool {
33+
return processIfUnpaused(logger.WithValues("predicate", "updateEvent"), e.ObjectNew, e.MetaNew)
34+
},
35+
CreateFunc: func(e event.CreateEvent) bool {
36+
return processIfUnpaused(logger.WithValues("predicate", "createEvent"), e.Object, e.Meta)
37+
},
38+
DeleteFunc: func(e event.DeleteEvent) bool {
39+
return processIfUnpaused(logger.WithValues("predicate", "deleteEvent"), e.Object, e.Meta)
40+
},
41+
GenericFunc: func(e event.GenericEvent) bool {
42+
return processIfUnpaused(logger.WithValues("predicate", "genericEvent"), e.Object, e.Meta)
43+
},
44+
}
3845
}
3946

40-
// TODO: Fix up Cluster API's clusterutil.IsPaused function
41-
func isPaused(cluster *clusterv1.Cluster, v metav1.Object) bool {
42-
if cluster == nil {
43-
cluster = &clusterv1.Cluster{
44-
Spec: clusterv1.ClusterSpec{},
45-
}
47+
func processIfUnpaused(logger logr.Logger, obj runtime.Object, meta metav1.Object) bool {
48+
kind := strings.ToLower(obj.GetObjectKind().GroupVersionKind().Kind)
49+
log := logger.WithValues("namespace", meta.GetNamespace(), kind, meta.GetName())
50+
if clusterutil.HasPausedAnnotation(meta) {
51+
log.V(4).Info("Resource is paused, will not attempt to map resource")
52+
return false
4653
}
47-
return clusterutil.IsPaused(cluster, v)
54+
log.V(4).Info("Resource is not paused, will attempt to map resource")
55+
return true
4856
}

controllers/openstackcluster_controller.go

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package controllers
1919
import (
2020
"context"
2121
"fmt"
22+
"reflect"
2223

2324
"github.com/go-logr/logr"
2425
"github.com/gophercloud/gophercloud"
@@ -41,7 +42,11 @@ import (
4142
"sigs.k8s.io/controller-runtime/pkg/client"
4243
"sigs.k8s.io/controller-runtime/pkg/controller"
4344
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
45+
"sigs.k8s.io/controller-runtime/pkg/event"
46+
"sigs.k8s.io/controller-runtime/pkg/handler"
47+
"sigs.k8s.io/controller-runtime/pkg/predicate"
4448
"sigs.k8s.io/controller-runtime/pkg/reconcile"
49+
"sigs.k8s.io/controller-runtime/pkg/source"
4550
)
4651

4752
// OpenStackClusterReconciler reconciles a OpenStackCluster object
@@ -75,11 +80,6 @@ func (r *OpenStackClusterReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result,
7580
return reconcile.Result{}, err
7681
}
7782

78-
if isPaused(cluster, openStackCluster) {
79-
log.Info("OpenStackCluster or linked Cluster is marked as paused. Won't reconcile")
80-
return reconcile.Result{}, nil
81-
}
82-
8383
if cluster == nil {
8484
log.Info("Cluster Controller has not yet set OwnerRef")
8585
return reconcile.Result{}, nil
@@ -438,9 +438,109 @@ func (r *OpenStackClusterReconciler) reconcileNetworkComponents(log logr.Logger,
438438
}
439439

440440
func (r *OpenStackClusterReconciler) SetupWithManager(mgr ctrl.Manager, options controller.Options) error {
441-
return ctrl.NewControllerManagedBy(mgr).
441+
controller, err := ctrl.NewControllerManagedBy(mgr).
442442
WithOptions(options).
443443
For(&infrav1.OpenStackCluster{}).
444-
WithEventFilter(pausePredicates).
445-
Complete(r)
444+
WithEventFilter(pausedPredicates(r.Log)).
445+
WithEventFilter(
446+
predicate.Funcs{
447+
// Avoid reconciling if the event triggering the reconciliation is related to incremental status updates
448+
// for OpenStackCluster resources only
449+
UpdateFunc: func(e event.UpdateEvent) bool {
450+
if e.ObjectOld.GetObjectKind().GroupVersionKind().Kind != "OpenStackCluster" {
451+
return true
452+
}
453+
454+
oldCluster := e.ObjectOld.(*infrav1.OpenStackCluster).DeepCopy()
455+
newCluster := e.ObjectNew.(*infrav1.OpenStackCluster).DeepCopy()
456+
457+
oldCluster.Status = infrav1.OpenStackClusterStatus{}
458+
newCluster.Status = infrav1.OpenStackClusterStatus{}
459+
460+
oldCluster.ObjectMeta.ResourceVersion = ""
461+
newCluster.ObjectMeta.ResourceVersion = ""
462+
463+
return !reflect.DeepEqual(oldCluster, newCluster)
464+
},
465+
},
466+
).
467+
Build(r)
468+
if err != nil {
469+
return errors.Wrap(err, "error creating controller")
470+
}
471+
472+
return controller.Watch(
473+
&source.Kind{Type: &clusterv1.Cluster{}},
474+
&handler.EnqueueRequestsFromMapFunc{
475+
ToRequests: handler.ToRequestsFunc(r.requeueOpenStackClusterForUnpausedCluster),
476+
},
477+
predicate.Funcs{
478+
UpdateFunc: func(e event.UpdateEvent) bool {
479+
oldCluster := e.ObjectOld.(*clusterv1.Cluster)
480+
newCluster := e.ObjectNew.(*clusterv1.Cluster)
481+
log := r.Log.WithValues("predicate", "updateEvent", "namespace", newCluster.Namespace, "cluster", newCluster.Name)
482+
switch {
483+
// return true if Cluster.Spec.Paused has changed from true to false
484+
case oldCluster.Spec.Paused && !newCluster.Spec.Paused:
485+
log.V(4).Info("Cluster was unpaused, will attempt to map associated OpenStackCluster.")
486+
return true
487+
// otherwise, return false
488+
default:
489+
log.V(4).Info("Cluster did not match expected conditions, will not attempt to map associated OpenStackCluster.")
490+
return false
491+
}
492+
},
493+
CreateFunc: func(e event.CreateEvent) bool {
494+
cluster := e.Object.(*clusterv1.Cluster)
495+
log := r.Log.WithValues("predicate", "createEvent", "namespace", cluster.Namespace, "cluster", cluster.Name)
496+
497+
// Only need to trigger a reconcile if the Cluster.Spec.Paused is false
498+
if !cluster.Spec.Paused {
499+
log.V(4).Info("Cluster is not paused, will attempt to map associated OpenStackCluster.")
500+
return true
501+
}
502+
log.V(4).Info("Cluster did not match expected conditions, will not attempt to map associated OpenStackCluster.")
503+
return false
504+
},
505+
DeleteFunc: func(e event.DeleteEvent) bool {
506+
log := r.Log.WithValues("predicate", "deleteEvent", "namespace", e.Meta.GetNamespace(), "cluster", e.Meta.GetName())
507+
log.V(4).Info("Cluster did not match expected conditions, will not attempt to map associated OpenStackCluster.")
508+
return false
509+
},
510+
GenericFunc: func(e event.GenericEvent) bool {
511+
log := r.Log.WithValues("predicate", "genericEvent", "namespace", e.Meta.GetNamespace(), "cluster", e.Meta.GetName())
512+
log.V(4).Info("Cluster did not match expected conditions, will not attempt to map associated OpenStackCluster.")
513+
return false
514+
},
515+
},
516+
)
517+
}
518+
519+
func (r *OpenStackClusterReconciler) requeueOpenStackClusterForUnpausedCluster(o handler.MapObject) []ctrl.Request {
520+
c := o.Object.(*clusterv1.Cluster)
521+
log := r.Log.WithValues("objectMapper", "clusterToOpenStackCluster", "namespace", c.Namespace, "cluster", c.Name)
522+
523+
// Don't handle deleted clusters
524+
if !c.ObjectMeta.DeletionTimestamp.IsZero() {
525+
log.V(4).Info("Cluster has a deletion timestamp, skipping mapping.")
526+
return nil
527+
}
528+
529+
// Make sure the ref is set
530+
if c.Spec.InfrastructureRef == nil {
531+
log.V(4).Info("Cluster does not have an InfrastructureRef, skipping mapping.")
532+
return nil
533+
}
534+
535+
if c.Spec.InfrastructureRef.GroupVersionKind().Kind != "OpenStackCluster" {
536+
log.V(4).Info("Cluster has an InfrastructureRef for a different type, skipping mapping.")
537+
return nil
538+
}
539+
540+
log.V(4).Info("Adding request.", "openstackCluster", c.Spec.InfrastructureRef.Name)
541+
return []ctrl.Request{
542+
{
543+
NamespacedName: client.ObjectKey{Namespace: c.Namespace, Name: c.Spec.InfrastructureRef.Name},
544+
},
545+
}
446546
}

0 commit comments

Comments
 (0)