Skip to content

Commit

Permalink
support non authenticated vaultadmin API in the conductor
Browse files Browse the repository at this point in the history
Issue: BB-622
  • Loading branch information
Kerkesni committed Nov 7, 2024
1 parent fc9e8b7 commit 46c62eb
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 5 deletions.
16 changes: 13 additions & 3 deletions extensions/utils/VaultClientWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const assert = require('assert');
const { ChainableTemporaryCredentials } = require('aws-sdk');
const { errorUtils } = require('arsenal');

const { authTypeAssumeRole } = require('../../lib/constants');
const { authTypeAssumeRole, authTypeNone } = require('../../lib/constants');
const VaultClientCache = require('../../lib/clients/VaultClientCache');
const CredentialsManager = require('../../lib/credentials/CredentialsManager');
const { http: HttpAgent, https: HttpsAgent } = require('httpagent');
Expand All @@ -23,7 +23,7 @@ class VaultClientWrapper {
}

init() {
if (this._authConfig.type !== authTypeAssumeRole) {
if (![authTypeAssumeRole, authTypeNone].includes(this._authConfig.type)) {
return;
}

Expand Down Expand Up @@ -110,10 +110,20 @@ class VaultClientWrapper {
}

getAccountIds(canonicalIds, cb) {
if (this._authConfig.type !== authTypeAssumeRole) {
if (![authTypeAssumeRole, authTypeNone].includes(this._authConfig.type)) {
return process.nextTick(cb, null, {});
}

if (this._authConfig.type === authTypeAssumeRole) {
return this.getAccountIdsWithTempCredentials(canonicalIds, cb);
}

const client = this._vaultClientCache.getClient(this._clientId);
const opts = {};
return client.getAccountIds(canonicalIds, opts, (err, res) => cb(err, res?.message?.body));
}

getAccountIdsWithTempCredentials(canonicalIds, cb) {
return this._tempCredsPromise
.then(creds => this._vaultClientCache.getClientWithAWSCreds(this._clientId, creds))
.then(client => client.enableIAMOnAdminRoutes())
Expand Down
7 changes: 5 additions & 2 deletions lib/config/configItems.joi.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const {
authTypeAccount,
authTypeService,
authTypeAssumeRole,
authTypeNone,
} = require('../constants');

const hostPortJoi = joi.object().keys({
Expand Down Expand Up @@ -69,7 +70,8 @@ const authJoi = joi.object({
type: joi.alternatives().try(
authTypeService,
authTypeAccount,
authTypeAssumeRole
authTypeAssumeRole,
authTypeNone,
).required(),
account: joi.string()
.when('type', { is: authTypeAccount, then: joi.required() })
Expand All @@ -79,7 +81,8 @@ const authJoi = joi.object({
sts: stsConfigJoi
.when('type', { is: authTypeAssumeRole, then: joi.required() }),
vault: hostPortJoi
.when('type', { is: authTypeAssumeRole, then: joi.required() }),
.when('type', { is: authTypeAssumeRole, then: joi.required() })
.when('type', { is: authTypeNone, then: joi.required() }),
});

const inheritedAuthJoi = authJoi
Expand Down
1 change: 1 addition & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const constants = {
authTypeAssumeRole: 'assumeRole',
authTypeAccount: 'account',
authTypeService: 'service',
authTypeNone: 'none',
services: {
queuePopulator: 'QueuePopulator',
replicationQueueProcessor: 'ReplicationQueueProcessor',
Expand Down
217 changes: 217 additions & 0 deletions tests/unit/utils/VaultClientWrapper.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,221 @@ describe('VaultClientWrapper', () => {
});
});

describe('init', () => {
it('should set vaultClinetCache if authConfig type is none', () => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'none' },
FakeLogger,
);

const storeAWSCredentialsPromise = sinon.stub(vaultClientWrapper, '_storeAWSCredentialsPromise').returns();

vaultClientWrapper.init();
assert(storeAWSCredentialsPromise.calledOnce);
assert(vaultClientWrapper._vaultClientCache);
});

it('should set vaultClinetCache if authConfig type is assumeRole', () => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'assumeRole' },
FakeLogger,
);

const storeAWSCredentialsPromise = sinon.stub(vaultClientWrapper, '_storeAWSCredentialsPromise').returns();

vaultClientWrapper.init();
assert(storeAWSCredentialsPromise.calledOnce);
assert(vaultClientWrapper._vaultClientCache);
});

it('should set vaultClinetCache if authConfig type is role', () => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);

const storeAWSCredentialsPromise = sinon.stub(vaultClientWrapper, '_storeAWSCredentialsPromise').returns();

vaultClientWrapper.init();
assert(storeAWSCredentialsPromise.notCalled);
});
});

