@@ -15,12 +15,15 @@ import { CoreV1Api, RequestContext } from './api.js';
1515import { bufferFromFileOrString , findHomeDir , findObject , KubeConfig , makeAbsolutePath } from './config.js' ;
1616import { ActionOnInvalid , Cluster , newClusters , newContexts , newUsers , User } from './config_types.js' ;
1717import { ExecAuth } from './exec_auth.js' ;
18+ import { HttpProxyAgent , HttpsProxyAgent } from 'hpagent' ;
19+ import { SocksProxyAgent } from 'socks-proxy-agent' ;
1820
1921const kcFileName = 'testdata/kubeconfig.yaml' ;
2022const kc2FileName = 'testdata/kubeconfig-2.yaml' ;
2123const kcDupeCluster = 'testdata/kubeconfig-dupe-cluster.yaml' ;
2224const kcDupeContext = 'testdata/kubeconfig-dupe-context.yaml' ;
2325const kcDupeUser = 'testdata/kubeconfig-dupe-user.yaml' ;
26+ const kcProxyUrl = 'testdata/kubeconfig-proxy-url.yaml' ;
2427
2528const kcNoUserFileName = 'testdata/empty-user-kubeconfig.yaml' ;
2629const kcInvalidContextFileName = 'testdata/empty-context-kubeconfig.yaml' ;
@@ -43,6 +46,7 @@ function validateFileLoad(kc: KubeConfig) {
4346 expect ( cluster1 . name ) . to . equal ( 'cluster1' ) ;
4447 expect ( cluster1 . caData ) . to . equal ( 'Q0FEQVRB' ) ;
4548 expect ( cluster1 . server ) . to . equal ( 'http://example.com' ) ;
49+ expect ( cluster1 . proxyUrl ) . to . equal ( 'socks5://localhost:1181' ) ;
4650 expect ( cluster2 . name ) . to . equal ( 'cluster2' ) ;
4751 expect ( cluster2 . caData ) . to . equal ( 'Q0FEQVRBMg==' ) ;
4852 expect ( cluster2 . server ) . to . equal ( 'http://example2.com' ) ;
@@ -358,6 +362,69 @@ describe('KubeConfig', () => {
358362
359363 assertRequestOptionsEqual ( opts , expectedOptions ) ;
360364 } ) ;
365+ it ( 'should apply socks proxy' , async ( ) => {
366+ const kc = new KubeConfig ( ) ;
367+ kc . loadFromFile ( kcProxyUrl ) ;
368+ kc . setCurrentContext ( 'contextA' ) ;
369+
370+ const testServerName = 'https://example.com' ;
371+ const rc = new RequestContext ( testServerName , HttpMethod . GET ) ;
372+
373+ await kc . applySecurityAuthentication ( rc ) ;
374+ const expectedCA = Buffer . from ( 'CADAT@' , 'utf-8' ) ;
375+ const expectedProxyHost = 'example' ;
376+ const expectedProxyPort = 1187 ;
377+
378+ expect ( rc . getAgent ( ) ) . to . be . instanceOf ( SocksProxyAgent ) ;
379+ const agent = rc . getAgent ( ) as SocksProxyAgent ;
380+ expect ( agent . options . ca ?. toString ( ) ) . to . equal ( expectedCA . toString ( ) ) ;
381+ expect ( agent . proxy . host ) . to . equal ( expectedProxyHost ) ;
382+ expect ( agent . proxy . port ) . to . equal ( expectedProxyPort ) ;
383+ } ) ;
384+ it ( 'should apply https proxy' , async ( ) => {
385+ const kc = new KubeConfig ( ) ;
386+ kc . loadFromFile ( kcProxyUrl ) ;
387+ kc . setCurrentContext ( 'contextB' ) ;
388+
389+ const testServerName = 'https://example.com' ;
390+ const rc = new RequestContext ( testServerName , HttpMethod . GET ) ;
391+
392+ await kc . applySecurityAuthentication ( rc ) ;
393+ const expectedCA = Buffer . from ( 'CADAT@' , 'utf-8' ) ;
394+ const expectedProxyHref = 'http://example:9443/' ;
395+
396+ expect ( rc . getAgent ( ) ) . to . be . instanceOf ( HttpsProxyAgent ) ;
397+ const agent = rc . getAgent ( ) as HttpsProxyAgent ;
398+ expect ( agent . options . ca ?. toString ( ) ) . to . equal ( expectedCA . toString ( ) ) ;
399+ expect ( agent . proxy . href ) . to . equal ( expectedProxyHref ) ;
400+ } ) ;
401+ it ( 'should apply http proxy' , async ( ) => {
402+ const kc = new KubeConfig ( ) ;
403+ kc . loadFromFile ( kcProxyUrl ) ;
404+ kc . setCurrentContext ( 'contextC' ) ;
405+
406+ const testServerName = 'https://example.com' ;
407+ const rc = new RequestContext ( testServerName , HttpMethod . GET ) ;
408+
409+ await kc . applySecurityAuthentication ( rc ) ;
410+ const expectedCA = Buffer . from ( 'CADAT@' , 'utf-8' ) ;
411+ const expectedProxyHref = 'http://example:8080/' ;
412+
413+ expect ( rc . getAgent ( ) ) . to . be . instanceOf ( HttpProxyAgent ) ;
414+ const agent = rc . getAgent ( ) as HttpProxyAgent ;
415+ expect ( agent . options . ca ?. toString ( ) ) . to . equal ( expectedCA . toString ( ) ) ;
416+ expect ( agent . proxy . href ) . to . equal ( expectedProxyHref ) ;
417+ } ) ;
418+ it ( 'should throw an error if proxy-url is provided but the server protocol is not http or https' , async ( ) => {
419+ const kc = new KubeConfig ( ) ;
420+ kc . loadFromFile ( kcProxyUrl ) ;
421+ kc . setCurrentContext ( 'contextD' ) ;
422+
423+ const testServerName = 'https://example.com' ;
424+ const rc = new RequestContext ( testServerName , HttpMethod . GET ) ;
425+
426+ return expect ( kc . applySecurityAuthentication ( rc ) ) . to . be . rejectedWith ( 'Unsupported proxy type' ) ;
427+ } ) ;
361428 } ) ;
362429
363430 describe ( 'loadClusterConfigObjects' , ( ) => {
0 commit comments