Skip to content

Commit 6a01c96

Browse files
authored
[AKS] Fix #15932: az aks install-cli: Add --gh-token parameter to allow authentication when downloading kubelogin (#32536)
1 parent 4ef9898 commit 6a01c96

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

src/azure-cli/azure/cli/command_modules/acs/_params.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,7 @@ def load_arguments(self, _):
877877
c.argument('kubelogin_version', validator=validate_kubelogin_version, help='Version of kubelogin to install.')
878878
c.argument('kubelogin_install_location', default=_get_default_install_location('kubelogin'), help='Path at which to install kubelogin. Note: the path should contain the binary filename.')
879879
c.argument('kubelogin_base_src_url', options_list=['--kubelogin-base-src-url', '-l'], help='Base download source URL for kubelogin releases.')
880+
c.argument('gh_token', help='GitHub authentication token used when downloading kubelogin binaries from GitHub releases. Supplying a token helps avoid GitHub API rate limits.')
880881

881882
with self.argument_context('aks update-credentials', arg_group='Service Principal') as c:
882883
c.argument('reset_service_principal', action='store_true')

src/azure-cli/azure/cli/command_modules/acs/custom.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,12 +2239,12 @@ def aks_check_acr(cmd, client, resource_group_name, name, acr, node_name=None):
22392239
# install kubectl & kubelogin
22402240
def k8s_install_cli(cmd, client_version='latest', install_location=None, base_src_url=None,
22412241
kubelogin_version='latest', kubelogin_install_location=None,
2242-
kubelogin_base_src_url=None):
2242+
kubelogin_base_src_url=None, gh_token=None):
22432243
arch = get_arch_for_cli_binary()
22442244
k8s_install_kubectl(cmd, client_version,
22452245
install_location, base_src_url, arch=arch)
22462246
k8s_install_kubelogin(cmd, kubelogin_version,
2247-
kubelogin_install_location, kubelogin_base_src_url, arch=arch)
2247+
kubelogin_install_location, kubelogin_base_src_url, arch=arch, gh_token=gh_token)
22482248

22492249

22502250
# determine the architecture for the binary based on platform.machine()
@@ -2444,7 +2444,7 @@ def k8s_install_kubectl(cmd, client_version='latest', install_location=None, sou
24442444

24452445

24462446
# install kubelogin
2447-
def k8s_install_kubelogin(cmd, client_version='latest', install_location=None, source_url=None, arch=None):
2447+
def k8s_install_kubelogin(cmd, client_version='latest', install_location=None, source_url=None, arch=None, gh_token=None):
24482448
"""
24492449
Install kubelogin, a client-go credential (exec) plugin implementing azure authentication.
24502450
"""
@@ -2462,7 +2462,7 @@ def k8s_install_kubelogin(cmd, client_version='latest', install_location=None, s
24622462
latest_release_url = 'https://mirror.azure.cn/kubernetes/kubelogin/latest'
24632463
logger.warning(
24642464
'No version specified, will get the latest version of kubelogin from "%s"', latest_release_url)
2465-
latest_release = _urlopen_read(latest_release_url)
2465+
latest_release = _urlopen_read(latest_release_url, gh_token=gh_token)
24662466
client_version = json.loads(latest_release)['tag_name'].strip()
24672467
else:
24682468
client_version = "v%s" % client_version
@@ -2519,11 +2519,15 @@ def _ssl_context():
25192519
return ssl.create_default_context()
25202520

25212521

2522-
def _urlopen_read(url, context=None):
2522+
def _urlopen_read(url, context=None, gh_token=None):
25232523
if context is None:
25242524
context = _ssl_context()
25252525
try:
2526-
return urlopen(url, context=context).read()
2526+
from urllib.request import Request
2527+
request = Request(url)
2528+
if gh_token:
2529+
request.add_header('Authorization', f'Bearer {gh_token}')
2530+
return urlopen(request, context=context).read()
25272531
except URLError as ex:
25282532
error_msg = str(ex)
25292533
if "[SSL: CERTIFICATE_VERIFY_FAILED]" in error_msg and "unable to get local issuer certificate" in error_msg:
@@ -2535,9 +2539,9 @@ def _urlopen_read(url, context=None):
25352539
raise ex
25362540

25372541

2538-
def _urlretrieve(url, filename):
2542+
def _urlretrieve(url, filename, gh_token=None):
25392543
with open(filename, "wb") as f:
2540-
f.write(_urlopen_read(url))
2544+
f.write(_urlopen_read(url, gh_token=gh_token))
25412545

25422546

25432547
def _unzip(src, dest):

src/azure-cli/azure/cli/command_modules/acs/tests/latest/test_custom.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,40 @@ def test_k8s_install_kubelogin_with_custom_source_url(self, logger_mock, mock_ur
690690
finally:
691691
shutil.rmtree(temp_dir)
692692

693+
@mock.patch('azure.cli.command_modules.acs.custom._urlopen_read')
694+
@mock.patch('azure.cli.command_modules.acs.custom._urlretrieve')
695+
@mock.patch('azure.cli.command_modules.acs.custom.logger')
696+
def test_k8s_install_kubelogin_with_gh_token(self, logger_mock, mock_url_retrieve, mock_urlopen_read):
697+
"""Test that gh_token parameter is properly passed to HTTP requests when installing kubelogin."""
698+
# Mock the GitHub API response for latest release
699+
mock_urlopen_read.return_value = b'{"tag_name": "v0.0.30"}'
700+
# Mock the zip file download
701+
mock_url_retrieve.side_effect = create_kubelogin_zip
702+
703+
try:
704+
temp_dir = tempfile.mkdtemp()
705+
test_location = os.path.join(temp_dir, 'foo', 'kubelogin')
706+
test_gh_token = 'ghp_test_token_123'
707+
708+
# Install kubelogin with gh_token
709+
k8s_install_kubelogin(
710+
mock.MagicMock(),
711+
client_version='latest',
712+
install_location=test_location,
713+
arch="amd64",
714+
gh_token=test_gh_token
715+
)
716+
717+
# Verify gh_token was passed to _urlopen_read for GitHub API call
718+
mock_urlopen_read.assert_called_once()
719+
call_args = mock_urlopen_read.call_args
720+
self.assertEqual(call_args.kwargs.get('gh_token'), test_gh_token)
721+
722+
# Verify the installation completed
723+
self.assertTrue(os.path.exists(test_location))
724+
finally:
725+
shutil.rmtree(temp_dir)
726+
693727
@mock.patch('azure.cli.command_modules.acs.addonconfiguration.get_rg_location', return_value='eastus')
694728
@mock.patch('azure.cli.command_modules.acs.addonconfiguration.get_resource_groups_client', autospec=True)
695729
@mock.patch('azure.cli.command_modules.acs.addonconfiguration.get_resources_client', autospec=True)

0 commit comments

Comments
 (0)