From 655792c9a6262a79fe3b69369a26ac1a582ba48a Mon Sep 17 00:00:00 2001 From: maslow Date: Sun, 8 Aug 2021 03:26:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(fix):=20=E6=96=B0=E5=A2=9E=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=99=A8=E8=BF=9C=E7=A8=8B=E6=8E=A8=E9=80=81=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=EF=BC=8C=E8=BF=9C=E7=A8=8B=E6=8E=A8=E9=80=81=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E4=BF=9D=E6=8C=81=20=5Fid=20=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E5=BC=8F=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devops-server/src/api/function.ts | 23 ++++++- packages/devops-server/src/api/rules.ts | 22 ++++++- packages/devops-server/src/api/trigger.ts | 60 ++++++++++++++++++- .../devops-server/src/router/deploy/index.ts | 13 +++- 4 files changed, 111 insertions(+), 7 deletions(-) diff --git a/packages/devops-server/src/api/function.ts b/packages/devops-server/src/api/function.ts index 5d8c2b9450..9502166dbc 100644 --- a/packages/devops-server/src/api/function.ts +++ b/packages/devops-server/src/api/function.ts @@ -3,6 +3,7 @@ import { Constants } from "../constants" import { Globals } from "../lib/globals" import { compileTs2js } from 'cloud-function-engine/dist/utils' import { CloudFunctionStruct } from "cloud-function-engine" +import { ObjectId } from 'mongodb' import * as assert from 'assert' const db = Globals.sys_db @@ -110,17 +111,19 @@ export async function deployFunctions(functions: CloudFunctionStruct[]) { } async function _deployOneFunction(func: CloudFunctionStruct) { + + await _deleteFunctionWithSameNameButNotId(func) + const db = Globals.sys_accessor.db - const r = await db.collection('__functions').findOne({ name: func.name }) + const r = await db.collection('__functions').findOne({ _id: new ObjectId(func._id) }) const data = { ...func } - delete data['_id'] - // if exists function if (r) { + delete data['_id'] const ret = await db.collection('__functions').updateOne({ _id: r._id }, { $set: data }) @@ -132,4 +135,18 @@ async function _deployOneFunction(func: CloudFunctionStruct) { // if new function const ret = await db.collection('__functions').insertOne(data as any) assert(ret.insertedId, `deploy: add function ${func.name} occurred error`) +} + +/** + * 删除本地 _id 不同,但 name 相同的云函数(若存在) + * @param func + */ +async function _deleteFunctionWithSameNameButNotId(func: CloudFunctionStruct) { + const db = Globals.sys_accessor.db + await db.collection('__functions').findOneAndDelete({ + _id: { + $ne: new ObjectId(func._id) + }, + name: func.name + }) } \ No newline at end of file diff --git a/packages/devops-server/src/api/rules.ts b/packages/devops-server/src/api/rules.ts index 4488b9ab20..eb38e612d5 100644 --- a/packages/devops-server/src/api/rules.ts +++ b/packages/devops-server/src/api/rules.ts @@ -1,6 +1,7 @@ import * as assert from 'assert' import { Constants } from '../constants' import { Globals } from "../lib/globals" +import { ObjectId } from 'mongodb' const db = Globals.sys_db export interface RuleDocument { @@ -87,17 +88,20 @@ export async function deployPolicies(policies) { } async function _deployOnePolicy(policy: any) { + + await _deletePolicyWithSameNameButNotId(policy) + const db = Globals.sys_accessor.db - const r = await db.collection('__policies').findOne({ name: policy.name }) + const r = await db.collection('__policies').findOne({ _id: new ObjectId(policy._id) }) const data = { ...policy } - delete data['_id'] // if exists if (r) { + delete data['_id'] const ret = await db.collection('__policies').updateOne({ _id: r._id }, { $set: data }) @@ -109,4 +113,18 @@ async function _deployOnePolicy(policy: any) { // if new const ret = await db.collection('__policies').insertOne(data as any) assert(ret.insertedId, `deploy: add policy ${policy.name} occurred error`) +} + +/** + * 删除本地 _id 不同,但 name 相同的策略(若存在) + * @param func + */ +async function _deletePolicyWithSameNameButNotId(policy: any) { + const db = Globals.sys_accessor.db + await db.collection('__policies').findOneAndDelete({ + _id: { + $ne: new ObjectId(policy._id) + }, + name: policy.name + }) } \ No newline at end of file diff --git a/packages/devops-server/src/api/trigger.ts b/packages/devops-server/src/api/trigger.ts index eb261c6c6c..97b49b557e 100644 --- a/packages/devops-server/src/api/trigger.ts +++ b/packages/devops-server/src/api/trigger.ts @@ -1,8 +1,11 @@ import { Constants } from "../constants" import { Globals } from "../lib/globals" +import { ObjectId } from 'mongodb' +import * as assert from 'assert' const db = Globals.sys_db +const logger = Globals.logger /** * 请求触发器列表 @@ -35,7 +38,7 @@ export async function getTriggerById(id: string) { * 发布触发器 * 实为将 sys db __triggers 集合,复制其数据至 app db 中 */ - export async function publishTriggers() { +export async function publishTriggers() { const logger = Globals.logger const app_accessor = Globals.app_accessor @@ -54,4 +57,59 @@ export async function getTriggerById(id: string) { } finally { await session.endSession() } +} + + +/** + * 部署触发器 + * 应用远程推送过来的部署请求 + */ +export async function deployTriggers(triggers: any[]) { + assert.ok(triggers) + assert.ok(triggers instanceof Array) + const logger = Globals.logger + + const accessor = Globals.sys_accessor + + const data = triggers + const session = accessor.conn.startSession() + + try { + await session.withTransaction(async () => { + for (const func of data) { + await _deployOneTrigger(func) + } + }) + } catch (error) { + logger.error(error) + throw error + } finally { + await session.endSession() + } +} + +async function _deployOneTrigger(trigger: any) { + + const db = Globals.sys_accessor.db + const r = await db.collection('__triggers').findOne({ _id: new ObjectId(trigger._id) }) + + const data = { + ...trigger + } + + logger.debug('deploy trigger: ', data, r) + // if exists function + if (r) { + delete data['_id'] + const ret = await db.collection('__triggers').updateOne({ _id: r._id }, { + $set: data + }) + + assert(ret.matchedCount, `deploy: update trigger ${trigger.name} occurred error`) + return + } + + // if new function + const ret = await db.collection('__triggers').insertOne(data as any) + assert(ret.insertedId, `deploy: add trigger ${trigger.name} occurred error`) } \ No newline at end of file diff --git a/packages/devops-server/src/router/deploy/index.ts b/packages/devops-server/src/router/deploy/index.ts index 8ca46eb95b..1172b0d11a 100644 --- a/packages/devops-server/src/router/deploy/index.ts +++ b/packages/devops-server/src/router/deploy/index.ts @@ -5,6 +5,7 @@ import { checkPermission } from '../../api/permission' import { Globals } from '../../lib/globals' import { getToken, parseToken } from '../../lib/utils/token' import { deployPolicies, publishAccessPolicy } from '../../api/rules' +import { deployTriggers, publishTriggers } from '../../api/trigger' export const DeployRouter = express.Router() const logger = Globals.logger @@ -67,7 +68,7 @@ DeployRouter.post('/create-token', async (req, res) => { * 接收部署请求 */ DeployRouter.post('/in', async (req, res) => { - const { policies, functions, comment } = req.body + const { policies, functions, comment, triggers } = req.body if (!policies && !functions) { return res.status(422).send('invalid polices & functions') } @@ -116,6 +117,7 @@ DeployRouter.post('/in', async (req, res) => { status: 'pending', // 'pending' | 'deployed' | 'canceled' type: 'function', data: functions, + triggers, comment, created_at: Date.now() } @@ -159,11 +161,20 @@ DeployRouter.post('/apply', async (req, res) => { const type = deploy_request.type assert.ok(['function', 'policy'].includes(type)) + // deploy functions if (type === 'function') { await deployFunctions(deploy_request.data) + + // deploy triggers if had + if (deploy_request.triggers) { + await deployTriggers(deploy_request.triggers) + await publishTriggers() + } + await publishFunctions() } + // deploy policies if (type === 'policy') { await deployPolicies(deploy_request.data) await publishAccessPolicy()