34
34
35
35
EXPIRY_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
36
36
# should be less than kube_config.EXPIRY_SKEW_PREVENTION_DELAY
37
- EXPIRY_TIMEDELTA = 2
37
+ PAST_EXPIRY_TIMEDELTA = 2
38
+ # should be more than kube_config.EXPIRY_SKEW_PREVENTION_DELAY
39
+ FUTURE_EXPIRY_TIMEDELTA = 60
38
40
39
41
NON_EXISTING_FILE = "zz_non_existing_file_472398324"
40
42
@@ -47,9 +49,9 @@ def _format_expiry_datetime(dt):
47
49
return dt .strftime (EXPIRY_DATETIME_FORMAT )
48
50
49
51
50
- def _get_expiry (loader ):
52
+ def _get_expiry (loader , active_context ):
51
53
expired_gcp_conf = (item for item in loader ._config .value .get ("users" )
52
- if item .get ("name" ) == "expired_gcp" )
54
+ if item .get ("name" ) == active_context )
53
55
return next (expired_gcp_conf ).get ("user" ).get ("auth-provider" ) \
54
56
.get ("config" ).get ("expiry" )
55
57
@@ -73,8 +75,11 @@ def _raise_exception(st):
73
75
TEST_PASSWORD = "pass"
74
76
# token for me:pass
75
77
TEST_BASIC_TOKEN = "Basic bWU6cGFzcw=="
76
- TEST_TOKEN_EXPIRY = _format_expiry_datetime (
77
- datetime .datetime .utcnow () - datetime .timedelta (minutes = EXPIRY_TIMEDELTA ))
78
+ DATETIME_EXPIRY_PAST = datetime .datetime .utcnow (
79
+ ) - datetime .timedelta (minutes = PAST_EXPIRY_TIMEDELTA )
80
+ DATETIME_EXPIRY_FUTURE = datetime .datetime .utcnow (
81
+ ) + datetime .timedelta (minutes = FUTURE_EXPIRY_TIMEDELTA )
82
+ TEST_TOKEN_EXPIRY_PAST = _format_expiry_datetime (DATETIME_EXPIRY_PAST )
78
83
79
84
TEST_SSL_HOST = "https://test-host"
80
85
TEST_CERTIFICATE_AUTH = "cert-auth"
@@ -371,6 +376,13 @@ class TestKubeConfigLoader(BaseTestCase):
371
376
"user" : "expired_gcp"
372
377
}
373
378
},
379
+ {
380
+ "name" : "expired_gcp_refresh" ,
381
+ "context" : {
382
+ "cluster" : "default" ,
383
+ "user" : "expired_gcp_refresh"
384
+ }
385
+ },
374
386
{
375
387
"name" : "oidc" ,
376
388
"context" : {
@@ -509,7 +521,22 @@ class TestKubeConfigLoader(BaseTestCase):
509
521
"name" : "gcp" ,
510
522
"config" : {
511
523
"access-token" : TEST_DATA_BASE64 ,
512
- "expiry" : TEST_TOKEN_EXPIRY , # always in past
524
+ "expiry" : TEST_TOKEN_EXPIRY_PAST , # always in past
525
+ }
526
+ },
527
+ "token" : TEST_DATA_BASE64 , # should be ignored
528
+ "username" : TEST_USERNAME , # should be ignored
529
+ "password" : TEST_PASSWORD , # should be ignored
530
+ }
531
+ },
532
+ {
533
+ "name" : "expired_gcp_refresh" ,
534
+ "user" : {
535
+ "auth-provider" : {
536
+ "name" : "gcp" ,
537
+ "config" : {
538
+ "access-token" : TEST_DATA_BASE64 ,
539
+ "expiry" : TEST_TOKEN_EXPIRY_PAST , # always in past
513
540
}
514
541
},
515
542
"token" : TEST_DATA_BASE64 , # should be ignored
@@ -630,16 +657,20 @@ def test_load_user_token(self):
630
657
self .assertEqual (BEARER_TOKEN_FORMAT % TEST_DATA_BASE64 , loader .token )
631
658
632
659
def test_gcp_no_refresh (self ):
633
- expected = FakeConfig (
634
- host = TEST_HOST ,
635
- token = BEARER_TOKEN_FORMAT % TEST_DATA_BASE64 )
636
- actual = FakeConfig ()
660
+ fake_config = FakeConfig ()
661
+ # swagger-generated config has this, but FakeConfig does not.
662
+ self .assertFalse (hasattr (fake_config , 'get_api_key_with_prefix' ))
637
663
KubeConfigLoader (
638
664
config_dict = self .TEST_KUBE_CONFIG ,
639
665
active_context = "gcp" ,
640
666
get_google_credentials = lambda : _raise_exception (
641
- "SHOULD NOT BE CALLED" )).load_and_set (actual )
642
- self .assertEqual (expected , actual )
667
+ "SHOULD NOT BE CALLED" )).load_and_set (fake_config )
668
+ # Should now be populated with a gcp token fetcher.
669
+ self .assertIsNotNone (fake_config .get_api_key_with_prefix )
670
+ self .assertEqual (TEST_HOST , fake_config .host )
671
+ # For backwards compatibility, authorization field should still be set.
672
+ self .assertEqual (BEARER_TOKEN_FORMAT % TEST_DATA_BASE64 ,
673
+ fake_config .api_key ['authorization' ])
643
674
644
675
def test_load_gcp_token_no_refresh (self ):
645
676
loader = KubeConfigLoader (
@@ -654,20 +685,48 @@ def test_load_gcp_token_no_refresh(self):
654
685
def test_load_gcp_token_with_refresh (self ):
655
686
def cred (): return None
656
687
cred .token = TEST_ANOTHER_DATA_BASE64
657
- cred .expiry = datetime .datetime .now ()
688
+ cred .expiry = datetime .datetime .utcnow ()
658
689
659
690
loader = KubeConfigLoader (
660
691
config_dict = self .TEST_KUBE_CONFIG ,
661
692
active_context = "expired_gcp" ,
662
693
get_google_credentials = lambda : cred )
663
- original_expiry = _get_expiry (loader )
694
+ original_expiry = _get_expiry (loader , "expired_gcp" )
664
695
self .assertTrue (loader ._load_auth_provider_token ())
665
- new_expiry = _get_expiry (loader )
696
+ new_expiry = _get_expiry (loader , "expired_gcp" )
666
697
# assert that the configs expiry actually updates
667
698
self .assertTrue (new_expiry > original_expiry )
668
699
self .assertEqual (BEARER_TOKEN_FORMAT % TEST_ANOTHER_DATA_BASE64 ,
669
700
loader .token )
670
701
702
+ def test_gcp_get_api_key_with_prefix (self ):
703
+ class cred_old :
704
+ token = TEST_DATA_BASE64
705
+ expiry = DATETIME_EXPIRY_PAST
706
+
707
+ class cred_new :
708
+ token = TEST_ANOTHER_DATA_BASE64
709
+ expiry = DATETIME_EXPIRY_FUTURE
710
+ fake_config = FakeConfig ()
711
+ _get_google_credentials = mock .Mock ()
712
+ _get_google_credentials .side_effect = [cred_old , cred_new ]
713
+
714
+ loader = KubeConfigLoader (
715
+ config_dict = self .TEST_KUBE_CONFIG ,
716
+ active_context = "expired_gcp_refresh" ,
717
+ get_google_credentials = _get_google_credentials )
718
+ loader .load_and_set (fake_config )
719
+ original_expiry = _get_expiry (loader , "expired_gcp_refresh" )
720
+ # Call GCP token fetcher.
721
+ token = fake_config .get_api_key_with_prefix ()
722
+ new_expiry = _get_expiry (loader , "expired_gcp_refresh" )
723
+
724
+ self .assertTrue (new_expiry > original_expiry )
725
+ self .assertEqual (BEARER_TOKEN_FORMAT % TEST_ANOTHER_DATA_BASE64 ,
726
+ loader .token )
727
+ self .assertEqual (BEARER_TOKEN_FORMAT % TEST_ANOTHER_DATA_BASE64 ,
728
+ token )
729
+
671
730
def test_oidc_no_refresh (self ):
672
731
loader = KubeConfigLoader (
673
732
config_dict = self .TEST_KUBE_CONFIG ,
0 commit comments