Skip to content

Proxy url #2091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 131 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
"stream-buffers": "^3.0.2",
"tar": "^7.0.0",
"tslib": "^2.4.1",
"ws": "^8.18.0"
"ws": "^8.18.0",
"socks-proxy-agent": "^8.0.4"
},
"devDependencies": {
"@types/byline": "^4.2.31",
Expand Down
9 changes: 9 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import path = require('path');

import request = require('request');
import WebSocket = require('ws');
import SocksProxyAgent = require('socks-proxy-agent');

import * as api from './api';
import { Authenticator } from './auth';
Expand Down Expand Up @@ -170,6 +171,14 @@ export class KubeConfig {
if (cluster && cluster.tlsServerName) {
opts.agentOptions = { servername: cluster.tlsServerName } as https.AgentOptions;
}

if (cluster && cluster.proxyUrl) {
if (cluster.proxyUrl.startsWith('socks')) {
opts.agent = new SocksProxyAgent.SocksProxyAgent(cluster.proxyUrl);
} else {
opts.proxy = cluster.proxyUrl;
}
}
}

public loadFromString(config: string, opts?: Partial<ConfigOptions>): void {
Expand Down
26 changes: 26 additions & 0 deletions src/config_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const kc2FileName = 'testdata/kubeconfig-2.yaml';
const kcDupeCluster = 'testdata/kubeconfig-dupe-cluster.yaml';
const kcDupeContext = 'testdata/kubeconfig-dupe-context.yaml';
const kcDupeUser = 'testdata/kubeconfig-dupe-user.yaml';
const kcProxyUrl = 'testdata/kubeconfig-proxy-url.yaml';

const kcNoUserFileName = 'testdata/empty-user-kubeconfig.yaml';
const kcInvalidContextFileName = 'testdata/empty-context-kubeconfig.yaml';
Expand All @@ -36,6 +37,7 @@ function validateFileLoad(kc: KubeConfig) {
expect(cluster1.name).to.equal('cluster1');
expect(cluster1.caData).to.equal('Q0FEQVRB');
expect(cluster1.server).to.equal('http://example.com');
expect(cluster1.proxyUrl).to.equal('socks5://localhost:1181');
expect(cluster2.name).to.equal('cluster2');
expect(cluster2.caData).to.equal('Q0FEQVRBMg==');
expect(cluster2.server).to.equal('http://example2.com');
Expand Down Expand Up @@ -403,6 +405,30 @@ describe('KubeConfig', () => {
rejectUnauthorized: false,
});
});
it('should apply proxy to request.Options', async () => {
const kc = new KubeConfig();
kc.loadFromFile(kc2FileName);

const opts = {} as requestlib.Options;

await kc.applyToRequest(opts);

expect(opts).to.deep.equal({
headers: {},
ca: Buffer.from('CADAT@', 'utf-8'),
cert: Buffer.from(']SER_CADATA', 'utf-8'),
key: Buffer.from(']SER_CKDATA', 'utf-8'),
proxy: 'https://localhost:1181',
});
});
it('should apply agent to request.Options', async () => {
const kc = new KubeConfig();
kc.loadFromFile(kcProxyUrl);

const opts = {} as requestlib.Options;
await kc.applyToRequest(opts);
expect(opts.agent).to.exist;
});
});

describe('loadClusterConfigObjects', () => {
Expand Down
3 changes: 3 additions & 0 deletions src/config_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface Cluster {
readonly server: string;
readonly skipTLSVerify?: boolean;
readonly tlsServerName?: string;
readonly proxyUrl?: string;
}

export function newClusters(a: any, opts?: Partial<ConfigOptions>): Cluster[] {
Expand All @@ -43,6 +44,7 @@ export function exportCluster(cluster: Cluster): any {
'certificate-authority': cluster.caFile,
'insecure-skip-tls-verify': cluster.skipTLSVerify,
'tls-server-name': cluster.tlsServerName,
'proxy-url': cluster.proxyUrl,
},
};
}
Expand All @@ -68,6 +70,7 @@ function clusterIterator(
server: elt.cluster.server.replace(/\/$/, ''),
skipTLSVerify: elt.cluster['insecure-skip-tls-verify'] === true,
tlsServerName: elt.cluster['tls-server-name'],
proxyUrl: elt.cluster['proxy-url'],
};
} catch (err) {
switch (onInvalidEntry) {
Expand Down
2 changes: 1 addition & 1 deletion src/web-socket-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class WebSocketHandler implements WebSocketInterface {
if (data instanceof Buffer) {
data.copy(buff, 1);
} else {
buff.write(data, 1);
buff.write(data as string, 1);
}

let i = 0;
Expand Down
4 changes: 2 additions & 2 deletions testdata/kubeconfig-2.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: Q0FEQVRA
certificate-authority-data: Q0FEQVRA
server: http://example2.com
proxy-url: https://localhost:1181
name: clusterA

contexts:
Expand All @@ -27,4 +28,3 @@ users:
user:
username: foo
password: bar

30 changes: 30 additions & 0 deletions testdata/kubeconfig-proxy-url.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: Q0FEQVRA
server: http://example2.com
proxy-url: socks://example:1187
name: clusterA

contexts:
- context:
cluster: clusterA
user: userA
name: contextA

current-context: contextA
kind: Config
preferences: {}
users:
- name: userA
user:
client-certificate-data: XVNFUl9DQURBVEE=
client-key-data: XVNFUl9DS0RBVEE=
- name: userB
user:
client-certificate-data: XVNFUjJfQ0FEQVRB
client-key-data: XVNFUjJfQ0tEQVRB
- name: userC
user:
username: foo
password: bar
Loading
Loading