@@ -315,30 +315,6 @@ func (a *Operator) ensureRBACInTargetNamespace(csv *v1alpha1.ClusterServiceVersi
315315 return nil
316316 }
317317
318- // otherwise, create roles/rolebindings for each target namespace
319- for _ , ns := range targetNamespaces {
320- if ns == operatorGroup .GetNamespace () {
321- continue
322- }
323-
324- permMet , _ , err := a .permissionStatus (strategyDetailsDeployment , ruleChecker , ns , csv .GetNamespace ())
325- if err != nil {
326- logger .WithError (err ).Debug ("permission status" )
327- return err
328- }
329- logger .WithField ("target" , ns ).WithField ("permMet" , permMet ).Debug ("permission status" )
330-
331- // operator already has access in the target namespace
332- if permMet {
333- logger .Debug ("operator has access" )
334- continue
335- }
336-
337- if err := a .ensureTenantRBAC (operatorGroup .GetNamespace (), ns , csv ); err != nil {
338- logger .WithError (err ).Debug ("ensuring tenant rbac" )
339- return err
340- }
341- }
342318 return nil
343319}
344320
@@ -413,15 +389,11 @@ func (a *Operator) ensureSingletonRBAC(operatorNamespace string, csv *v1alpha1.C
413389 return nil
414390}
415391
416- func (a * Operator ) ensureTenantRBAC (operatorNamespace , targetNamespace string , csv * v1alpha1.ClusterServiceVersion ) error {
392+ func (a * Operator ) ensureTenantRBAC (operatorNamespace , targetNamespace string , csv * v1alpha1.ClusterServiceVersion , targetCSV * v1alpha1. ClusterServiceVersion ) error {
417393 if operatorNamespace == targetNamespace {
418394 return nil
419395 }
420396
421- targetCSV , err := a .lister .OperatorsV1alpha1 ().ClusterServiceVersionLister ().ClusterServiceVersions (targetNamespace ).Get (csv .GetName ())
422- if err != nil {
423- return err
424- }
425397 ownerSelector := ownerutil .CSVOwnerSelector (csv )
426398 ownedRoles , err := a .lister .RbacV1 ().RoleLister ().Roles (operatorNamespace ).List (ownerSelector )
427399 if err != nil {
@@ -525,27 +497,74 @@ func (a *Operator) ensureCSVsInNamespaces(csv *v1alpha1.ClusterServiceVersion, o
525497 if err != nil {
526498 return err
527499 }
500+
501+ strategyResolver := install.StrategyResolver {}
502+ strategy , err := strategyResolver .UnmarshalStrategy (csv .Spec .InstallStrategy )
503+ if err != nil {
504+ return err
505+ }
506+ strategyDetailsDeployment , ok := strategy .(* install.StrategyDetailsDeployment )
507+ if ! ok {
508+ return fmt .Errorf ("could not cast install strategy as type %T" , strategyDetailsDeployment )
509+ }
510+ ruleChecker := install .NewCSVRuleChecker (a .lister .RbacV1 ().RoleLister (), a .lister .RbacV1 ().RoleBindingLister (), a .lister .RbacV1 ().ClusterRoleLister (), a .lister .RbacV1 ().ClusterRoleBindingLister (), csv )
511+
512+ logger := a .Log .WithField ("opgroup" , operatorGroup .GetName ()).WithField ("csv" , csv .GetName ())
513+
514+ targetCSVs := make (map [string ]* v1alpha1.ClusterServiceVersion )
528515 for _ , ns := range namespaces {
529516 if ns .GetName () == operatorGroup .Namespace {
530517 continue
531518 }
532519 if targets .Contains (ns .GetName ()) {
533- if err := a .copyToNamespace (csv , ns .GetName ()); err != nil {
520+ var targetCSV * v1alpha1.ClusterServiceVersion
521+ if targetCSV , err = a .copyToNamespace (csv , ns .GetName ()); err != nil {
534522 a .Log .WithError (err ).Debug ("error copying to target" )
535523 }
524+ targetCSVs [ns .GetName ()] = targetCSV
536525 } else {
537526 if err := a .pruneFromNamespace (operatorGroup .GetName (), ns .GetName ()); err != nil {
538527 a .Log .WithError (err ).Debug ("error pruning from old target" )
539528 }
540529 }
541530 }
542531
532+ targetNamespaces := operatorGroup .Status .Namespaces
533+ if targetNamespaces == nil {
534+ a .Log .Errorf ("operatorgroup '%v' should have non-nil status" , operatorGroup .GetName ())
535+ return nil
536+ }
537+ for _ , ns := range targetNamespaces {
538+ // create roles/rolebindings for each target namespace
539+ permMet , _ , err := a .permissionStatus (strategyDetailsDeployment , ruleChecker , ns , csv .GetNamespace ())
540+ if err != nil {
541+ logger .WithError (err ).Debug ("permission status" )
542+ return err
543+ }
544+ logger .WithField ("target" , ns ).WithField ("permMet" , permMet ).Debug ("permission status" )
545+
546+ // operator already has access in the target namespace
547+ if permMet {
548+ logger .Debug ("operator has access" )
549+ continue
550+ }
551+
552+ targetCSV , ok := targetCSVs [ns ]
553+ if ! ok {
554+ return fmt .Errorf ("bug: no target CSV for namespace %v" , ns )
555+ }
556+ if err := a .ensureTenantRBAC (operatorGroup .GetNamespace (), ns , csv , targetCSV ); err != nil {
557+ logger .WithError (err ).Debug ("ensuring tenant rbac" )
558+ return err
559+ }
560+ }
561+
543562 return nil
544563}
545564
546- func (a * Operator ) copyToNamespace (csv * v1alpha1.ClusterServiceVersion , namespace string ) error {
565+ func (a * Operator ) copyToNamespace (csv * v1alpha1.ClusterServiceVersion , namespace string ) ( * v1alpha1. ClusterServiceVersion , error ) {
547566 if csv .GetNamespace () == namespace {
548- return nil
567+ return nil , fmt . Errorf ( "bug: can not copy to active namespace %v" , csv . GetNamespace ())
549568 }
550569
551570 logger := a .Log .WithField ("operator-ns" , csv .GetNamespace ()).WithField ("target-ns" , namespace )
@@ -566,7 +585,7 @@ func (a *Operator) copyToNamespace(csv *v1alpha1.ClusterServiceVersion, namespac
566585 logger .Debug ("updating target CSV" )
567586 if _ , err := a .client .OperatorsV1alpha1 ().ClusterServiceVersions (namespace ).Update (fetchedCSV ); err != nil {
568587 logger .WithError (err ).Error ("update target CSV failed" )
569- return err
588+ return nil , err
570589 }
571590 }
572591
@@ -582,10 +601,12 @@ func (a *Operator) copyToNamespace(csv *v1alpha1.ClusterServiceVersion, namespac
582601 fetchedCSV .Status .LastUpdateTime = timeNow ()
583602 if _ , err := a .client .OperatorsV1alpha1 ().ClusterServiceVersions (namespace ).UpdateStatus (fetchedCSV ); err != nil {
584603 logger .WithError (err ).Error ("status update for target CSV failed" )
585- return err
604+ return nil , err
586605 }
587606 }
588607
608+ return fetchedCSV , nil
609+
589610 } else if k8serrors .IsNotFound (err ) {
590611 newCSV .SetNamespace (namespace )
591612 newCSV .SetResourceVersion ("" )
@@ -595,21 +616,25 @@ func (a *Operator) copyToNamespace(csv *v1alpha1.ClusterServiceVersion, namespac
595616 createdCSV , err := a .client .OperatorsV1alpha1 ().ClusterServiceVersions (namespace ).Create (newCSV )
596617 if err != nil {
597618 a .Log .Errorf ("Create for new CSV failed: %v" , err )
598- return err
619+ return nil , err
599620 }
600621 createdCSV .Status .Reason = v1alpha1 .CSVReasonCopied
601622 createdCSV .Status .Message = fmt .Sprintf ("The operator is running in %s but is managing this namespace" , csv .GetNamespace ())
602623 createdCSV .Status .LastUpdateTime = timeNow ()
603624 if _ , err := a .client .OperatorsV1alpha1 ().ClusterServiceVersions (namespace ).UpdateStatus (createdCSV ); err != nil {
604625 a .Log .Errorf ("Status update for CSV failed: %v" , err )
605- return err
626+ return nil , err
606627 }
607628
629+ return createdCSV , nil
630+
608631 } else if err != nil {
609632 logger .WithError (err ).Error ("couldn't get CSV" )
610- return err
633+ return nil , err
611634 }
612- return nil
635+
636+ // this return shouldn't be hit
637+ return nil , fmt .Errorf ("unhandled code path" )
613638}
614639
615640func (a * Operator ) pruneFromNamespace (operatorGroupName , namespace string ) error {
0 commit comments