--- tags: feature author: Oliver.W, Tim --- # Verfication Feature [![hackmd-github-sync-badge](https://hackmd.io/4q5NJy6pRse5xfM9E0Tkrw/badge)](https://hackmd.io/4q5NJy6pRse5xfM9E0Tkrw) ## Requirements 目前用户遇到的问题多为配置和账户相关问题,在这些问题上,serverless framework目前并没有有效的方式校验并提示用户。腾讯的错误信息也不够友好,不足以让用户知道如何使配置serverless以解决问题,同时还存在以下问题: * 组件的多个版本需要维护非常多的校验文件。 * 无法为校验添加多个规则 * 无法添加警告校验信息 * 无法进行组件之外的校验,比如组件间引用的校验。 * 校验文件无法在不更新组件的情况下单独更新。 ### Key Results * 添加在Serverless Platform的服务端校验。 * 每个校验支持多条校验规则,同时可以对规则进行分组和添加优先级(error/warning) ![](https://i.imgur.com/NGP3nbf.png) * 可以动态更新,加载校验规则文件(不需要重新部署platform) * 一次校验可以返回所有错误。 ![](https://i.imgur.com/As6JERa.png) * 校验文件统一存储在git repo中,可以进行修改 https://github.com/serverlessinc/tencent-component-types * 组件的校验自动向前匹配最近的版本进行校验。 * 可以提供警告信息,单纯的警告不会终止部署 ![](https://i.imgur.com/oiuhFbn.png) * 向前兼容(`components@v<=3.15.0`) ![](https://i.imgur.com/1dCS6jn.png) ![](https://i.imgur.com/rEUdQfv.png) ### 问题 * SCF-name 名称长度的校验。 * 环境变量注入 * 多个组件的基础信息。 * inputs的配置进行校验。 * 上传文件之后。 ### 例子 1. 必填字段缺失 > component: 不存在 2. 字段校验,多条件, > app: 应用名称超长 3. 组件间关联字段丢失 > vpc-name: 未定义 预期返回结果:(暂定) ``` scf 组件校验结果 : 错误2 警告2 规则版本v0.0.3 ----------------------------------------- * app - 组件component是必填字段,需要指定要是用的组件名称。(错误-红) * stage - 名称不能包含非英文及数字的特殊字符。(错误-红色) - 名称长度过长,建议控制长度为10个字符。(警告-黄色) * inputs.field - 当前vpc名称不存在。(警告-黄色) ``` ``` scf 组件校验结果 : 错误2 警告1 规则版本v0.0.3 ----------------------------------------- 当前组件版本已不再更新,建议升级到 1.00 版本之上(警告-黄色) * app - 此字段类型不正确,请使用 String 类型。(警告-红色) * inputs.field3 - 此字段为必填字段。(警告-红色) ----------------------------------------- 可以使用 sls deploy --force 跳过校验进行部署。 ``` 1. YAML config 2. Create Instance Obj 1. get component <!-- 3. Validation (component non-refer fields) --> 4. Save Instance (complete reference fields) 5. Validation (component fields) ## User Experience ### Developer Scenario: Developer publish a new verison of components When developer upload a new validation to the repo Then the validation rules will sync to Serverless Platform And during components deploy will use the rules to verify the config file. ### User Scenario: Deploy a component app with Serverless CLI Given a complete config a serverless app When user deploy the app to cloud Then the Serverless Platform will check the configs by components And list the error & warning messages in console ## Architecture Design ### 校验规则的更新和使用过程: 1. 在 https://github.com/serverlessinc/tencent-component-types 存入scf@0.0.0.yml, scf@1.0.0.yml 等文件存放 types.(只有在校验规则有 breaking change 的时候才引入新版本的校验规则) 2. 当文件更改时, GitHub Action 同步配置到 Redis 3. 用户部署时从 redis 拿到对应 Component 规则,并对用户的 yml 做校验 ### 具体设计要点: - 匹配规则: 如果用户 component 版本是 1.0.1,我们在数据库中找到 0.0.0 和 3.0.0 两个匹配规则,使用 0.0.0 版本匹配规则。如果用户 component 没有配置版本(大多数情况),使用最高版本配置规则 - 校验规则:沿用目前 types 的格式 关键词:type, required, allow, regex, min, max(for number type)... - 校验使用的库:https://github.com/sideway/joi 兼容原有的 types 系统,并增加两个新特性: - 允许对同一个字段进行多个校验 - 加入 waring 和 error 字段标记错误程度 例子 ``` message(可选): "当前组件版本已不再更新,建议升级到 1.00 版本之上/建议使用http组件替换更新,详情查看:xxxx" messageLevel: warning inputs: region: type: string required: false allow: - ap-guangzhou - ap-shanghai message: 'region 无法识别' level: error name: type: string required: false rules: - regex: '^[A-Za-z][\w-_]{0,28}[A-Za-z0-9]$' message: '名称不能包含非英文及数字的特殊字符' level: error - regex: '^[A-Za-z][\w-_]{0,10}[A-Za-z0-9]$' message: '名称长度过长,建议控制长度为10个字符' level: warning // 对outpus校验 未来添加暂不实现。 outputs: ``` ### 配置说明列表 filename example: `scf@0.8.2.yml` | field | 必填 | 示例 | 备注 | | ----------- | ---- | ----------------------------------------------- | --------------------------- | | message | 否 | string/number/boolean/object/array/datetime/url | | | messageLevel | 否 | | 默认 warning | | inputs | 否 | | 默认 error, error会终止进程 | | outpus | 否 | | | inputs 中字段支持的条件 | type | 必填 | 规则 | 示例 | 备注 | | -------- | ---- | ---- | ----------------------------------------------- | ----------- | | type | 是 | 是 | string/number/boolean/object/array/datetime/url | | | required | 否 | 是 | | 默认 false | | rules | 否 | 否 | | | | items | 否 | 否 | | 数组类型 | | keys | 否 | 否 | | Object 类型 | > 只有一个规则,可以将规则直接写在inputs字段条件中,不需要嵌套在 rules rules 配置(多个规则放在rules 下,单个规则放在字段下) | type | 必填 | 支持type | 示例 | 备注 | | ------- | ---- | ------------------- | ---- | ---------- | | regex | 是 | string | | | | min | 否 | string,number,array | | | | max | 否 | string,number,array | | | | allow | 否 | string,number | | | | message | 否 | / | | | | level | 否 | / | | 默认 error | <!-- | string | | min, max, regex, allow | | | number | | min, max, allow | | | boolean | | / | | | object | | / | | | array | | min, max | | | datetime | | / | | | url | | / | | --> ### 返回校验结果 <!-- ``` { typeVersion: '0.0.1' errors: [{ path: ['name'], message: '错误信息' }], warnings: [] } ``` --> ```yml // 组件为单位的错误信息 component: version: messages: [{ path: 'message' level: 'warning/error' message: 'hello' }, { path: 'inputs.name' level: 'warning/error' message: 'hello' }] ```