Skip to content
Draft
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
55 changes: 39 additions & 16 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ jobs:
tests:
needs: build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
suite:
- replication
- unit
- api:routes
- api:retry
- lifecycle
- ingestion
- lib
- notification
- ballooning
services:
redis:
image: redis:alpine
Expand Down Expand Up @@ -134,24 +147,34 @@ jobs:
cache: yarn
- name: Install node dependencies
run: yarn install --ignore-engines --frozen-lockfile --network-concurrency 1
- name: Lint markdown
run: yarn run --silent lint_md
- name: Lint Javascript
run: yarn run --silent lint

# - name: Lint markdown
# run: yarn run --silent lint_md

- name: Run feature replication tests
if: matrix.suite == 'replication'
uses: ./.github/actions/ft-test
with:
testsuite: replication
token: ${{ secrets.CODECOV_TOKEN }}

- name: Run unit tests
if: matrix.suite == 'unit'
run: yarn run cover
env:
BACKBEAT_CONFIG_FILE: tests/config.json
TEST_SUITE: test

- uses: codecov/codecov-action@v5
- name: Upload unit test coverage
if: matrix.suite == 'unit'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
directory: ./coverage/test
flags: unit

- name: Run backbeat routes test
if: matrix.suite == 'api:routes'
uses: ./.github/actions/ft-test
with:
testsuite: api:routes
Expand All @@ -161,43 +184,43 @@ jobs:
MANAGEMENT_BACKEND: operator

- name: Run backbeat retry tests with account authentication
if: matrix.suite == 'api:retry'
uses: ./.github/actions/ft-test
with:
testsuite: api:retry
token: ${{ secrets.CODECOV_TOKEN }}
runner: run_server_tests.bash

- name: run feature replication tests
uses: ./.github/actions/ft-test
with:
testsuite: replication
token: ${{ secrets.CODECOV_TOKEN }}

- name: run feature lifecycle tests
- name: Run feature lifecycle tests
if: matrix.suite == 'lifecycle'
uses: ./.github/actions/ft-test
with:
testsuite: lifecycle
token: ${{ secrets.CODECOV_TOKEN }}

- name: run feature ingestion tests
- name: Run feature ingestion tests
if: matrix.suite == 'ingestion'
uses: ./.github/actions/ft-test
with:
testsuite: ingestion
token: ${{ secrets.CODECOV_TOKEN }}

- name: run misc functional tests
- name: Run misc functional tests
if: matrix.suite == 'lib'
uses: ./.github/actions/ft-test
with:
testsuite: lib
token: ${{ secrets.CODECOV_TOKEN }}

- name: run backbeat notification feature tests
- name: Run backbeat notification feature tests
if: matrix.suite == 'notification'
uses: ./.github/actions/ft-test
with:
testsuite: notification
token: ${{ secrets.CODECOV_TOKEN }}

- name: run ballooning tests for lifecycle conductor
- name: Run ballooning tests for lifecycle conductor
if: matrix.suite == 'ballooning'
run: yarn mocha tests/performance/lifecycle/conductor-check-memory-balloon.js --exit
env:
# Constrain heap long-lived heap size to 150MB, so that pushing 200K messages
Expand Down
176 changes: 88 additions & 88 deletions bin/ensureServiceUser
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ const { program } = require('commander');
const werelogs = require('werelogs');
const version = require('../package.json').version;
const async = require('async');
const { IAM, STS } = require('aws-sdk');
const { IAMClient, GetUserCommand, CreateUserCommand, ListPoliciesCommand, CreatePolicyCommand,
ListAttachedUserPoliciesCommand, AttachUserPolicyCommand, GetRoleCommand, CreateRoleCommand,
ListAttachedRolePoliciesCommand, AttachRolePolicyCommand, ListAccessKeysCommand, CreateAccessKeyCommand,
NoSuchEntityException } = require('@aws-sdk/client-iam');
const { STSClient, GetCallerIdentityCommand } = require('@aws-sdk/client-sts');

const systemPrefix = '/scality-internal/';

Expand Down Expand Up @@ -42,14 +46,14 @@ function generateRoleTrustPolicyDocument(userArn) {
}

