diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index e4ecd06..08464fb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -3,15 +3,19 @@ name: docker on: push: branches: - - master + - main pull_request: branches: - - master + - main concurrency: group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.run_number || github.event.pull_request.number }} cancel-in-progress: true +permissions: + contents: read + id-token: write + jobs: docker: name: Build Docker image @@ -28,51 +32,32 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to Artifactory - if: ${{ github.event_name == 'push' }} - uses: docker/login-action@v3 - with: - registry: splitio-docker-dev.jfrog.io - username: ${{ secrets.ARTIFACTORY_DOCKER_USER }} - password: ${{ secrets.ARTIFACTORY_DOCKER_PASS }} - - name: Create build version run: echo "BUILD_VERSION=$(cat package.json | grep version | head -1 | awk '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]')" >> $GITHUB_ENV - - name: Docker build - uses: docker/build-push-action@v6 + - name: Login to Dockerhub + uses: docker/login-action@v3 with: - context: . - push: ${{ github.event_name == 'push' }} - platforms: linux/amd64,linux/arm64 - tags: splitio-docker-dev.jfrog.io/${{ github.event.repository.name }}:${{ env.BUILD_VERSION}},splitio-docker-dev.jfrog.io/${{ github.event.repository.name }}:latest + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_RO_TOKEN }} - lacework: - name: Scan Docker image - if: ${{ github.event_name == 'pull_request' }} - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Configure AWS credentials + if: ${{ github.event_name == 'push' }} + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ vars.ECR_TESTING_ROLE_ARN }} + aws-region: us-east-1 - - name: Create build version - run: echo "BUILD_VERSION=$(cat package.json | grep version | head -1 | awk '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]')" >> $GITHUB_ENV + - name: Login to Amazon ECR + if: ${{ github.event_name == 'push' }} + uses: aws-actions/amazon-ecr-login@v2 - name: Docker build uses: docker/build-push-action@v6 with: context: . - push: false - tags: splitio-docker-dev.jfrog.io/${{ github.event.repository.name }}:${{ env.BUILD_VERSION}} - build-args: | - ARTIFACTORY_USER=${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_TOKEN=${{ secrets.ARTIFACTORY_TOKEN }} - - - name: Scan container using Lacework - uses: lacework/lw-scanner-action@v1.4.5 - with: - LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_NAME }} - LW_ACCESS_TOKEN: ${{ secrets.LW_ACCESS_TOKEN }} - IMAGE_NAME: splitio-docker-dev.jfrog.io/${{ github.event.repository.name }} - IMAGE_TAG: ${{ env.BUILD_VERSION}} - SAVE_RESULTS_IN_LACEWORK: true + push: ${{ github.event_name == 'push' }} + platforms: linux/amd64,linux/arm64 + tags: | + ${{ vars.ECR_TESTING_URL }}/${{ github.event.repository.name }}:${{ env.BUILD_VERSION}} + ${{ vars.ECR_TESTING_URL }}/${{ github.event.repository.name }}:latest diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index ee40538..d528d6b 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -3,19 +3,33 @@ name: unstable on: push: branches-ignore: - - master + - main + +permissions: + contents: read + id-token: write jobs: push-docker-image: name: Build and Push Docker Image runs-on: ubuntu-latest steps: - - name: Login to DockerHub + - name: Login to Dockerhub uses: docker/login-action@v3 with: - registry: splitio-docker-dev.jfrog.io - username: ${{ secrets.ARTIFACTORY_DOCKER_USER }} - password: ${{ secrets.ARTIFACTORY_DOCKER_PASS }} + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_RO_TOKEN }} + + - name: Configure AWS credentials + if: ${{ github.event_name == 'push' }} + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ vars.ECR_TESTING_ROLE_ARN }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + if: ${{ github.event_name == 'push' }} + uses: aws-actions/amazon-ecr-login@v2 - name: Checkout code uses: actions/checkout@v4 @@ -37,4 +51,5 @@ jobs: context: . push: true platforms: linux/amd64,linux/arm64 - tags: splitio-docker-dev.jfrog.io/${{ github.event.repository.name }}:${{ env.SHORT_SHA}} + tags: | + ${{ vars.ECR_TESTING_URL }}/${{ github.event.repository.name }}:${{ env.SHORT_SHA}} diff --git a/manager/__tests__/split.test.js b/manager/__tests__/split.test.js deleted file mode 100644 index 5ef505c..0000000 --- a/manager/__tests__/split.test.js +++ /dev/null @@ -1,75 +0,0 @@ -const request = require('supertest'); -const app = require('../../app'); -const { expectError, expectErrorContaining } = require('../../utils/testWrapper'); - -describe('split', () => { - // Testing authorization - test('should be 401 if auth is not passed', async () => { - const response = await request(app) - .get('/manager/split?split-name=split'); - expectError(response, 401, 'Unauthorized'); - }); - - test('should be 401 if auth does not match', async () => { - const response = await request(app) - .get('/manager/split?split-name=split') - .set('Authorization', 'invalid'); - expectError(response, 401, 'Unauthorized'); - }); - - test('should be 400 if split-name is not passed', async () => { - const expected = [ - 'you passed a null or undefined split-name, split-name must be a non-empty string.' - ]; - const response = await request(app) - .get('/manager/split') - .set('Authorization', 'test'); - expectErrorContaining(response, 400, expected); - }); - - test('should be 400 if split-name is empty', async () => { - const expected = [ - 'you passed an empty split-name, split-name must be a non-empty string.' - ]; - const response = await request(app) - .get('/manager/split?split-name=') - .set('Authorization', 'test'); - expectErrorContaining(response, 400, expected); - }); - - test('should be 400 if split-name is empty trimmed', async () => { - const expected = [ - 'you passed an empty split-name, split-name must be a non-empty string.' - ]; - const response = await request(app) - .get('/manager/split?split-name= ') - .set('Authorization', 'test'); - expectErrorContaining(response, 400, expected); - }); - - test('should be 404 if split is not found', async () => { - const response = await request(app) - .get('/manager/split?split-name=not-found') - .set('Authorization', 'test'); - expect(response.statusCode).toBe(404); - expect(response.body).toHaveProperty('error', 'Feature flag "not-found" was not found.'); - }); - - test('should be 200 and matches with passed split in YAML', async () => { - const response = await request(app) - .get('/manager/split?split-name=my-experiment') - .set('Authorization', 'test'); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('name', 'my-experiment'); - expect(response.body).toHaveProperty('trafficType', 'localhost'); - expect(response.body).toHaveProperty('killed', false); - expect(response.body).toHaveProperty('changeNumber', 0); - expect(response.body).toHaveProperty('treatments'); - expect(response.body.treatments).toEqual(expect.arrayContaining(['on', 'off'])); - expect(response.body).toHaveProperty('configs'); - expect(response.body.configs).toEqual({ - on: '{"desc" : "this applies only to ON treatment"}', - off: '{"desc" : "this applies only to OFF and only for only_test. The rest will receive ON"}', - }); - }); -}); diff --git a/manager/__tests__/splitNames.test.js b/manager/__tests__/splitNames.test.js deleted file mode 100644 index 40635aa..0000000 --- a/manager/__tests__/splitNames.test.js +++ /dev/null @@ -1,30 +0,0 @@ -const request = require('supertest'); -const app = require('../../app'); -const { expectError } = require('../../utils/testWrapper'); - -describe('names', () => { - // Testing authorization - test('should be 401 if auth is not passed', async () => { - const response = await request(app) - .get('/manager/names'); - expectError(response, 401, 'Unauthorized'); - }); - - test('should be 401 if auth does not match', async () => { - const response = await request(app) - .get('/manager/names') - .set('Authorization', 'invalid'); - expectError(response, 401, 'Unauthorized'); - }); - - test('should be 200 and retuns the feature flags defined in YAML', async () => { - const response = await request(app) - .get('/manager/names') - .set('Authorization', 'test'); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('splits'); - expect(response.body.splits.length).toEqual(4); - expect(response.body.splits) - .toEqual(expect.arrayContaining(['my-experiment', 'other-experiment-3', 'other-experiment', 'other-experiment-2'])); - }); -}); diff --git a/manager/__tests__/splits.test.js b/manager/__tests__/splits.test.js deleted file mode 100644 index 2cd3c61..0000000 --- a/manager/__tests__/splits.test.js +++ /dev/null @@ -1,29 +0,0 @@ -const request = require('supertest'); -const app = require('../../app'); -const { expectError } = require('../../utils/testWrapper'); - -describe('splits', () => { - // Testing authorization - test('should be 401 if auth is not passed', async () => { - const response = await request(app) - .get('/manager/splits'); - expectError(response, 401, 'Unauthorized'); - }); - - test('should be 401 if auth does not match', async () => { - const response = await request(app) - .get('/manager/splits') - .set('Authorization', 'invalid'); - expectError(response, 401, 'Unauthorized'); - }); - - test('should be 200 and returns the feature flags added in YAML', async () => { - const response = await request(app) - .get('/manager/splits') - .set('Authorization', 'test'); - expect(response.statusCode).toBe(200); - expect(response.body).toHaveProperty('splits'); - const keys = Object.keys(response.body.splits); - expect(keys.length).toEqual(4); - }); -}); diff --git a/manager/manager.controller.js b/manager/manager.controller.js deleted file mode 100644 index e6fcac5..0000000 --- a/manager/manager.controller.js +++ /dev/null @@ -1,60 +0,0 @@ -const environmentManager = require('../environmentManager').getInstance(); - -/** - * split returns splitView for a particular feature flag - * @param {*} req - * @param {*} res - */ -const split = async (req, res) => { - const featureFlagName = req.splitio.featureFlagName; - - try { - const manager = environmentManager.getManager(req.headers.authorization); - const featureFlag = await manager.split(featureFlagName); - return featureFlag ? res.send(featureFlag) : res.status(404).send({ - error: `Feature flag "${featureFlagName}" was not found.`, - }); - } catch (error) { - res.status(500).send({error}); - } -}; - -/** - * splits returns featureFlags - * @param {*} req - * @param {*} res - */ -const splits = async (req, res) => { - try { - const manager = environmentManager.getManager(req.headers.authorization); - const featureFlags = await manager.splits(); - res.send({ - splits: featureFlags, - }); - } catch (error) { - res.status(500).send({error}); - } -}; - -/** - * splitNames returns featureFlagNames - * @param {*} req - * @param {*} res - */ -const splitNames = async (req, res) => { - try { - const manager = environmentManager.getManager(req.headers.authorization); - const featureFlagNames = await manager.names(); - res.send({ - splits: featureFlagNames, - }); - } catch (error) { - res.status(500).send({error}); - } -}; - -module.exports = { - splitNames, - split, - splits, -}; diff --git a/manager/manager.router.js b/manager/manager.router.js deleted file mode 100644 index 4e2a9f3..0000000 --- a/manager/manager.router.js +++ /dev/null @@ -1,36 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const splitValidator = require('../utils/inputValidation/split'); -const managerController = require('./manager.controller'); -const { parseValidators } = require('../utils/utils'); - -/** - * featureFlagValidation performs input validation for manager call - * @param {object} req - * @param {object} res - * @param {function} next - */ -const featureFlagValidation = (req, res, next) => { - const featureFlagNameValidation = splitValidator(req.query['split-name']); - - const error = parseValidators([featureFlagNameValidation]); - if (error.length) { - return res - .status(400) - .send({ - error, - }); - } else { - req.splitio = { - featureFlagName: featureFlagNameValidation.value, - }; - } - - next(); -}; - -router.get('/split', featureFlagValidation, managerController.split); -router.get('/splits', managerController.splits); -router.get('/names', managerController.splitNames); - -module.exports = router;