From fda85580760680831198004c7d8dcfa11f6e4f65 Mon Sep 17 00:00:00 2001 From: kerenfinkelstein Date: Thu, 14 Sep 2023 15:36:38 +0300 Subject: [PATCH] feat: add chaos mesh api description and table schema --- docs/openapi3.yaml | 249 ++++++++++++++++++ .../models/database/databaseConnector.js | 39 +++ .../database/sequelize/sequelizeConnector.js | 117 ++++++++ 3 files changed, 405 insertions(+) create mode 100644 src/chaos-experiments/models/database/databaseConnector.js create mode 100644 src/chaos-experiments/models/database/sequelize/sequelizeConnector.js diff --git a/docs/openapi3.yaml b/docs/openapi3.yaml index 3226c848..b8a55fc9 100644 --- a/docs/openapi3.yaml +++ b/docs/openapi3.yaml @@ -64,6 +64,9 @@ tags: - name: Webhooks description: | This resource allows you to configure webhooks. + - name: Chaos Experiments + description: | + This resource allows you to add chaos mesh experiments as part of the running job x-tagGroups: - name: Reference tags: @@ -1890,6 +1893,185 @@ paths: application/json: schema: $ref: '#/components/schemas/upload_file_response' + /v1/chaos-experiments: + parameters: + - $ref: '#/components/parameters/context_id' + post: + operationId: create-chaos-experiment + tags: + - Chaos Experiments + summary: Create chaos file + description: >- + Create a chaos experiment. + responses: + '201': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/chaosExperiment' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + '422': + description: Unprocessable entity + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/chaosExperiment' + description: The chaos experiment to create + required: true + get: + operationId: retrieve-all-choos-experiments + tags: + - Chaos Experiments + summary: Retrieve all chaos experiments + description: Retrieve all chaos experiments + parameters: + - in: query + name: from + description: From which result to start retrieve data - pagination + required: false + schema: + type: integer + minimum: 0 + default: 0 + - in: query + name: limit + description: Max results to return from this query ( Limit to 100 ) + required: false + schema: + type: integer + maximum: 200 + default: 100 + - in: query + name: template + description: filter to get templates only + required: false + schema: + type: boolean + example: true + - in: query + name: exclude + description: fields to exclude from response + required: false + schema: + type: array + items: + type: string + enum: + - kubeObject + responses: + '200': + description: Success + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/chaosExperiment' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + /v1/chaos-experiments/{experiment_id}: + parameters: + - $ref: '#/components/parameters/context_id' + get: + operationId: retrieve-chaos-experiment + tags: + - Chaos Experiments + summary: Retrieve chaos experiment + description: Retrieve a specific chaos experiment. + parameters: + - in: path + name: experiment_id + description: The id of the experiment to retrieve. + required: true + schema: + type: string + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/chaosExperiment' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + delete: + operationId: delete-chaos-experiment + tags: + - Chaos Experiments + summary: Delete chaos experiment + description: Delete a specific chaos experiment + parameters: + - in: path + name: experiment_id + description: The id of the experiment to retrieve. + required: true + schema: + type: string + responses: + '204': + description: Success + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + '409': + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/error_response' + components: parameters: context_id: @@ -2956,3 +3138,70 @@ components: url: type: string description: Webhook url to post events + chaosExperiment: + required: + - name + - kind + - namespace + properties: + id: + description: Unique experiment identifier + type: string + format: uuid + readOnly: true + name: + type: string + minLength: 1 + description: The name of the experiment. + example: Custom javascript for logging + kubeObject: + $ref: '#/components/schemas/kubeObject' + updated_at: + type: string + format: date-time + description: The date and time that the procesor file was updated. + readOnly: true + created_at: + type: string + format: date-time + description: The date and time that the procesor file was created. + readOnly: true + kubeObject: + required: + - apiVersion + - kind + - namespace + - name + - spec + properties: + apiVersion: + type: string + enum: + - "chaos-mesh.org/v1alpha1" + kind: + type: string + enum: + - 'dnschaos' + - 'PodChaos' + - 'AWSChaos' + - 'HTTPChaos' + - 'StressChaos' + description: A description of the experiment. + example: 'PodChaos' + namespace: + type: string + example: "apps" + name: + type: string + example: "my-pod-chaos" + spec: + type: object + example: + selector: + namespaces: + - apps + labelSelectors: + app: live-balances-api + mode: all + action: pod-kill + duration: 1m diff --git a/src/chaos-experiments/models/database/databaseConnector.js b/src/chaos-experiments/models/database/databaseConnector.js new file mode 100644 index 00000000..eedef802 --- /dev/null +++ b/src/chaos-experiments/models/database/databaseConnector.js @@ -0,0 +1,39 @@ +const sequelizeConnector = require('./sequelize/sequelizeConnector'); +const databaseConnector = sequelizeConnector; +module.exports = { + init, + getAllChaosExperiments, + insertChaosExperiment, + getChaosExperimentById, + getChaosExperimentByName, + deleteChaosExperiment, + closeConnection +}; + +async function init() { + return databaseConnector.init(); +} + +function closeConnection() { + return databaseConnector.closeConnection(); +} + +async function insertChaosExperiment(experimentId, experiment, contextId) { + return databaseConnector.insertChaosExperiment(experimentId, experiment, contextId); +} + +async function getAllChaosExperiments(from, limit, exclude, contextId) { + return databaseConnector.getAllChaosExperiments(from, limit, exclude, contextId); +} + +async function getChaosExperimentById(experimentId, contextId) { + return databaseConnector.getChaosExperimentById(experimentId, contextId); +} + +async function getChaosExperimentByName(name, contextId) { + return databaseConnector.getChaosExperimentByName(name, contextId); +} + +async function deleteChaosExperiment(experimentId) { + return databaseConnector.deleteChaosExperiment(experimentId); +} diff --git a/src/chaos-experiments/models/database/sequelize/sequelizeConnector.js b/src/chaos-experiments/models/database/sequelize/sequelizeConnector.js new file mode 100644 index 00000000..4b2329b4 --- /dev/null +++ b/src/chaos-experiments/models/database/sequelize/sequelizeConnector.js @@ -0,0 +1,117 @@ +'use strict'; + +const Sequelize = require('sequelize'); +const KUBEOBJECT = 'kubeObject'; +let client; + +module.exports = { + init, + getAllChaosExperiments, + insertChaosExperiment, + getChaosExperimentById, + getChaosExperimentByName, + deleteChaosExperiment +}; + +async function init(sequelizeClient) { + client = sequelizeClient; + await initSchemas(); +} + +async function insertChaosExperiment(experimentId, experiment, contextId) { + const chaosExperimentModel = client.model('chaos-experiment'); + const params = { + id: experimentId, + name: experiment.name, + kubeObject: experiment.kubeObject, + created_at: Date.now(), + updated_at: Date.now(), + context_id: contextId + }; + return chaosExperimentModel.create(params); +} + +async function getAllChaosExperiments(from, limit, exclude, contextId) { + const chaosExperimentModel = client.model('chaos-experiment'); + const attributes = {}, where = {}; + if (exclude && (exclude === KUBEOBJECT || exclude.includes(KUBEOBJECT))) { + attributes.exclude = [`${KUBEOBJECT}`]; + } + + if (contextId) { + where.context_id = contextId; + } + + const allExperiments = chaosExperimentModel.findAll({ attributes, offset: from, limit, order: [['created_at', 'DESC']], where }); + return allExperiments; +} + +async function _getChaosExperiment(options) { + const chaosExperimentModel = client.model('chaos-experiment'); + const chaosExperiments = await chaosExperimentModel.findAll(options); + return chaosExperiments[0]; +} + +async function getChaosExperimentById(experimentId, contextId) { + const options = { + where: { id: experimentId } + }; + + if (contextId) { + options.where.context_id = contextId; + } + + let chaosExperiment = await _getChaosExperiment(options); + if (chaosExperiment) { + chaosExperiment = chaosExperiment.get(); + } + return chaosExperiment; +} + +async function getChaosExperimentByName(experimentName, contextId) { + const options = { + where: { name: experimentName } + }; + + if (contextId) { + options.where.context_id = contextId; + } + + return _getChaosExperiment(options); +} + +async function deleteChaosExperiment(processorId) { + const chaosExperimentModel = client.model('chaos-experiment'); + const options = { + where: { + id: processorId + } + }; + + return chaosExperimentModel.destroy(options); +} + +async function initSchemas() { + const chaosExperiments = client.define('chaos-experiment', { + id: { + type: Sequelize.DataTypes.UUID, + primaryKey: true + }, + name: { + type: Sequelize.DataTypes.TEXT('medium') + }, + kubeObject: { + type: Sequelize.DataTypes.TEXT('JSON') + }, + created_at: { + type: Sequelize.DataTypes.DATE + }, + updated_at: { + type: Sequelize.DataTypes.DATE + }, + context_id: { + type: Sequelize.DataTypes.STRING + } + }); + await chaosExperiments.sync(); +}