describe('tempCredentialsReady', () => {
it('should return true if auth type is not assumeRole', () => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);
assert.strictEqual(vaultClientWrapper.tempCredentialsReady(), true);
});

it('should return the value of _tempCredsPromiseResolved', () => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'assumeRole' },
FakeLogger,
);
vaultClientWrapper._tempCredsPromiseResolved = true;
assert.strictEqual(vaultClientWrapper.tempCredentialsReady(), true);
});
});

describe('getAccountIds', () => {
it('should return empty result if authConfig type is not assumeRole', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);
vaultClientWrapper.getAccountIds(['account'], (err, res) => {
assert.ifError(err);
assert.deepEqual(res, {});
done();
});
});

it('should call getAccountIdsWithTempCredentials if auth type is assumeRole', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'assumeRole' },
FakeLogger,
);
const getAccountIdsWithTempCredentials =
sinon.stub(vaultClientWrapper, 'getAccountIdsWithTempCredentials').yields();
vaultClientWrapper.getAccountIds(['account'], err => {
assert.ifError(err);
assert(getAccountIdsWithTempCredentials.calledOnce);
done();
});
});

it('should use non authenticated API when auth type is none', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'none' },
FakeLogger,
false,
);
vaultClientWrapper.init();
sinon.stub(vaultClientWrapper._vaultClientCache, 'getClient').returns({
getAccountIds: (canonicalIds, opts, cb) =>
cb(null, { message: { body: { account: 'accountID' } } }),
});
vaultClientWrapper.getAccountIds(['account'], (err, accountIds) => {
assert.ifError(err);
assert.strictEqual(accountIds.account, 'accountID');
done();
});
});
});

describe('getAccountIdsWithTempCredentials', () => {
it('should return accountIds', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);
vaultClientWrapper._tempCredsPromise = Promise.resolve({});
vaultClientWrapper._vaultClientCache = {
getClientWithAWSCreds: sinon.stub().resolves({
enableIAMOnAdminRoutes: sinon.stub().resolves({
getAccountIds: (canonicalIds, opts, cb) =>
cb(null, { message: { body: { account: 'accountID' } } }),
}),
}),
};
vaultClientWrapper.getAccountIdsWithTempCredentials(['account'], (err, accountIds) => {
assert.ifError(err);
assert.strictEqual(accountIds.account, 'accountID');
done();
});
});

it('should return error if getAccountIds fails', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);
vaultClientWrapper._tempCredsPromise = Promise.resolve({});
vaultClientWrapper._vaultClientCache = {
getClientWithAWSCreds: sinon.stub().resolves({
enableIAMOnAdminRoutes: sinon.stub().resolves({
getAccountIds: (canonicalIds, opts, cb) =>
cb(errors.InternalError, null),
}),
}),
};
vaultClientWrapper.getAccountIdsWithTempCredentials(['account'], err => {
assert.deepStrictEqual(err, errors.InternalError);
done();
});
});

it('should return an error if enableIAMOnAdminRoutes fails', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);
vaultClientWrapper._tempCredsPromise = Promise.resolve({});
vaultClientWrapper._vaultClientCache = {
getClientWithAWSCreds: sinon.stub().resolves({
enableIAMOnAdminRoutes: sinon.stub().rejects(errors.InternalError),
}),
};
vaultClientWrapper.getAccountIdsWithTempCredentials(['account'], err => {
assert.deepStrictEqual(err, errors.InternalError);
done();
});
});

it('should return an error if getClientWithAWSCreds fails', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);
vaultClientWrapper._tempCredsPromise = Promise.resolve({});
vaultClientWrapper._vaultClientCache = {
getClientWithAWSCreds: sinon.stub().rejects(errors.InternalError),
};
vaultClientWrapper.getAccountIdsWithTempCredentials(['account'], err => {
assert.deepStrictEqual(err, errors.InternalError);
done();
});
});

it('should return an error if _tempCredsPromise fails', done => {
const vaultClientWrapper = new VaultClientWrapper(
'id',
{ host: '127.0.0.1', port: 8500 },
{ type: 'role' },
FakeLogger,
);
vaultClientWrapper._tempCredsPromise = Promise.reject(errors.InternalError);
vaultClientWrapper.getAccountIdsWithTempCredentials(['account'], err => {
assert.deepStrictEqual(err, errors.InternalError);
done();
});
});
});
});

0 comments on commit 46c62eb

Please sign in to comment.