function createIAMClient(opts) {
return new IAM({
return new IAMClient({
endpoint: opts.iamEndpoint,
region: opts.region,
});
}

function createSTSClient(opts) {
return new STS({
return new STSClient({
endpoint: opts.stsEndpoint,
region: opts.region,
});
Expand Down Expand Up @@ -111,21 +115,21 @@ class UserHandler extends BaseHandler {
return 'user';
}

collect() {
return this.iamClient.getUser({
async collect() {
const command = new GetUserCommand({
UserName: this.resourceName,
})
.promise()
.then(res => res.User);
});
const res = await this.iamClient.send(command);
return res.User;
}

create(allResources) {
return this.iamClient.createUser({
async create(allResources) {
const command = new CreateUserCommand({
UserName: this.resourceName,
Path: systemPrefix,
})
.promise()
.then(res => res.User);
});
const res = await this.iamClient.send(command);
return res.User;
}

conflicts(u) {
Expand All @@ -138,49 +142,44 @@ class PolicyHandler extends BaseHandler {
return 'policy';
}

collect() {
return this.iamClient.listPolicies({
async collect() {
const command = new ListPoliciesCommand({
MaxItems: 100,
OnlyAttached: false,
Scope: 'All',
})
.promise()
.then(res => res.Policies.find(p => p.PolicyName === this.resourceName));
});
const res = await this.iamClient.send(command);
return res.Policies.find(p => p.PolicyName === this.resourceName);
}

create(allResources) {
return new Promise((resolve, reject) => {
if (!this.options.constrainToThisAccount) {
return resolve('*');
}

return this.stsClient.getCallerIdentity((err, res) => {
if (err) {
// return reject(err);
// Workaround a Vault issue on 8.3 branch
// https://scality.atlassian.net/browse/VAULT-238
return resolve('000000000000');
}

return resolve(res.Account);
});
})
.then(accountId => {
if (this.options.policy) {
return this.options.policy;
async create(allResources) {
let accountId;

if (!this.options.constrainToThisAccount) {
accountId = '*';
} else {
try {
const command = new GetCallerIdentityCommand({});
const res = await this.stsClient.send(command);
accountId = res.Account;
} catch (err) {
// Workaround a Vault issue on 8.3 branch
// https://scality.atlassian.net/browse/VAULT-238
accountId = '000000000000';
}
}

return generateUserAssumeRolePolicyDocument(this.serviceName, accountId);
})
.then(policyDocument =>
this.iamClient.createPolicy({
PolicyName: this.resourceName,
PolicyDocument: JSON.stringify(policyDocument),
Path: systemPrefix,
})
.promise()
)
.then(res => res.Policy);
const policyDocument = this.options.policy ||
generateUserAssumeRolePolicyDocument(this.serviceName, accountId);

const command = new CreatePolicyCommand({
PolicyName: this.resourceName,
PolicyDocument: JSON.stringify(policyDocument),
Path: systemPrefix,
});

const res = await this.iamClient.send(command);
return res.Policy;
}

conflicts(p) {
Expand All @@ -193,24 +192,25 @@ class RoleHandler extends BaseHandler {
return 'role';
}

collect() {
return this.iamClient.getRole({
async collect() {
const command = new GetRoleCommand({
RoleName: this.resourceName,
})
.promise()
.then(res => res.Role);
});
const res = await this.iamClient.send(command);
return res.Role;
}

create(allResources) {
async create(allResources) {
const trustPolicy = generateRoleTrustPolicyDocument(allResources.user.Arn);

return this.iamClient.createRole({
const command = new CreateRoleCommand({
RoleName: this.resourceName,
Path: systemPrefix,
AssumeRolePolicyDocument: JSON.stringify(trustPolicy),
})
.promise()
.then(res => res.Role);
});

const res = await this.iamClient.send(command);
return res.Role;
}

conflicts(p) {
Expand All @@ -223,21 +223,21 @@ class PolicyUserAttachmentHandler extends BaseHandler {
return 'policyAttachment';
}

collect() {
return this.iamClient.listAttachedUserPolicies({
async collect() {
const command = new ListAttachedUserPoliciesCommand({
UserName: this.resourceName,
MaxItems: 100,
})
.promise()
.then(res => res.AttachedPolicies);
});
const res = await this.iamClient.send(command);
return res.AttachedPolicies;
}

create(allResources) {
return this.iamClient.attachUserPolicy({
async create(allResources) {
const command = new AttachUserPolicyCommand({
PolicyArn: allResources.policy_user.Arn,
UserName: this.resourceName,
})
.promise();
});
await this.iamClient.send(command);
}

conflicts(p) {
Expand All @@ -250,21 +250,21 @@ class PolicyRoleAttachmentHandler extends BaseHandler {
return 'policyRoleAttachment';
}

collect() {
return this.iamClient.listAttachedRolePolicies({
async collect() {
const command = new ListAttachedRolePoliciesCommand({
RoleName: this.resourceName,
MaxItems: 100,
})
.promise()
.then(res => res.AttachedPolicies);
});
const res = await this.iamClient.send(command);
return res.AttachedPolicies;
}

create(allResources) {
return this.iamClient.attachRolePolicy({
async create(allResources) {
const command = new AttachRolePolicyCommand({
PolicyArn: allResources.policy_role.Arn,
RoleName: this.resourceName,
})
.promise();
});
await this.iamClient.send(command);
}

conflicts(p) {
Expand All @@ -277,21 +277,21 @@ class AccessKeyHandler extends BaseHandler {
return 'accessKey';
}

collect() {
return this.iamClient.listAccessKeys({
async collect() {
const command = new ListAccessKeysCommand({
UserName: this.resourceName,
MaxItems: 100,
})
.promise()
.then(res => res.AccessKeyMetadata);
});
const res = await this.iamClient.send(command);
return res.AccessKeyMetadata;
}

create(allResources) {
return this.iamClient.createAccessKey({
async create(allResources) {
const command = new CreateAccessKeyCommand({
UserName: this.resourceName,
})
.promise()
.then(res => res.AccessKey);
});
const res = await this.iamClient.send(command);
return res.AccessKey;
}

conflicts(a) {
Expand All @@ -303,7 +303,7 @@ function collectResource(v, done) {
v.collect()
.then(res => done(null, res))
.catch(err => {
if (err.code === 'NoSuchEntity') {
if (err instanceof NoSuchEntityException) {
return done(null, null);
}
done(err);
Expand Down
Loading
Loading