@@ -241,12 +241,16 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
241241 }
242242 rosaScope .ControlPlane .Spec .ControlPlaneEndpoint = * apiEndpoint
243243
244- if err := r .reconcileKubeconfig ( ctx , rosaScope , ocmClient , cluster ); err != nil {
245- return ctrl.Result {}, fmt .Errorf ("failed to reconcile kubeconfig : %w" , err )
244+ if err := r .updateOCMCluster ( rosaScope , ocmClient , cluster , creator ); err != nil {
245+ return ctrl.Result {}, fmt .Errorf ("failed to update rosa control plane : %w" , err )
246246 }
247247 if err := r .reconcileClusterVersion (rosaScope , ocmClient , cluster ); err != nil {
248248 return ctrl.Result {}, err
249249 }
250+ if err := r .reconcileKubeconfig (ctx , rosaScope , ocmClient , cluster ); err != nil {
251+ return ctrl.Result {}, fmt .Errorf ("failed to reconcile kubeconfig: %w" , err )
252+ }
253+
250254 return ctrl.Result {}, nil
251255 case cmv1 .ClusterStateError :
252256 errorMessage := cluster .Status ().ProvisionErrorMessage ()
@@ -272,80 +276,9 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
272276 return ctrl.Result {RequeueAfter : time .Second * 60 }, nil
273277 }
274278
275- billingAccount := * rosaScope .Identity .Account
276- if rosaScope .ControlPlane .Spec .BillingAccount != "" {
277- billingAccount = rosaScope .ControlPlane .Spec .BillingAccount
278- }
279-
280- ocmClusterSpec := ocm.Spec {
281- DryRun : ptr .To (false ),
282- Name : rosaScope .RosaClusterName (),
283- DomainPrefix : rosaScope .ControlPlane .Spec .DomainPrefix ,
284- Region : rosaScope .ControlPlane .Spec .Region ,
285- MultiAZ : true ,
286- Version : ocm .CreateVersionID (rosaScope .ControlPlane .Spec .Version , ocm .DefaultChannelGroup ),
287- ChannelGroup : ocm .DefaultChannelGroup ,
288- DisableWorkloadMonitoring : ptr .To (true ),
289- DefaultIngress : ocm .NewDefaultIngressSpec (), // n.b. this is a no-op when it's set to the default value
290- ComputeMachineType : rosaScope .ControlPlane .Spec .DefaultMachinePoolSpec .InstanceType ,
291- AvailabilityZones : rosaScope .ControlPlane .Spec .AvailabilityZones ,
292- Tags : rosaScope .ControlPlane .Spec .AdditionalTags ,
293- EtcdEncryption : rosaScope .ControlPlane .Spec .EtcdEncryptionKMSArn != "" ,
294- EtcdEncryptionKMSArn : rosaScope .ControlPlane .Spec .EtcdEncryptionKMSArn ,
295-
296- SubnetIds : rosaScope .ControlPlane .Spec .Subnets ,
297- IsSTS : true ,
298- RoleARN : rosaScope .ControlPlane .Spec .InstallerRoleARN ,
299- SupportRoleARN : rosaScope .ControlPlane .Spec .SupportRoleARN ,
300- WorkerRoleARN : rosaScope .ControlPlane .Spec .WorkerRoleARN ,
301- OperatorIAMRoles : operatorIAMRoles (rosaScope .ControlPlane .Spec .RolesRef ),
302- OidcConfigId : rosaScope .ControlPlane .Spec .OIDCID ,
303- Mode : "auto" ,
304- Hypershift : ocm.Hypershift {
305- Enabled : true ,
306- },
307- BillingAccount : billingAccount ,
308- AWSCreator : creator ,
309- }
310-
311- if rosaScope .ControlPlane .Spec .EndpointAccess == rosacontrolplanev1 .Private {
312- ocmClusterSpec .Private = ptr .To (true )
313- ocmClusterSpec .PrivateLink = ptr .To (true )
314- }
315-
316- if networkSpec := rosaScope .ControlPlane .Spec .Network ; networkSpec != nil {
317- if networkSpec .MachineCIDR != "" {
318- _ , machineCIDR , err := net .ParseCIDR (networkSpec .MachineCIDR )
319- if err != nil {
320- return ctrl.Result {}, err
321- }
322- ocmClusterSpec .MachineCIDR = * machineCIDR
323- }
324-
325- if networkSpec .PodCIDR != "" {
326- _ , podCIDR , err := net .ParseCIDR (networkSpec .PodCIDR )
327- if err != nil {
328- return ctrl.Result {}, err
329- }
330- ocmClusterSpec .PodCIDR = * podCIDR
331- }
332-
333- if networkSpec .ServiceCIDR != "" {
334- _ , serviceCIDR , err := net .ParseCIDR (networkSpec .ServiceCIDR )
335- if err != nil {
336- return ctrl.Result {}, err
337- }
338- ocmClusterSpec .ServiceCIDR = * serviceCIDR
339- }
340-
341- ocmClusterSpec .HostPrefix = networkSpec .HostPrefix
342- ocmClusterSpec .NetworkType = networkSpec .NetworkType
343- }
344-
345- // Set cluster compute autoscaling replicas
346- if computeAutoscaling := rosaScope .ControlPlane .Spec .DefaultMachinePoolSpec .Autoscaling ; computeAutoscaling != nil {
347- ocmClusterSpec .MaxReplicas = computeAutoscaling .MaxReplicas
348- ocmClusterSpec .MinReplicas = computeAutoscaling .MinReplicas
279+ ocmClusterSpec , err := buildOCMClusterSpec (rosaScope .ControlPlane .Spec , creator )
280+ if err != nil {
281+ return ctrl.Result {}, err
349282 }
350283
351284 cluster , err = ocmClient .CreateCluster (ocmClusterSpec )
@@ -364,51 +297,6 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
364297 return ctrl.Result {}, nil
365298}
366299
367- func operatorIAMRoles (rolesRef rosacontrolplanev1.AWSRolesRef ) []ocm.OperatorIAMRole {
368- return []ocm.OperatorIAMRole {
369- {
370- Name : "cloud-credentials" ,
371- Namespace : "openshift-ingress-operator" ,
372- RoleARN : rolesRef .IngressARN ,
373- },
374- {
375- Name : "installer-cloud-credentials" ,
376- Namespace : "openshift-image-registry" ,
377- RoleARN : rolesRef .ImageRegistryARN ,
378- },
379- {
380- Name : "ebs-cloud-credentials" ,
381- Namespace : "openshift-cluster-csi-drivers" ,
382- RoleARN : rolesRef .StorageARN ,
383- },
384- {
385- Name : "cloud-credentials" ,
386- Namespace : "openshift-cloud-network-config-controller" ,
387- RoleARN : rolesRef .NetworkARN ,
388- },
389- {
390- Name : "kube-controller-manager" ,
391- Namespace : "kube-system" ,
392- RoleARN : rolesRef .KubeCloudControllerARN ,
393- },
394- {
395- Name : "kms-provider" ,
396- Namespace : "kube-system" ,
397- RoleARN : rolesRef .KMSProviderARN ,
398- },
399- {
400- Name : "control-plane-operator" ,
401- Namespace : "kube-system" ,
402- RoleARN : rolesRef .ControlPlaneOperatorARN ,
403- },
404- {
405- Name : "capa-controller-manager" ,
406- Namespace : "kube-system" ,
407- RoleARN : rolesRef .NodePoolManagementARN ,
408- },
409- }
410- }
411-
412300func (r * ROSAControlPlaneReconciler ) reconcileDelete (ctx context.Context , rosaScope * scope.ROSAControlPlaneScope ) (res ctrl.Result , reterr error ) {
413301 rosaScope .Info ("Reconciling ROSAControlPlane delete" )
414302
@@ -497,6 +385,29 @@ func (r *ROSAControlPlaneReconciler) reconcileClusterVersion(rosaScope *scope.RO
497385 return nil
498386}
499387
388+ func (r * ROSAControlPlaneReconciler ) updateOCMCluster (rosaScope * scope.ROSAControlPlaneScope , ocmClient * ocm.Client , cluster * cmv1.Cluster , creator * rosaaws.Creator ) error {
389+ currentAuditLogRole := cluster .AWS ().AuditLog ().RoleArn ()
390+ if currentAuditLogRole == rosaScope .ControlPlane .Spec .AuditLogRoleARN {
391+ return nil
392+ }
393+
394+ ocmClusterSpec := ocm.Spec {
395+ AuditLogRoleARN : ptr .To (rosaScope .ControlPlane .Spec .AuditLogRoleARN ),
396+ }
397+
398+ // if this fails, the provided role is likely invalid or it doesn't have the required permissions.
399+ if err := ocmClient .UpdateCluster (cluster .ID (), creator , ocmClusterSpec ); err != nil {
400+ conditions .MarkFalse (rosaScope .ControlPlane ,
401+ rosacontrolplanev1 .ROSAControlPlaneValidCondition ,
402+ rosacontrolplanev1 .ROSAControlPlaneInvalidConfigurationReason ,
403+ clusterv1 .ConditionSeverityError ,
404+ err .Error ())
405+ return err
406+ }
407+
408+ return nil
409+ }
410+
500411func (r * ROSAControlPlaneReconciler ) reconcileKubeconfig (ctx context.Context , rosaScope * scope.ROSAControlPlaneScope , ocmClient * ocm.Client , cluster * cmv1.Cluster ) error {
501412 rosaScope .Debug ("Reconciling ROSA kubeconfig for cluster" , "cluster-name" , rosaScope .RosaClusterName ())
502413
@@ -627,6 +538,131 @@ func validateControlPlaneSpec(ocmClient *ocm.Client, rosaScope *scope.ROSAContro
627538 return "" , nil
628539}
629540
541+ func buildOCMClusterSpec (controPlaneSpec rosacontrolplanev1.RosaControlPlaneSpec , creator * rosaaws.Creator ) (ocm.Spec , error ) {
542+ billingAccount := controPlaneSpec .BillingAccount
543+ if billingAccount == "" {
544+ billingAccount = creator .AccountID
545+ }
546+
547+ ocmClusterSpec := ocm.Spec {
548+ DryRun : ptr .To (false ),
549+ Name : controPlaneSpec .RosaClusterName ,
550+ Region : controPlaneSpec .Region ,
551+ MultiAZ : true ,
552+ Version : ocm .CreateVersionID (controPlaneSpec .Version , ocm .DefaultChannelGroup ),
553+ ChannelGroup : ocm .DefaultChannelGroup ,
554+ DisableWorkloadMonitoring : ptr .To (true ),
555+ DefaultIngress : ocm .NewDefaultIngressSpec (), // n.b. this is a no-op when it's set to the default value
556+ ComputeMachineType : controPlaneSpec .DefaultMachinePoolSpec .InstanceType ,
557+ AvailabilityZones : controPlaneSpec .AvailabilityZones ,
558+ Tags : controPlaneSpec .AdditionalTags ,
559+ EtcdEncryption : controPlaneSpec .EtcdEncryptionKMSARN != "" ,
560+ EtcdEncryptionKMSArn : controPlaneSpec .EtcdEncryptionKMSARN ,
561+
562+ SubnetIds : controPlaneSpec .Subnets ,
563+ IsSTS : true ,
564+ RoleARN : controPlaneSpec .InstallerRoleARN ,
565+ SupportRoleARN : controPlaneSpec .SupportRoleARN ,
566+ WorkerRoleARN : controPlaneSpec .WorkerRoleARN ,
567+ OperatorIAMRoles : operatorIAMRoles (controPlaneSpec .RolesRef ),
568+ OidcConfigId : controPlaneSpec .OIDCID ,
569+ Mode : "auto" ,
570+ Hypershift : ocm.Hypershift {
571+ Enabled : true ,
572+ },
573+ BillingAccount : billingAccount ,
574+ AWSCreator : creator ,
575+ AuditLogRoleARN : ptr .To (controPlaneSpec .AuditLogRoleARN ),
576+ }
577+
578+ if controPlaneSpec .EndpointAccess == rosacontrolplanev1 .Private {
579+ ocmClusterSpec .Private = ptr .To (true )
580+ ocmClusterSpec .PrivateLink = ptr .To (true )
581+ }
582+
583+ if networkSpec := controPlaneSpec .Network ; networkSpec != nil {
584+ if networkSpec .MachineCIDR != "" {
585+ _ , machineCIDR , err := net .ParseCIDR (networkSpec .MachineCIDR )
586+ if err != nil {
587+ return ocmClusterSpec , err
588+ }
589+ ocmClusterSpec .MachineCIDR = * machineCIDR
590+ }
591+
592+ if networkSpec .PodCIDR != "" {
593+ _ , podCIDR , err := net .ParseCIDR (networkSpec .PodCIDR )
594+ if err != nil {
595+ return ocmClusterSpec , err
596+ }
597+ ocmClusterSpec .PodCIDR = * podCIDR
598+ }
599+
600+ if networkSpec .ServiceCIDR != "" {
601+ _ , serviceCIDR , err := net .ParseCIDR (networkSpec .ServiceCIDR )
602+ if err != nil {
603+ return ocmClusterSpec , err
604+ }
605+ ocmClusterSpec .ServiceCIDR = * serviceCIDR
606+ }
607+
608+ ocmClusterSpec .HostPrefix = networkSpec .HostPrefix
609+ ocmClusterSpec .NetworkType = networkSpec .NetworkType
610+ }
611+
612+ // Set cluster compute autoscaling replicas
613+ if computeAutoscaling := controPlaneSpec .DefaultMachinePoolSpec .Autoscaling ; computeAutoscaling != nil {
614+ ocmClusterSpec .MaxReplicas = computeAutoscaling .MaxReplicas
615+ ocmClusterSpec .MinReplicas = computeAutoscaling .MinReplicas
616+ }
617+
618+ return ocmClusterSpec , nil
619+ }
620+
621+ func operatorIAMRoles (rolesRef rosacontrolplanev1.AWSRolesRef ) []ocm.OperatorIAMRole {
622+ return []ocm.OperatorIAMRole {
623+ {
624+ Name : "cloud-credentials" ,
625+ Namespace : "openshift-ingress-operator" ,
626+ RoleARN : rolesRef .IngressARN ,
627+ },
628+ {
629+ Name : "installer-cloud-credentials" ,
630+ Namespace : "openshift-image-registry" ,
631+ RoleARN : rolesRef .ImageRegistryARN ,
632+ },
633+ {
634+ Name : "ebs-cloud-credentials" ,
635+ Namespace : "openshift-cluster-csi-drivers" ,
636+ RoleARN : rolesRef .StorageARN ,
637+ },
638+ {
639+ Name : "cloud-credentials" ,
640+ Namespace : "openshift-cloud-network-config-controller" ,
641+ RoleARN : rolesRef .NetworkARN ,
642+ },
643+ {
644+ Name : "kube-controller-manager" ,
645+ Namespace : "kube-system" ,
646+ RoleARN : rolesRef .KubeCloudControllerARN ,
647+ },
648+ {
649+ Name : "kms-provider" ,
650+ Namespace : "kube-system" ,
651+ RoleARN : rolesRef .KMSProviderARN ,
652+ },
653+ {
654+ Name : "control-plane-operator" ,
655+ Namespace : "kube-system" ,
656+ RoleARN : rolesRef .ControlPlaneOperatorARN ,
657+ },
658+ {
659+ Name : "capa-controller-manager" ,
660+ Namespace : "kube-system" ,
661+ RoleARN : rolesRef .NodePoolManagementARN ,
662+ },
663+ }
664+ }
665+
630666func (r * ROSAControlPlaneReconciler ) rosaClusterToROSAControlPlane (log * logger.Logger ) handler.MapFunc {
631667 return func (ctx context.Context , o client.Object ) []ctrl.Request {
632668 rosaCluster , ok := o .(* expinfrav1.ROSACluster )
0 commit comments