@@ -18,7 +18,7 @@ import { fileURLToPath } from 'node:url';
1818import mockfs from 'mock-fs' ;
1919
2020import { Authenticator } from './auth.js' ;
21- import { Headers } from 'node-fetch' ;
21+ import fetch , { Headers } from 'node-fetch' ;
2222import { HttpMethod } from './index.js' ;
2323import { assertRequestAgentsEqual , assertRequestOptionsEqual } from './test/match-buffer.js' ;
2424import { CoreV1Api , RequestContext } from './api.js' ;
@@ -27,6 +27,7 @@ import { ActionOnInvalid, Cluster, newClusters, newContexts, newUsers, User } fr
2727import { ExecAuth } from './exec_auth.js' ;
2828import { HttpProxyAgent , HttpsProxyAgent } from 'hpagent' ;
2929import { SocksProxyAgent } from 'socks-proxy-agent' ;
30+ import { AddressInfo } from 'node:net' ;
3031
3132const kcFileName = 'testdata/kubeconfig.yaml' ;
3233const kc2FileName = 'testdata/kubeconfig-2.yaml' ;
@@ -40,6 +41,9 @@ const kcInvalidContextFileName = 'testdata/empty-context-kubeconfig.yaml';
4041const kcInvalidClusterFileName = 'testdata/empty-cluster-kubeconfig.yaml' ;
4142const kcTlsServerNameFileName = 'testdata/tls-server-name-kubeconfig.yaml' ;
4243
44+ const testCertFileName = 'testdata/certs/test-cert.pem' ;
45+ const testKeyFileName = 'testdata/certs/test-key.pem' ;
46+
4347const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
4448
4549describe ( 'Config' , ( ) => { } ) ;
@@ -491,6 +495,61 @@ describe('KubeConfig', () => {
491495
492496 strictEqual ( rc . getAgent ( ) instanceof https . Agent , true ) ;
493497 } ) ;
498+
499+ it ( 'should apply NODE_TLS_REJECT_UNAUTHORIZED from environment to agent' , async ( ) => {
500+ const { server, host, port } = await createTestHttpsServer ( ( req , res ) => {
501+ res . setHeader ( 'Content-Type' , 'application/json' ) ;
502+ if ( req . url ?. includes ( '/api/v1/namespaces' ) ) {
503+ res . writeHead ( 200 ) ;
504+ res . end (
505+ JSON . stringify ( {
506+ apiVersion : 'v1' ,
507+ kind : 'NamespaceList' ,
508+ items : [
509+ {
510+ apiVersion : 'v1' ,
511+ kind : 'Namespace' ,
512+ metadata : { name : 'default' } ,
513+ } ,
514+ ] ,
515+ } ) ,
516+ ) ;
517+ } else {
518+ res . writeHead ( 200 ) ;
519+ res . end ( 'ok' ) ;
520+ }
521+ } ) ;
522+
523+ const originalValue = process . env . NODE_TLS_REJECT_UNAUTHORIZED ;
524+ process . env . NODE_TLS_REJECT_UNAUTHORIZED = '0' ; // lgtm[js/disabling-certificate-validation]
525+ after ( ( ) => {
526+ process . env . NODE_TLS_REJECT_UNAUTHORIZED = originalValue ;
527+ server . close ( ) ;
528+ } ) ;
529+
530+ const kc = new KubeConfig ( ) ;
531+ kc . loadFromClusterAndUser (
532+ {
533+ name : 'test-cluster' ,
534+ server : `https://${ host } :${ port } ` ,
535+ // ignore skipTLSVerify specified from environment variables
536+ } as Cluster ,
537+ {
538+ name : 'test-user' ,
539+ token : 'test-token' ,
540+ } ,
541+ ) ;
542+ const coreV1Api = kc . makeApiClient ( CoreV1Api ) ;
543+ const namespaceList = await coreV1Api . listNamespace ( ) ;
544+
545+ strictEqual ( namespaceList . kind , 'NamespaceList' ) ;
546+ strictEqual ( namespaceList . items . length , 1 ) ;
547+ strictEqual ( namespaceList . items [ 0 ] . metadata ?. name , 'default' ) ;
548+
549+ const res2 = await fetch ( `https://${ host } :${ port } ` , await kc . applyToFetchOptions ( { } ) ) ;
550+ strictEqual ( res2 . status , 200 ) ;
551+ strictEqual ( await res2 . text ( ) , 'ok' ) ;
552+ } ) ;
494553 } ) ;
495554
496555 describe ( 'loadClusterConfigObjects' , ( ) => {
@@ -1827,3 +1886,38 @@ describe('KubeConfig', () => {
18271886 } ) ;
18281887 } ) ;
18291888} ) ;
1889+
1890+ // create a self-signed HTTPS test server
1891+ async function createTestHttpsServer (
1892+ requestHandler ?: ( req : http . IncomingMessage , res : http . ServerResponse ) => void ,
1893+ ) : Promise < {
1894+ server : https . Server ;
1895+ host : string ;
1896+ port : number ;
1897+ ca : string ;
1898+ } > {
1899+ const host = 'localhost' ;
1900+
1901+ const cert = readFileSync ( testCertFileName , 'utf8' ) ;
1902+ const key = readFileSync ( testKeyFileName , 'utf8' ) ;
1903+
1904+ const defaultHandler = ( req : http . IncomingMessage , res : http . ServerResponse ) => {
1905+ res . writeHead ( 200 ) ;
1906+ res . end ( 'ok' ) ;
1907+ } ;
1908+
1909+ const server = https . createServer ( { key, cert } , requestHandler ?? defaultHandler ) ;
1910+
1911+ const port = await new Promise < number > ( ( resolve ) => {
1912+ server . listen ( 0 , ( ) => {
1913+ resolve ( ( server . address ( ) as AddressInfo ) . port ) ;
1914+ } ) ;
1915+ } ) ;
1916+
1917+ return {
1918+ server,
1919+ host,
1920+ port,
1921+ ca : cert , // ca is the same as cert here
1922+ } ;
1923+ }
0 commit comments