@@ -285,15 +285,15 @@ var _ = Describe("getIsolatedCredentials", func() {
285285 defer server .Close ()
286286
287287 client := & http.Client {}
288- ip , err := checkEgressIP (client , server .URL )
288+ ip , err := CheckEgressIP (client , server .URL )
289289
290290 Expect (err ).NotTo (HaveOccurred ())
291291 Expect (ip ).To (Equal (net .ParseIP (mockIP )))
292292 })
293293 It ("should return an error when the HTTP GET fails" , func () {
294294 client = & http.Client {}
295295 // Invalid URL to force error
296- ip , err := checkEgressIP (client , "http://invalid_url" )
296+ ip , err := CheckEgressIP (client , "http://invalid_url" )
297297 Expect (err ).To (HaveOccurred ())
298298 Expect (ip ).To (BeNil ())
299299 })
@@ -303,7 +303,7 @@ var _ = Describe("getIsolatedCredentials", func() {
303303 }))
304304 client = server .Client ()
305305
306- ip , err := checkEgressIP (client , server .URL )
306+ ip , err := CheckEgressIP (client , server .URL )
307307 Expect (err ).To (MatchError (ContainSubstring ("failed to parse IP" )))
308308 Expect (ip ).To (BeNil ())
309309 })
@@ -359,6 +359,85 @@ var _ = Describe("getIsolatedCredentials", func() {
359359 Expect (err ).To (BeNil ())
360360 })
361361 })
362+
363+ Context ("Execute verifyTrustedIPAndGetPolicy" , func () {
364+ It ("should successfully verify IP and return policy when IP is in trusted range" , func () {
365+ // Mock the IP check to return a valid IP
366+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
367+ fmt .Fprint (w , "209.10.10.10" ) // IP that matches our test trusted range
368+ }))
369+ defer server .Close ()
370+
371+ // Override the checkEgressIP function to use our test server
372+ originalCheckEgressIP := CheckEgressIP
373+ CheckEgressIP = func (client * http.Client , url string ) (net.IP , error ) {
374+ return originalCheckEgressIP (client , server .URL )
375+ }
376+ defer func () {
377+ CheckEgressIP = originalCheckEgressIP
378+ }()
379+
380+ // Set up expected trusted IP list
381+ ip1 := cmv1 .NewTrustedIp ().ID ("209.10.10.10" ).Enabled (true )
382+ expectedIPList , err := cmv1 .NewTrustedIpList ().Items (ip1 ).Build ()
383+ Expect (err ).To (BeNil ())
384+ mockOcmInterface .EXPECT ().GetTrustedIPList (gomock .Any ()).Return (expectedIPList , nil )
385+
386+ // Call the function
387+ policy , err := verifyTrustedIPAndGetPolicy (& testQueryConfig )
388+
389+ // Verify success
390+ Expect (err ).To (BeNil ())
391+ Expect (policy .Version ).To (Equal ("2012-10-17" ))
392+ Expect (len (policy .Statement )).To (BeNumerically (">" , 0 ))
393+ })
394+
395+ It ("should fail when client IP is not in trusted range" , func () {
396+ // Mock the IP check to return an untrusted IP
397+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
398+ fmt .Fprint (w , "192.168.1.1" ) // IP that doesn't match our test trusted range
399+ }))
400+ defer server .Close ()
401+
402+ // Override the checkEgressIP function to use our test server
403+ originalCheckEgressIP := CheckEgressIP
404+ CheckEgressIP = func (client * http.Client , url string ) (net.IP , error ) {
405+ return originalCheckEgressIP (client , server .URL )
406+ }
407+ defer func () {
408+ CheckEgressIP = originalCheckEgressIP
409+ }()
410+
411+ // Set up expected trusted IP list (only has 209.x.x.x IPs)
412+ ip1 := cmv1 .NewTrustedIp ().ID ("209.10.10.10" ).Enabled (true )
413+ expectedIPList , err := cmv1 .NewTrustedIpList ().Items (ip1 ).Build ()
414+ Expect (err ).To (BeNil ())
415+ mockOcmInterface .EXPECT ().GetTrustedIPList (gomock .Any ()).Return (expectedIPList , nil )
416+
417+ // Call the function
418+ _ , err = verifyTrustedIPAndGetPolicy (& testQueryConfig )
419+
420+ // Verify failure
421+ Expect (err ).To (HaveOccurred ())
422+ Expect (err .Error ()).To (ContainSubstring ("client IP 192.168.1.1 is not in the trusted IP range" ))
423+ })
424+
425+ It ("should fail when proxy URL is invalid" , func () {
426+ // Set an invalid proxy URL
427+ invalidProxyURL := "://invalid-url"
428+ testQueryConfig .BackplaneConfiguration .ProxyURL = & invalidProxyURL
429+
430+ // Call the function
431+ _ , err := verifyTrustedIPAndGetPolicy (& testQueryConfig )
432+
433+ // Verify failure
434+ Expect (err ).To (HaveOccurred ())
435+ Expect (err .Error ()).To (ContainSubstring ("failed to parse proxy URL" ))
436+
437+ // Reset proxy URL
438+ testQueryConfig .BackplaneConfiguration .ProxyURL = nil
439+ })
440+ })
362441})
363442
364443// newTestCluster assembles a *cmv1.Cluster while handling the error to help out with inline test-case generation
@@ -537,6 +616,19 @@ var _ = Describe("PolicyARNs Integration", func() {
537616
538617 // Helper function to simulate the getIsolatedCredentials logic
539618 simulateGetIsolatedCredentialsLogic := func (roleChainResponse assumeChainResponse ) []awsutil.RoleArnSession {
619+ // Create a mock inline policy for testing
620+ mockInlinePolicy := & awsutil.PolicyDocument {
621+ Version : "2012-10-17" ,
622+ Statement : []awsutil.PolicyStatement {
623+ {
624+ Sid : "TestPolicy" ,
625+ Effect : "Allow" ,
626+ Action : []string {"s3:GetObject" },
627+ Resource : aws .String ("*" ),
628+ },
629+ },
630+ }
631+
540632 assumeRoleArnSessionSequence := make ([]awsutil.RoleArnSession , 0 , len (roleChainResponse .AssumptionSequence ))
541633 for _ , namedRoleArnEntry := range roleChainResponse .AssumptionSequence {
542634 roleArnSession := awsutil.RoleArnSession {RoleArn : namedRoleArnEntry .Arn }
@@ -550,14 +642,18 @@ var _ = Describe("PolicyARNs Integration", func() {
550642 roleArnSession .PolicyARNs = []types.PolicyDescriptorType {}
551643 if namedRoleArnEntry .Name == CustomerRoleArnName {
552644 roleArnSession .IsCustomerRole = true
645+
553646 // Add the session policy ARN for selected roles
554647 if roleChainResponse .SessionPolicyArn != "" {
555648 roleArnSession .PolicyARNs = []types.PolicyDescriptorType {
556649 {
557650 Arn : aws .String (roleChainResponse .SessionPolicyArn ),
558651 },
559652 }
653+ } else {
654+ roleArnSession .Policy = mockInlinePolicy
560655 }
656+
561657 } else {
562658 roleArnSession .IsCustomerRole = false
563659 }
@@ -591,6 +687,8 @@ var _ = Describe("PolicyARNs Integration", func() {
591687 Expect (customerRole .Name ).To (Equal (CustomerRoleArnName ))
592688 Expect (len (customerRole .PolicyARNs )).To (Equal (1 ))
593689 Expect (* customerRole .PolicyARNs [0 ].Arn ).To (Equal (testSessionPolicyArn ))
690+ // Verify that Policy is nil when SessionPolicyArn is used
691+ Expect (customerRole .Policy ).To (BeNil ())
594692 })
595693
596694 It ("should not set PolicyARNs for non-customer roles" , func () {
@@ -613,6 +711,8 @@ var _ = Describe("PolicyARNs Integration", func() {
613711 Expect (supportRole .IsCustomerRole ).To (BeFalse ())
614712 Expect (supportRole .Name ).To (Equal ("Support-Role-Arn" ))
615713 Expect (len (supportRole .PolicyARNs )).To (Equal (0 ))
714+ // Verify that Policy is nil for non-customer roles
715+ Expect (supportRole .Policy ).To (BeNil ())
616716 })
617717
618718 // Generated by Cursor
@@ -636,6 +736,69 @@ var _ = Describe("PolicyARNs Integration", func() {
636736 Expect (customerRole .IsCustomerRole ).To (BeTrue ())
637737 Expect (customerRole .Name ).To (Equal (CustomerRoleArnName ))
638738 Expect (len (customerRole .PolicyARNs )).To (Equal (0 ))
739+ // Verify that Policy is set when SessionPolicyArn is empty
740+ Expect (customerRole .Policy ).ToNot (BeNil ())
741+ })
742+ })
743+
744+ Context ("when verifying roleArnSession.Policy field behavior" , func () {
745+ It ("should set Policy only for customer roles without SessionPolicyArn" , func () {
746+ // Test customer role with SessionPolicyArn - Policy should be nil
747+ roleChainResponseWithArn := assumeChainResponse {
748+ AssumptionSequence : []namedRoleArn {
749+ {
750+ Name : CustomerRoleArnName ,
751+ Arn : "arn:aws:iam::123456789012:role/customer-role" ,
752+ },
753+ },
754+ CustomerRoleSessionName : "customer-session" ,
755+ SessionPolicyArn : testSessionPolicyArn ,
756+ }
757+
758+ assumeRoleArnSessionSequence := simulateGetIsolatedCredentialsLogic (roleChainResponseWithArn )
759+ customerRoleWithArn := assumeRoleArnSessionSequence [0 ]
760+
761+ Expect (customerRoleWithArn .IsCustomerRole ).To (BeTrue ())
762+ Expect (customerRoleWithArn .Policy ).To (BeNil ()) // Policy should be nil when SessionPolicyArn is used
763+ Expect (len (customerRoleWithArn .PolicyARNs )).To (Equal (1 ))
764+
765+ // Test customer role without SessionPolicyArn - Policy should be set
766+ roleChainResponseWithoutArn := assumeChainResponse {
767+ AssumptionSequence : []namedRoleArn {
768+ {
769+ Name : CustomerRoleArnName ,
770+ Arn : "arn:aws:iam::123456789012:role/customer-role" ,
771+ },
772+ },
773+ CustomerRoleSessionName : "customer-session" ,
774+ SessionPolicyArn : "" , // Empty SessionPolicyArn
775+ }
776+
777+ assumeRoleArnSessionSequence = simulateGetIsolatedCredentialsLogic (roleChainResponseWithoutArn )
778+ customerRoleWithoutArn := assumeRoleArnSessionSequence [0 ]
779+
780+ Expect (customerRoleWithoutArn .IsCustomerRole ).To (BeTrue ())
781+ Expect (customerRoleWithoutArn .Policy ).ToNot (BeNil ()) // Policy should be set when SessionPolicyArn is empty
782+ Expect (len (customerRoleWithoutArn .PolicyARNs )).To (Equal (0 ))
783+
784+ // Test non-customer role - Policy should always be nil
785+ roleChainResponseNonCustomer := assumeChainResponse {
786+ AssumptionSequence : []namedRoleArn {
787+ {
788+ Name : "Support-Role-Arn" ,
789+ Arn : "arn:aws:iam::123456789012:role/support-role" ,
790+ },
791+ },
792+ CustomerRoleSessionName : "customer-session" ,
793+ SessionPolicyArn : "" , // Empty SessionPolicyArn
794+ }
795+
796+ assumeRoleArnSessionSequence = simulateGetIsolatedCredentialsLogic (roleChainResponseNonCustomer )
797+ nonCustomerRole := assumeRoleArnSessionSequence [0 ]
798+
799+ Expect (nonCustomerRole .IsCustomerRole ).To (BeFalse ())
800+ Expect (nonCustomerRole .Policy ).To (BeNil ()) // Policy should always be nil for non-customer roles
801+ Expect (len (nonCustomerRole .PolicyARNs )).To (Equal (0 ))
639802 })
640803 })
641804
0 commit comments