diff --git a/src/config.ts b/src/config.ts index a99d413c66..da2efc7519 100644 --- a/src/config.ts +++ b/src/config.ts @@ -45,6 +45,11 @@ export class KubeConfig { */ public 'currentContext': string; + /** + * Root directory for a config file driven config. Used for loading relative cert paths. + */ + public 'rootDirectory': string; + public getContexts() { return this.contexts; } @@ -97,6 +102,7 @@ export class KubeConfig { } public loadFromFile(file: string) { + this.rootDirectory = path.dirname(file); this.loadFromString(fs.readFileSync(file, 'utf8')); } @@ -255,15 +261,18 @@ export class KubeConfig { if (cluster != null && cluster.skipTLSVerify) { opts.rejectUnauthorized = false; } - const ca = cluster != null ? bufferFromFileOrString(cluster.caFile, cluster.caData) : null; + const ca = + cluster != null + ? bufferFromFileOrString(this.rootDirectory, cluster.caFile, cluster.caData) + : null; if (ca) { opts.ca = ca; } - const cert = bufferFromFileOrString(user.certFile, user.certData); + const cert = bufferFromFileOrString(this.rootDirectory, user.certFile, user.certData); if (cert) { opts.cert = cert; } - const key = bufferFromFileOrString(user.keyFile, user.keyData); + const key = bufferFromFileOrString(this.rootDirectory, user.keyFile, user.keyData); if (key) { opts.key = key; } @@ -355,8 +364,11 @@ export class Config { } // This is public really only for testing. -export function bufferFromFileOrString(file?: string, data?: string): Buffer | null { +export function bufferFromFileOrString(root?: string, file?: string, data?: string): Buffer | null { if (file) { + if (!path.isAbsolute(file) && root) { + file = path.join(root, file); + } return fs.readFileSync(file); } if (data) { diff --git a/src/config_test.ts b/src/config_test.ts index e4275db213..00a91ea4a0 100644 --- a/src/config_test.ts +++ b/src/config_test.ts @@ -1,6 +1,6 @@ import { readFileSync } from 'fs'; import * as https from 'https'; -import { join } from 'path'; +import { dirname, join } from 'path'; import { expect } from 'chai'; import mockfs = require('mock-fs'); @@ -167,7 +167,7 @@ describe('KubeConfig', () => { it('should load the kubeconfig file properly', () => { const kc = new KubeConfig(); kc.loadFromFile(kcFileName); - + expect(kc.rootDirectory).to.equal(dirname(kcFileName)); validateFileLoad(kc); }); it('should fail to load a missing kubeconfig file', () => { @@ -1012,13 +1012,28 @@ describe('KubeConfig', () => { }); describe('BufferOrFile', () => { + it('should load from root if present', () => { + const data = 'some data for file'; + const arg: any = { + configDir: { + config: data, + }, + }; + mockfs(arg); + const inputData = bufferFromFileOrString('configDir', 'config'); + expect(inputData).to.not.equal(null); + if (inputData) { + expect(inputData.toString()).to.equal(data); + } + mockfs.restore(); + }); it('should load from a file if present', () => { const data = 'some data for file'; const arg: any = { config: data, }; mockfs(arg); - const inputData = bufferFromFileOrString('config'); + const inputData = bufferFromFileOrString(undefined, 'config'); expect(inputData).to.not.equal(null); if (inputData) { expect(inputData.toString()).to.equal(data);