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,9 @@ 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 () - datetime .timedelta (minutes = PAST_EXPIRY_TIMEDELTA )
79
+ DATETIME_EXPIRY_FUTURE = datetime .datetime .utcnow () + datetime .timedelta (minutes = FUTURE_EXPIRY_TIMEDELTA )
80
+ TEST_TOKEN_EXPIRY_PAST = _format_expiry_datetime (DATETIME_EXPIRY_PAST )
78
81
79
82
TEST_SSL_HOST = "https://test-host"
80
83
TEST_CERTIFICATE_AUTH = "cert-auth"
@@ -371,6 +374,13 @@ class TestKubeConfigLoader(BaseTestCase):
371
374
"user" : "expired_gcp"
372
375
}
373
376
},
377
+ {
378
+ "name" : "expired_gcp_refresh" ,
379
+ "context" : {
380
+ "cluster" : "default" ,
381
+ "user" : "expired_gcp_refresh"
382
+ }
383
+ },
374
384
{
375
385
"name" : "oidc" ,
376
386
"context" : {
@@ -509,7 +519,22 @@ class TestKubeConfigLoader(BaseTestCase):
509
519
"name" : "gcp" ,
510
520
"config" : {
511
521
"access-token" : TEST_DATA_BASE64 ,
512
- "expiry" : TEST_TOKEN_EXPIRY , # always in past
522
+ "expiry" : TEST_TOKEN_EXPIRY_PAST , # always in past
523
+ }
524
+ },
525
+ "token" : TEST_DATA_BASE64 , # should be ignored
526
+ "username" : TEST_USERNAME , # should be ignored
527
+ "password" : TEST_PASSWORD , # should be ignored
528
+ }
529
+ },
530
+ {
531
+ "name" : "expired_gcp_refresh" ,
532
+ "user" : {
533
+ "auth-provider" : {
534
+ "name" : "gcp" ,
535
+ "config" : {
536
+ "access-token" : TEST_DATA_BASE64 ,
537
+ "expiry" : TEST_TOKEN_EXPIRY_PAST , # always in past
513
538
}
514
539
},
515
540
"token" : TEST_DATA_BASE64 , # should be ignored
@@ -630,16 +655,20 @@ def test_load_user_token(self):
630
655
self .assertEqual (BEARER_TOKEN_FORMAT % TEST_DATA_BASE64 , loader .token )
631
656
632
657
def test_gcp_no_refresh (self ):
633
- expected = FakeConfig (
634
- host = TEST_HOST ,
635
- token = BEARER_TOKEN_FORMAT % TEST_DATA_BASE64 )
636
- actual = FakeConfig ()
658
+ fake_config = FakeConfig ()
659
+ # swagger-generated config has this, but FakeConfig does not.
660
+ self .assertFalse (hasattr (fake_config , 'get_api_key_with_prefix' ))
637
661
KubeConfigLoader (
638
662
config_dict = self .TEST_KUBE_CONFIG ,
639
663
active_context = "gcp" ,
640
664
get_google_credentials = lambda : _raise_exception (
641
- "SHOULD NOT BE CALLED" )).load_and_set (actual )
642
- self .assertEqual (expected , actual )
665
+ "SHOULD NOT BE CALLED" )).load_and_set (fake_config )
666
+ # Should now be populated with a gcp token fetcher.
667
+ self .assertIsNotNone (fake_config .get_api_key_with_prefix )
668
+ self .assertEqual (TEST_HOST , fake_config .host )
669
+ # For backwards compatibility, authorization field should still be set.
670
+ self .assertEqual (BEARER_TOKEN_FORMAT % TEST_DATA_BASE64 ,
671
+ fake_config .api_key ['authorization' ])
643
672
644
673
def test_load_gcp_token_no_refresh (self ):
645
674
loader = KubeConfigLoader (
@@ -654,20 +683,47 @@ def test_load_gcp_token_no_refresh(self):
654
683
def test_load_gcp_token_with_refresh (self ):
655
684
def cred (): return None
656
685
cred .token = TEST_ANOTHER_DATA_BASE64
657
- cred .expiry = datetime .datetime .now ()
686
+ cred .expiry = datetime .datetime .utcnow ()
658
687
659
688
loader = KubeConfigLoader (
660
689
config_dict = self .TEST_KUBE_CONFIG ,
661
690
active_context = "expired_gcp" ,
662
691
get_google_credentials = lambda : cred )
663
- original_expiry = _get_expiry (loader )
692
+ original_expiry = _get_expiry (loader , "expired_gcp" )
664
693
self .assertTrue (loader ._load_auth_provider_token ())
665
- new_expiry = _get_expiry (loader )
694
+ new_expiry = _get_expiry (loader , "expired_gcp" )
666
695
# assert that the configs expiry actually updates
667
696
self .assertTrue (new_expiry > original_expiry )
668
697
self .assertEqual (BEARER_TOKEN_FORMAT % TEST_ANOTHER_DATA_BASE64 ,
669
698
loader .token )
670
699
700
+ def test_gcp_get_api_key_with_prefix (self ):
701
+ class cred_old :
702
+ token = TEST_DATA_BASE64
703
+ expiry = DATETIME_EXPIRY_PAST
704
+ class cred_new :
705
+ token = TEST_ANOTHER_DATA_BASE64
706
+ expiry = DATETIME_EXPIRY_FUTURE
707
+ fake_config = FakeConfig ()
708
+ _get_google_credentials = mock .Mock ()
709
+ _get_google_credentials .side_effect = [cred_old , cred_new ]
710
+
711
+ loader = KubeConfigLoader (
712
+ config_dict = self .TEST_KUBE_CONFIG ,
713
+ active_context = "expired_gcp_refresh" ,
714
+ get_google_credentials = _get_google_credentials )
715
+ loader .load_and_set (fake_config )
716
+ original_expiry = _get_expiry (loader , "expired_gcp_refresh" )
717
+ # Call GCP token fetcher.
718
+ token = fake_config .get_api_key_with_prefix ()
719
+ new_expiry = _get_expiry (loader , "expired_gcp_refresh" )
720
+
721
+ self .assertTrue (new_expiry > original_expiry )
722
+ self .assertEqual (BEARER_TOKEN_FORMAT % TEST_ANOTHER_DATA_BASE64 ,
723
+ loader .token )
724
+ self .assertEqual (BEARER_TOKEN_FORMAT % TEST_ANOTHER_DATA_BASE64 ,
725
+ token )
726
+
671
727
def test_oidc_no_refresh (self ):
672
728
loader = KubeConfigLoader (
673
729
config_dict = self .TEST_KUBE_CONFIG ,
0 commit comments