Skip to content

Commit 4dd20a6

Browse files
authored
Merge pull request #2744 from davidgamero/useragent
add useragent with package version
2 parents 24dbae3 + f78746d commit 4dd20a6

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

src/config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,19 @@ import WebSocket from 'isomorphic-ws';
3636
import child_process from 'node:child_process';
3737
import { SocksProxyAgent } from 'socks-proxy-agent';
3838
import { HttpProxyAgent, HttpProxyAgentOptions, HttpsProxyAgent, HttpsProxyAgentOptions } from 'hpagent';
39+
import packagejson from '../package.json' with { type: 'json' };
40+
import { setHeaderMiddleware } from './middleware.js';
3941

4042
const SERVICEACCOUNT_ROOT: string = '/var/run/secrets/kubernetes.io/serviceaccount';
4143
const SERVICEACCOUNT_CA_PATH: string = SERVICEACCOUNT_ROOT + '/ca.crt';
4244
const SERVICEACCOUNT_TOKEN_PATH: string = SERVICEACCOUNT_ROOT + '/token';
4345
const SERVICEACCOUNT_NAMESPACE_PATH: string = SERVICEACCOUNT_ROOT + '/namespace';
46+
const USER_AGENT_KEY = 'User-Agent';
47+
48+
function getUserAgent(): string {
49+
const version = packagejson.version ?? '';
50+
return `kubernetes-client-javascript/${version}`;
51+
}
4452

4553
// fs.existsSync was removed in node 10
4654
function fileExists(filepath: string): boolean {
@@ -491,6 +499,7 @@ export class KubeConfig implements SecurityAuthentication {
491499
const config: Configuration = createConfiguration({
492500
baseServer: baseServerConfig,
493501
authMethods: authConfig,
502+
middleware: [setHeaderMiddleware(USER_AGENT_KEY, getUserAgent())],
494503
});
495504

496505
const apiClient = new apiClientType(config);

src/config_test.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { after, before, beforeEach, describe, it, mock } from 'node:test';
1+
import { after, before, beforeEach, describe, it, mock, TestContext } from 'node:test';
22
import assert, {
33
deepEqual,
44
deepStrictEqual,
@@ -1674,6 +1674,67 @@ describe('KubeConfig', () => {
16741674
const client = kc.makeApiClient(CoreV1Api);
16751675
strictEqual(client instanceof CoreV1Api, true);
16761676
});
1677+
1678+
it('should include User-Agent header with version', async (t: TestContext) => {
1679+
let capturedUserAgent: string | undefined;
1680+
1681+
const { server, host, port } = await createTestHttpsServer((req, res) => {
1682+
capturedUserAgent = req.headers['user-agent'];
1683+
1684+
res.setHeader('Content-Type', 'application/json');
1685+
res.writeHead(200);
1686+
res.end(
1687+
JSON.stringify({
1688+
apiVersion: 'v1',
1689+
kind: 'NamespaceList',
1690+
items: [],
1691+
}),
1692+
);
1693+
});
1694+
t.after(async () => {
1695+
await new Promise<Error | undefined>((resolve) => {
1696+
server.close(resolve);
1697+
});
1698+
});
1699+
1700+
const kc = new KubeConfig();
1701+
kc.loadFromClusterAndUser(
1702+
{
1703+
name: 'test-cluster',
1704+
server: `https://${host}:${port}`,
1705+
skipTLSVerify: true,
1706+
} as Cluster,
1707+
{
1708+
name: 'test-user',
1709+
token: 'test-token',
1710+
} as User,
1711+
);
1712+
1713+
const coreV1Api = kc.makeApiClient(CoreV1Api);
1714+
await coreV1Api.listNamespace();
1715+
1716+
// Read version from package.json
1717+
const packageJsonPath = join(__dirname, '..', 'package.json');
1718+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
1719+
const expectedVersion = packageJson.version;
1720+
1721+
// Verify version is not blank
1722+
strictEqual(typeof expectedVersion, 'string');
1723+
strictEqual(expectedVersion.length > 0, true, 'package.json version should not be blank');
1724+
1725+
// Verify User-Agent header contains client name and version
1726+
strictEqual(typeof capturedUserAgent, 'string');
1727+
strictEqual(
1728+
capturedUserAgent!.startsWith('kubernetes-client-javascript/'),
1729+
true,
1730+
'capturedUserAgent should start with "kubernetes-javascript-client/"',
1731+
);
1732+
strictEqual(
1733+
capturedUserAgent!.endsWith(expectedVersion),
1734+
true,
1735+
`User-Agent should include version ${expectedVersion}`,
1736+
);
1737+
});
16771738
});
16781739

16791740
describe('EmptyConfig', () => {

0 commit comments

Comments
 (0)