@@ -43,6 +43,7 @@ import (
4343 octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1"
4444 "github.com/openstack-k8s-operators/octavia-operator/pkg/octavia"
4545 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
46+ "k8s.io/apimachinery/pkg/types"
4647 "k8s.io/apimachinery/pkg/util/intstr"
4748
4849 appsv1 "k8s.io/api/apps/v1"
@@ -186,7 +187,6 @@ func (r *OctaviaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (re
186187 condition .UnknownCondition (octaviav1 .OctaviaAPIReadyCondition , condition .InitReason , octaviav1 .OctaviaAPIReadyInitMessage ),
187188 condition .UnknownCondition (condition .NetworkAttachmentsReadyCondition , condition .InitReason , condition .NetworkAttachmentsReadyInitMessage ),
188189 condition .UnknownCondition (condition .ExposeServiceReadyCondition , condition .InitReason , condition .ExposeServiceReadyInitMessage ),
189- condition .UnknownCondition (condition .DeploymentReadyCondition , condition .InitReason , condition .DeploymentReadyInitMessage ),
190190 condition .UnknownCondition (octaviav1 .OctaviaAmphoraCertsReadyCondition , condition .InitReason , octaviav1 .OctaviaAmphoraCertsReadyInitMessage ),
191191 condition .UnknownCondition (octaviav1 .OctaviaQuotasReadyCondition , condition .InitReason , octaviav1 .OctaviaQuotasReadyInitMessage ),
192192 condition .UnknownCondition (octaviav1 .OctaviaAmphoraSSHReadyCondition , condition .InitReason , octaviav1 .OctaviaAmphoraSSHReadyInitMessage ),
@@ -504,9 +504,12 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav
504504 condition .InputReadyWaitingMessage ))
505505 return ctrl.Result {RequeueAfter : time .Duration (10 ) * time .Second }, nil
506506 }
507+ instance .Status .Conditions .MarkTrue (
508+ condition .RabbitMqTransportURLReadyCondition ,
509+ condition .RabbitMqTransportURLReadyMessage )
507510 instance .Status .Conditions .MarkTrue (condition .InputReadyCondition , condition .InputReadyMessage )
508511
509- err = octavia .EnsureAmphoraCerts (ctx , instance , helper , & Log )
512+ err = octavia .EnsureAmphoraCerts (ctx , instance , helper )
510513 if err != nil {
511514 instance .Status .Conditions .Set (condition .FalseCondition (
512515 octaviav1 .OctaviaAmphoraCertsReadyCondition ,
@@ -673,6 +676,109 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav
673676 return ctrl.Result {}, err
674677 }
675678
679+ nodeConfigMap := & corev1.ConfigMap {
680+ ObjectMeta : metav1.ObjectMeta {
681+ Name : octavia .HmConfigMap ,
682+ Namespace : instance .GetNamespace (),
683+ Labels : labels .GetLabels (instance , labels .GetGroupLabel (instance .ObjectMeta .Name ), map [string ]string {}),
684+ },
685+ Data : make (map [string ]string ),
686+ }
687+
688+ // Look for existing config map and if exists, read existing data and match
689+ // against nodes.
690+ foundMap := & corev1.ConfigMap {}
691+ err = helper .GetClient ().Get (ctx , types.NamespacedName {Name : octavia .HmConfigMap , Namespace : instance .GetNamespace ()},
692+ foundMap )
693+ if err != nil {
694+ if k8s_errors .IsNotFound (err ) {
695+ Log .Info (fmt .Sprintf ("Port map %s doesn't exist, creating." , octavia .HmConfigMap ))
696+ } else {
697+ return ctrl.Result {}, err
698+ }
699+ } else {
700+ Log .Info ("Retrieved existing map, updating.." )
701+ nodeConfigMap .Data = foundMap .Data
702+ }
703+
704+ //
705+ // Predictable IPs.
706+ //
707+ // NOTE(beagles): refactoring this might be nice. This could also be
708+ // optimized but the data sets are small (nodes an IP ranges are less than
709+ // 100) so optimization might be a waste.
710+ //
711+ predictableIPParams , err := octavia .GetPredictableIPAM (networkParameters )
712+ if err != nil {
713+ return ctrl.Result {}, err
714+ }
715+ // Get a list of the nodes in the cluster
716+
717+ // TODO(beagles):
718+ // * confirm whether or not this lists only the nodes we want (i.e. ones
719+ // that will host the daemonset)
720+ // * do we want to provide a mechanism to temporarily disabling this list
721+ // for maintenance windows where nodes might be "coming and going"
722+
723+ nodes , _ := helper .GetKClient ().CoreV1 ().Nodes ().List (ctx , metav1.ListOptions {})
724+ updatedMap := make (map [string ]string )
725+ allocatedIPs := make (map [string ]bool )
726+ var predictableIPsRequired []string
727+
728+ // First scan existing allocations so we can keep existing allocations.
729+ // Keeping track of what's required and what already exists. If a node is
730+ // removed from the cluster, it's IPs will not be added to the allocated
731+ // list and are effectively recycled.
732+ for _ , node := range nodes .Items {
733+ Log .Info (fmt .Sprintf ("cluster node name %s" , node .Name ))
734+ portName := fmt .Sprintf ("hm_%s" , node .Name )
735+ if ipValue , ok := nodeConfigMap .Data [portName ]; ok {
736+ updatedMap [portName ] = ipValue
737+ allocatedIPs [ipValue ] = true
738+ Log .Info (fmt .Sprintf ("%s has IP mapping %s: %s" , node .Name , portName , ipValue ))
739+ } else {
740+ predictableIPsRequired = append (predictableIPsRequired , portName )
741+ }
742+ portName = fmt .Sprintf ("rsyslog_%s" , node .Name )
743+ if ipValue , ok := nodeConfigMap .Data [portName ]; ok {
744+ updatedMap [portName ] = ipValue
745+ allocatedIPs [ipValue ] = true
746+ Log .Info (fmt .Sprintf ("%s has IP mapping %s: %s" , node .Name , portName , ipValue ))
747+ } else {
748+ predictableIPsRequired = append (predictableIPsRequired , portName )
749+ }
750+ }
751+ // Get new IPs using the range from predictableIPParmas minus the
752+ // allocatedIPs captured above.
753+ Log .Info (fmt .Sprintf ("Allocating %d predictable IPs" , len (predictableIPsRequired )))
754+ for _ , portName := range predictableIPsRequired {
755+ hmPort , err := octavia .GetNextIP (predictableIPParams , allocatedIPs )
756+ if err != nil {
757+ // An error here is really unexpected- it means either we have
758+ // messed up the allocatedIPs list or the range we are assuming is
759+ // too small for the number of health managers and rsyslog
760+ // containers.
761+ return ctrl.Result {}, err
762+ }
763+ updatedMap [portName ] = hmPort
764+ }
765+
766+ mapLabels := labels .GetLabels (instance , labels .GetGroupLabel (instance .ObjectMeta .Name ), map [string ]string {})
767+ _ , err = controllerutil .CreateOrPatch (ctx , helper .GetClient (), nodeConfigMap , func () error {
768+ nodeConfigMap .Labels = util .MergeStringMaps (nodeConfigMap .Labels , mapLabels )
769+ nodeConfigMap .Data = updatedMap
770+ err := controllerutil .SetControllerReference (instance , nodeConfigMap , helper .GetScheme ())
771+ if err != nil {
772+ return err
773+ }
774+ return nil
775+ })
776+
777+ if err != nil {
778+ Log .Info ("Unable to create config map for health manager ports..." )
779+ return ctrl.Result {}, err
780+ }
781+
676782 octaviaHealthManager , op , err := r .amphoraControllerDaemonSetCreateOrUpdate (instance , networkInfo ,
677783 ampImageOwnerID , instance .Spec .OctaviaHealthManager , octaviav1 .HealthManager )
678784 if err != nil {
@@ -823,6 +929,8 @@ func (r *OctaviaReconciler) reconcileNormal(ctx context.Context, instance *octav
823929 octaviav1 .OctaviaAmphoraImagesReadyCondition ,
824930 octaviav1 .OctaviaAmphoraImagesReadyCompleteMessage )
825931
932+ instance .Status .Conditions .MarkTrue (condition .ExposeServiceReadyCondition , condition .ExposeServiceReadyMessage )
933+
826934 // create Deployment - end
827935
828936 // We reached the end of the Reconcile, update the Ready condition based on
@@ -965,6 +1073,7 @@ func (r *OctaviaReconciler) reconcileAmphoraImages(
9651073) (ctrl.Result , error ) {
9661074 Log := r .GetLogger (ctx )
9671075
1076+ var ctrlResult ctrl.Result
9681077 if instance .Spec .AmphoraImageContainerImage == "" {
9691078 if instance .Status .Hash [octaviav1 .ImageUploadHash ] != "" {
9701079 Log .Info ("Reseting image upload hash" )
@@ -986,36 +1095,6 @@ func (r *OctaviaReconciler) reconcileAmphoraImages(
9861095 common .AppSelector : octavia .ServiceName + "-image" ,
9871096 }
9881097
989- Log .Info ("Initializing amphora image upload deployment" )
990- depl := deployment .NewDeployment (
991- octavia .ImageUploadDeployment (instance , serviceLabels ),
992- time .Duration (5 )* time .Second ,
993- )
994- ctrlResult , err := depl .CreateOrPatch (ctx , helper )
995- if err != nil {
996- instance .Status .Conditions .Set (condition .FalseCondition (
997- condition .DeploymentReadyCondition ,
998- condition .ErrorReason ,
999- condition .SeverityWarning ,
1000- condition .DeploymentReadyErrorMessage ,
1001- err .Error ()))
1002- return ctrlResult , err
1003- } else if (ctrlResult != ctrl.Result {}) {
1004- instance .Status .Conditions .Set (condition .FalseCondition (
1005- condition .DeploymentReadyCondition ,
1006- condition .RequestedReason ,
1007- condition .SeverityInfo ,
1008- condition .DeploymentReadyRunningMessage ))
1009- return ctrlResult , nil
1010- }
1011-
1012- readyCount := depl .GetDeployment ().Status .ReadyReplicas
1013- if readyCount == 0 {
1014- // Not ready, wait for the next loop
1015- Log .Info ("Image Upload Pod not ready" )
1016- return ctrl.Result {Requeue : true , RequeueAfter : 1 * time .Second }, nil
1017- }
1018-
10191098 exportLabels := util .MergeStringMaps (
10201099 serviceLabels ,
10211100 map [string ]string {
@@ -1076,6 +1155,35 @@ func (r *OctaviaReconciler) reconcileAmphoraImages(
10761155 condition .ExposeServiceReadyRunningMessage ))
10771156 return ctrlResult , nil
10781157 }
1158+ Log .Info ("Initializing amphora image upload deployment" )
1159+ depl := deployment .NewDeployment (
1160+ octavia .ImageUploadDeployment (instance , serviceLabels ),
1161+ time .Duration (5 )* time .Second ,
1162+ )
1163+ ctrlResult , err = depl .CreateOrPatch (ctx , helper )
1164+ if err != nil {
1165+ instance .Status .Conditions .Set (condition .FalseCondition (
1166+ octaviav1 .OctaviaAmphoraImagesReadyCondition ,
1167+ condition .ErrorReason ,
1168+ condition .SeverityWarning ,
1169+ octaviav1 .OctaviaAmphoraImagesReadyErrorMessage ,
1170+ err .Error ()))
1171+ return ctrlResult , err
1172+ } else if (ctrlResult != ctrl.Result {}) {
1173+ instance .Status .Conditions .Set (condition .FalseCondition (
1174+ octaviav1 .OctaviaAmphoraImagesReadyCondition ,
1175+ condition .ErrorReason ,
1176+ condition .SeverityWarning ,
1177+ octaviav1 .OctaviaAmphoraImagesReadyErrorMessage ,
1178+ err .Error ()))
1179+ return ctrlResult , nil
1180+ }
1181+ readyCount := depl .GetDeployment ().Status .ReadyReplicas
1182+ if readyCount == 0 {
1183+ // Not ready, wait for the next loop
1184+ Log .Info ("Image Upload Pod not ready" )
1185+ return ctrl.Result {Requeue : true , RequeueAfter : 1 * time .Second }, nil
1186+ }
10791187 endpoint , err := svc .GetAPIEndpoint (nil , nil , "" )
10801188 if err != nil {
10811189 return ctrl.Result {}, err
0 commit comments