@@ -458,6 +458,293 @@ func TestClusterScope_ReconcileRouteTable(t *testing.T) {
458458	}
459459}
460460
461+ func  TestClusterScope_CreateRouteTable (t  * testing.T ) {
462+ 	type  args  struct  {
463+ 		routeTableType  string 
464+ 		spec            infrastructurev1beta2.OCIClusterSpec 
465+ 		setupMock       func (t  * testing.T , vcn  * mock_vcn.MockClient )
466+ 	}
467+ 	tests  :=  []struct  {
468+ 		name                  string 
469+ 		args                  args 
470+ 		wantErr               bool 
471+ 		expectedErrorMessage  string 
472+ 	}{
473+ 		{
474+ 			name : "private without peering (NAT + Service routes only)" ,
475+ 			args : args {
476+ 				routeTableType : infrastructurev1beta2 .Private ,
477+ 				spec : infrastructurev1beta2.OCIClusterSpec {
478+ 					CompartmentId : "comp" ,
479+ 					NetworkSpec : infrastructurev1beta2.NetworkSpec {
480+ 						Vcn : infrastructurev1beta2.VCN {
481+ 							ID : common .String ("vcn1" ),
482+ 							NATGateway : infrastructurev1beta2.NATGateway {
483+ 								Id : common .String ("ngw" ),
484+ 							},
485+ 							ServiceGateway : infrastructurev1beta2.ServiceGateway {
486+ 								Id : common .String ("sgw" ),
487+ 							},
488+ 						},
489+ 					},
490+ 				},
491+ 				setupMock : func (t  * testing.T , vcn  * mock_vcn.MockClient ) {
492+ 					_  =  core.CreateRouteTableRequest {
493+ 						CreateRouteTableDetails : core.CreateRouteTableDetails {
494+ 							VcnId :         common .String ("vcn1" ),
495+ 							CompartmentId : common .String ("comp" ),
496+ 							DisplayName :   common .String (PrivateRouteTableName ),
497+ 							FreeformTags :  map [string ]string {},
498+ 							DefinedTags :   map [string ]map [string ]interface {}{},
499+ 							RouteRules : []core.RouteRule {
500+ 								{
501+ 									DestinationType : core .RouteRuleDestinationTypeCidrBlock ,
502+ 									Destination :     common .String ("0.0.0.0/0" ),
503+ 									NetworkEntityId : common .String ("ngw" ),
504+ 									Description :     common .String ("traffic to the internet" ),
505+ 								},
506+ 								{
507+ 									DestinationType : core .RouteRuleDestinationTypeServiceCidrBlock ,
508+ 									Destination :     common .String ("all-iad-services-in-oracle-services-network" ),
509+ 									NetworkEntityId : common .String ("sgw" ),
510+ 									Description :     common .String ("traffic to OCI services" ),
511+ 								},
512+ 							},
513+ 						},
514+ 					}
515+ 					vcn .EXPECT ().
516+ 						CreateRouteTable (gomock .Any (), gomock .Any ()).
517+ 						DoAndReturn (func (_  context.Context , req  core.CreateRouteTableRequest ) (core.CreateRouteTableResponse , error ) {
518+ 							// Validate core fields; ignore tags differences 
519+ 							if  req .CreateRouteTableDetails .VcnId  ==  nil  ||  * req .CreateRouteTableDetails .VcnId  !=  "vcn1"  {
520+ 								t .Errorf ("expected VcnId=vcn1, got %v" , req .CreateRouteTableDetails .VcnId )
521+ 							}
522+ 							if  req .CreateRouteTableDetails .CompartmentId  ==  nil  ||  * req .CreateRouteTableDetails .CompartmentId  !=  "comp"  {
523+ 								t .Errorf ("expected CompartmentId=comp, got %v" , req .CreateRouteTableDetails .CompartmentId )
524+ 							}
525+ 							if  req .CreateRouteTableDetails .DisplayName  ==  nil  ||  * req .CreateRouteTableDetails .DisplayName  !=  PrivateRouteTableName  {
526+ 								t .Errorf ("expected DisplayName=%s, got %v" , PrivateRouteTableName , req .CreateRouteTableDetails .DisplayName )
527+ 							}
528+ 							rr  :=  req .CreateRouteTableDetails .RouteRules 
529+ 							if  len (rr ) !=  2  {
530+ 								t .Fatalf ("expected 2 route rules, got %d" , len (rr ))
531+ 							}
532+ 							// NAT route 
533+ 							if  rr [0 ].Destination  ==  nil  ||  * rr [0 ].Destination  !=  "0.0.0.0/0"  {
534+ 								t .Errorf ("expected rule[0] dest 0.0.0.0/0, got %v" , rr [0 ].Destination )
535+ 							}
536+ 							if  rr [0 ].NetworkEntityId  ==  nil  ||  * rr [0 ].NetworkEntityId  !=  "ngw"  {
537+ 								t .Errorf ("expected rule[0] NEI=ngw, got %v" , rr [0 ].NetworkEntityId )
538+ 							}
539+ 							// Service gateway route 
540+ 							if  rr [1 ].Destination  ==  nil  ||  * rr [1 ].Destination  !=  "all-iad-services-in-oracle-services-network"  {
541+ 								t .Errorf ("expected rule[1] dest all-iad-services-in-oracle-services-network, got %v" , rr [1 ].Destination )
542+ 							}
543+ 							if  rr [1 ].NetworkEntityId  ==  nil  ||  * rr [1 ].NetworkEntityId  !=  "sgw"  {
544+ 								t .Errorf ("expected rule[1] NEI=sgw, got %v" , rr [1 ].NetworkEntityId )
545+ 							}
546+ 							return  core.CreateRouteTableResponse {RouteTable : core.RouteTable {Id : common .String ("rt" )}}, nil 
547+ 						})
548+ 				},
549+ 			},
550+ 			wantErr : false ,
551+ 		},
552+ 		{
553+ 			name : "private with peering (adds DRG peer routes)" ,
554+ 			args : args {
555+ 				routeTableType : infrastructurev1beta2 .Private ,
556+ 				spec : infrastructurev1beta2.OCIClusterSpec {
557+ 					CompartmentId : "comp" ,
558+ 					NetworkSpec : infrastructurev1beta2.NetworkSpec {
559+ 						VCNPeering : & infrastructurev1beta2.VCNPeering {
560+ 							DRG : & infrastructurev1beta2.DRG {ID : common .String ("drg-id" )},
561+ 							PeerRouteRules : []infrastructurev1beta2.PeerRouteRule {
562+ 								{VCNCIDRRange : "10.1.0.0/16" },
563+ 							},
564+ 						},
565+ 						Vcn : infrastructurev1beta2.VCN {
566+ 							ID : common .String ("vcn1" ),
567+ 							NATGateway : infrastructurev1beta2.NATGateway {
568+ 								Id : common .String ("ngw" ),
569+ 							},
570+ 							ServiceGateway : infrastructurev1beta2.ServiceGateway {
571+ 								Id : common .String ("sgw" ),
572+ 							},
573+ 						},
574+ 					},
575+ 				},
576+ 				setupMock : func (t  * testing.T , vcn  * mock_vcn.MockClient ) {
577+ 					_  =  core.CreateRouteTableRequest {
578+ 						CreateRouteTableDetails : core.CreateRouteTableDetails {
579+ 							VcnId :         common .String ("vcn1" ),
580+ 							CompartmentId : common .String ("comp" ),
581+ 							DisplayName :   common .String (PrivateRouteTableName ),
582+ 							FreeformTags :  map [string ]string {},
583+ 							DefinedTags :   map [string ]map [string ]interface {}{},
584+ 							RouteRules : []core.RouteRule {
585+ 								{
586+ 									DestinationType : core .RouteRuleDestinationTypeCidrBlock ,
587+ 									Destination :     common .String ("0.0.0.0/0" ),
588+ 									NetworkEntityId : common .String ("ngw" ),
589+ 									Description :     common .String ("traffic to the internet" ),
590+ 								},
591+ 								{
592+ 									DestinationType : core .RouteRuleDestinationTypeServiceCidrBlock ,
593+ 									Destination :     common .String ("all-iad-services-in-oracle-services-network" ),
594+ 									NetworkEntityId : common .String ("sgw" ),
595+ 									Description :     common .String ("traffic to OCI services" ),
596+ 								},
597+ 								{
598+ 									DestinationType : core .RouteRuleDestinationTypeCidrBlock ,
599+ 									Destination :     common .String ("10.1.0.0/16" ),
600+ 									NetworkEntityId : common .String ("drg-id" ),
601+ 									Description :     common .String ("traffic to peer DRG" ),
602+ 								},
603+ 							},
604+ 						},
605+ 					}
606+ 					vcn .EXPECT ().
607+ 						CreateRouteTable (gomock .Any (), gomock .Any ()).
608+ 						DoAndReturn (func (_  context.Context , req  core.CreateRouteTableRequest ) (core.CreateRouteTableResponse , error ) {
609+ 							// Validate core fields; ignore tags differences 
610+ 							if  req .CreateRouteTableDetails .VcnId  ==  nil  ||  * req .CreateRouteTableDetails .VcnId  !=  "vcn1"  {
611+ 								t .Errorf ("expected VcnId=vcn1, got %v" , req .CreateRouteTableDetails .VcnId )
612+ 							}
613+ 							if  req .CreateRouteTableDetails .CompartmentId  ==  nil  ||  * req .CreateRouteTableDetails .CompartmentId  !=  "comp"  {
614+ 								t .Errorf ("expected CompartmentId=comp, got %v" , req .CreateRouteTableDetails .CompartmentId )
615+ 							}
616+ 							if  req .CreateRouteTableDetails .DisplayName  ==  nil  ||  * req .CreateRouteTableDetails .DisplayName  !=  PrivateRouteTableName  {
617+ 								t .Errorf ("expected DisplayName=%s, got %v" , PrivateRouteTableName , req .CreateRouteTableDetails .DisplayName )
618+ 							}
619+ 							rr  :=  req .CreateRouteTableDetails .RouteRules 
620+ 							if  len (rr ) !=  3  {
621+ 								t .Fatalf ("expected 3 route rules, got %d" , len (rr ))
622+ 							}
623+ 							// NAT route 
624+ 							if  rr [0 ].Destination  ==  nil  ||  * rr [0 ].Destination  !=  "0.0.0.0/0"  {
625+ 								t .Errorf ("expected rule[0] dest 0.0.0.0/0, got %v" , rr [0 ].Destination )
626+ 							}
627+ 							if  rr [0 ].NetworkEntityId  ==  nil  ||  * rr [0 ].NetworkEntityId  !=  "ngw"  {
628+ 								t .Errorf ("expected rule[0] NEI=ngw, got %v" , rr [0 ].NetworkEntityId )
629+ 							}
630+ 							// Service gateway route 
631+ 							if  rr [1 ].Destination  ==  nil  ||  * rr [1 ].Destination  !=  "all-iad-services-in-oracle-services-network"  {
632+ 								t .Errorf ("expected rule[1] dest all-iad-services-in-oracle-services-network, got %v" , rr [1 ].Destination )
633+ 							}
634+ 							if  rr [1 ].NetworkEntityId  ==  nil  ||  * rr [1 ].NetworkEntityId  !=  "sgw"  {
635+ 								t .Errorf ("expected rule[1] NEI=sgw, got %v" , rr [1 ].NetworkEntityId )
636+ 							}
637+ 							// DRG peering route 
638+ 							if  rr [2 ].Destination  ==  nil  ||  * rr [2 ].Destination  !=  "10.1.0.0/16"  {
639+ 								t .Errorf ("expected rule[2] dest 10.1.0.0/16, got %v" , rr [2 ].Destination )
640+ 							}
641+ 							if  rr [2 ].NetworkEntityId  ==  nil  ||  * rr [2 ].NetworkEntityId  !=  "drg-id"  {
642+ 								t .Errorf ("expected rule[2] NEI=drg-id, got %v" , rr [2 ].NetworkEntityId )
643+ 							}
644+ 							return  core.CreateRouteTableResponse {RouteTable : core.RouteTable {Id : common .String ("rt" )}}, nil 
645+ 						})
646+ 				},
647+ 			},
648+ 			wantErr : false ,
649+ 		},
650+ 		{
651+ 			name : "private with peering but DRG is nil" ,
652+ 			args : args {
653+ 				routeTableType : infrastructurev1beta2 .Private ,
654+ 				spec : infrastructurev1beta2.OCIClusterSpec {
655+ 					CompartmentId : "comp" ,
656+ 					NetworkSpec : infrastructurev1beta2.NetworkSpec {
657+ 						VCNPeering : & infrastructurev1beta2.VCNPeering {
658+ 							DRG :                      nil , // Intentionally set to nil 
659+ 							PeerRouteRules :           []infrastructurev1beta2.PeerRouteRule {{VCNCIDRRange : "10.1.0.0/16" }},
660+ 							RemotePeeringConnections : nil ,
661+ 						},
662+ 						Vcn : infrastructurev1beta2.VCN {
663+ 							ID : common .String ("vcn1" ),
664+ 							NATGateway : infrastructurev1beta2.NATGateway {
665+ 								Id : common .String ("ngw" ),
666+ 							},
667+ 							ServiceGateway : infrastructurev1beta2.ServiceGateway {
668+ 								Id : common .String ("sgw" ),
669+ 							},
670+ 						},
671+ 					},
672+ 				},
673+ 				setupMock : func (t  * testing.T , vcn  * mock_vcn.MockClient ) {
674+ 					// No CreateRouteTable call expected because we error out before 
675+ 					vcn .EXPECT ().CreateRouteTable (gomock .Any (), gomock .Any ()).Times (0 )
676+ 				},
677+ 			},
678+ 			wantErr :              true ,
679+ 			expectedErrorMessage : "Create Route Table: DRG has not been specified" ,
680+ 		},
681+ 		{
682+ 			name : "private with peering but DRG ID is nil" ,
683+ 			args : args {
684+ 				routeTableType : infrastructurev1beta2 .Private ,
685+ 				spec : infrastructurev1beta2.OCIClusterSpec {
686+ 					CompartmentId : "comp" ,
687+ 					NetworkSpec : infrastructurev1beta2.NetworkSpec {
688+ 						VCNPeering : & infrastructurev1beta2.VCNPeering {
689+ 							DRG :            & infrastructurev1beta2.DRG {ID : nil },
690+ 							PeerRouteRules : []infrastructurev1beta2.PeerRouteRule {{VCNCIDRRange : "10.1.0.0/16" }},
691+ 						},
692+ 						Vcn : infrastructurev1beta2.VCN {
693+ 							ID : common .String ("vcn1" ),
694+ 							NATGateway : infrastructurev1beta2.NATGateway {
695+ 								Id : common .String ("ngw" ),
696+ 							},
697+ 							ServiceGateway : infrastructurev1beta2.ServiceGateway {
698+ 								Id : common .String ("sgw" ),
699+ 							},
700+ 						},
701+ 					},
702+ 				},
703+ 				setupMock : func (t  * testing.T , vcn  * mock_vcn.MockClient ) {
704+ 					// No CreateRouteTable call expected because we error out before 
705+ 					vcn .EXPECT ().CreateRouteTable (gomock .Any (), gomock .Any ()).Times (0 )
706+ 				},
707+ 			},
708+ 			wantErr :              true ,
709+ 			expectedErrorMessage : "Create Route Table: DRG ID has not been set" ,
710+ 		},
711+ 	}
712+ 
713+ 	for  _ , tt  :=  range  tests  {
714+ 		tt  :=  tt 
715+ 		t .Run (tt .name , func (t  * testing.T ) {
716+ 			mockCtrl  :=  gomock .NewController (t )
717+ 			defer  mockCtrl .Finish ()
718+ 			vcnClient  :=  mock_vcn .NewMockClient (mockCtrl )
719+ 			if  tt .args .setupMock  !=  nil  {
720+ 				tt .args .setupMock (t , vcnClient )
721+ 			}
722+ 
723+ 			l  :=  log .FromContext (context .Background ())
724+ 			ociClusterAccessor  :=  OCISelfManagedCluster {
725+ 				OCICluster : & infrastructurev1beta2.OCICluster {
726+ 					ObjectMeta : metav1.ObjectMeta {UID : "cluster_uid" },
727+ 					Spec :       tt .args .spec ,
728+ 				},
729+ 			}
730+ 			s  :=  & ClusterScope {
731+ 				VCNClient :          vcnClient ,
732+ 				OCIClusterAccessor : ociClusterAccessor ,
733+ 				Logger :             & l ,
734+ 				RegionKey :          "iad" ,
735+ 			}
736+ 
737+ 			_ , err  :=  s .CreateRouteTable (context .Background (), tt .args .routeTableType )
738+ 			if  (err  !=  nil ) !=  tt .wantErr  {
739+ 				t .Fatalf ("CreateRouteTable() error = %v, wantErr %v" , err , tt .wantErr )
740+ 			}
741+ 			if  err  !=  nil  &&  tt .expectedErrorMessage  !=  ""  &&  err .Error () !=  tt .expectedErrorMessage  {
742+ 				t .Fatalf ("CreateRouteTable() expected error = %q, got %q" , tt .expectedErrorMessage , err .Error ())
743+ 			}
744+ 		})
745+ 	}
746+ }
747+ 
461748func  TestClusterScope_DeleteRouteTables (t  * testing.T ) {
462749	mockCtrl  :=  gomock .NewController (t )
463750	defer  mockCtrl .Finish ()
0 commit comments