Skip to content

Commit

Permalink
Merge pull request #702 from mansona/gcp-auth-file
Browse files Browse the repository at this point in the history
split cloud_auth into gcp and azure
  • Loading branch information
k8s-ci-robot authored Jul 30, 2021
2 parents 6b713dc + 1eddbe5 commit 1adb9a7
Show file tree
Hide file tree
Showing 6 changed files with 683 additions and 260 deletions.
4 changes: 2 additions & 2 deletions src/cloud_auth.ts → src/azure_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ interface Config {
['expiry-key']: string;
['access-token']?: string;
}
export class CloudAuth implements Authenticator {
export class AzureAuth implements Authenticator {
public isAuthProvider(user: User): boolean {
if (!user || !user.authProvider) {
return false;
}
return user.authProvider.name === 'azure' || user.authProvider.name === 'gcp';
return user.authProvider.name === 'azure';
}

public async applyAuthentication(
Expand Down
288 changes: 288 additions & 0 deletions src/azure_auth_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
import { expect } from 'chai';
import * as requestlib from 'request';
import { join } from 'path';

import { User, Cluster } from './config_types';
import { AzureAuth } from './azure_auth';
import { KubeConfig } from './config';

describe('AzureAuth', () => {
var auth: AzureAuth;
beforeEach(() => {
auth = new AzureAuth();
});

it('should be true for azure user', () => {
const user = {
authProvider: {
name: 'azure',
},
} as User;

expect(auth.isAuthProvider(user)).to.equal(true);
});

it('should be false for other user', () => {
const user = {
authProvider: {
name: 'gcp',
},
} as User;

expect(auth.isAuthProvider(user)).to.equal(false);
});

it('should be false for null user.authProvider', () => {
const user = {} as User;

expect(auth.isAuthProvider(user)).to.equal(false);
});

it('should populate from auth provider', async () => {
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
expiry: 'Fri Aug 24 07:32:05 PDT 3018',
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
opts.headers = [];
opts.headers.Host = 'foo.com';
await config.applyToRequest(opts);
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
});

it('should populate from auth provider without expirty', async () => {
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});

it('should populate rejectUnauthorized=false when skipTLSVerify is set', async () => {
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{ skipTLSVerify: true } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.rejectUnauthorized).to.equal(false);
});

it('should not set rejectUnauthorized if skipTLSVerify is not set', async () => {
// This test is just making 100% sure we validate certs unless we explictly set
// skipTLSVerify = true
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{} as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.rejectUnauthorized).to.equal(undefined);
});

it('should throw with expired token and no cmd', () => {
const config = new KubeConfig();
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
expiry: 'Aug 24 07:32:05 PDT 2017',
},
},
} as User,
);
const opts = {} as requestlib.Options;

return expect(config.applyToRequest(opts)).to.eventually.be.rejectedWith('Token is expired!');
});

it('should throw with bad command', () => {
const config = new KubeConfig();
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': 'token',
expiry: 'Aug 24 07:32:05 PDT 2017',
'cmd-path': 'non-existent-command',
},
},
} as User,
);
const opts = {} as requestlib.Options;
return expect(config.applyToRequest(opts)).to.eventually.be.rejectedWith(/Failed to refresh token/);
});

it('should exec with expired token', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
expiry: 'Aug 24 07:32:05 PDT 2017',
'cmd-path': 'echo',
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
it('should exec without access-token', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'cmd-path': 'echo',
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
it('should exec without access-token', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'cmd-path': 'echo',
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
it('should exec succesfully with spaces in cmd', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'cmd-path': join(__dirname, '..', 'test', 'echo space.js'),
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
});
6 changes: 4 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import shelljs = require('shelljs');

import * as api from './api';
import { Authenticator } from './auth';
import { CloudAuth } from './cloud_auth';
import { AzureAuth } from './azure_auth';
import {
Cluster,
ConfigOptions,
Expand All @@ -25,6 +25,7 @@ import {
} from './config_types';
import { ExecAuth } from './exec_auth';
import { FileAuth } from './file_auth';
import { GoogleCloudPlatformAuth } from './gcp_auth';
import { OpenIDConnectAuth } from './oidc_auth';

// fs.existsSync was removed in node 10
Expand All @@ -39,7 +40,8 @@ function fileExists(filepath: string): boolean {

export class KubeConfig {
private static authenticators: Authenticator[] = [
new CloudAuth(),
new AzureAuth(),
new GoogleCloudPlatformAuth(),
new ExecAuth(),
new FileAuth(),
new OpenIDConnectAuth(),
Expand Down
Loading

0 comments on commit 1adb9a7

Please sign in to comment.