feat: 新增 MongoDB、Ansible、Ansible Playbook 三个组件

- MongoDB: WiredTiger 引擎、认证、TLS、副本集、Oplog、压缩算法
- Ansible: SSH 连接、Pipelining、Become 提权、Forks、日志、事实缓存
- Ansible Playbook: 变量、包管理、服务管理、文件复制、模板渲染、Shell、Handlers
- 更新 README 组件矩阵与项目结构
- 更新 Schema 注册中心,新增自动化运维分类
This commit is contained in:
cnbugs
2026-07-18 19:28:34 +08:00
parent 5070664593
commit 4c25ae183e
5 changed files with 1092 additions and 2 deletions
+7 -1
View File
@@ -44,8 +44,11 @@
| 代理与 Web | **NGINX** | `.conf` | HTTP/HTTPS 端口、域名、SSL 证书、反向代理、Gzip、CORS |
| 缓存 | **Redis** | `.conf` | 单机/哨兵/集群模式、端口、内存限制、RDB/AOF 持久化、密码 |
| 数据库 | **MySQL** | `.cnf` | 版本(5.7/8.0)、Buffer Pool 自动计算、字符集、慢查询、主从复制 |
| 数据库 | **MongoDB** | `.conf` | 端口、WiredTiger 引擎、认证、TLS、副本集、Oplog、压缩算法 |
| 云原生 | **K8s Deployment** | `.yaml` | 镜像、副本数、资源限制、健康检查、滚动更新策略 |
| 云原生 | **K8s Service** | `.yaml` | ClusterIP/NodePort/LoadBalancer、端口映射、会话保持 |
| 自动化运维 | **Ansible** | `.cfg` | SSH 连接、Pipelining、Become 提权、Forks 并发、日志、事实缓存 |
| 自动化运维 | **Ansible Playbook** | `.yaml` | 变量、包管理、服务管理、文件复制、模板渲染、Shell 命令、Handlers |
---
@@ -105,8 +108,11 @@ conf-template/
│ ├── nginx.js # NGINX Schema 定义 + 模板生成
│ ├── redis.js # Redis Schema 定义 + 模板生成
│ ├── mysql.js # MySQL Schema 定义 + 模板生成
│ ├── mongodb.js # MongoDB Schema 定义 + 模板生成
│ ├── k8s-deployment.js # K8s Deployment Schema + YAML 生成
── k8s-service.js # K8s Service Schema + YAML 生成
── k8s-service.js # K8s Service Schema + YAML 生成
│ ├── ansible.js # Ansible Schema + 配置生成
│ └── ansible-playbook.js # Ansible Playbook Schema + YAML 生成
└── dist/ # 生产构建产物(gitignore
```
+468
View File
@@ -0,0 +1,468 @@
export const ansiblePlaybookSchema = {
id: 'ansible-playbook',
name: 'Ansible Playbook',
icon: 'List',
category: '自动化运维',
description: 'Ansible 任务编排与自动化剧本',
format: 'yaml',
fileName: 'playbook.yaml',
groups: [
{
title: 'Play 基本信息',
fields: [
{
key: 'playName',
label: 'Play 名称',
type: 'text',
placeholder: 'Configure web servers',
default: 'My Playbook',
required: true,
},
{
key: 'hosts',
label: '目标主机/组',
type: 'text',
placeholder: 'webservers 或 all',
default: 'all',
required: true,
},
{
key: 'become',
label: '使用 sudo 提权',
type: 'switch',
default: true,
},
{
key: 'gatherFacts',
label: '收集主机信息',
type: 'switch',
default: true,
},
],
},
{
title: '变量与环境',
fields: [
{
key: 'enableVars',
label: '定义变量',
type: 'switch',
default: false,
},
{
key: 'varAppPort',
label: '应用端口 (app_port)',
type: 'number',
min: 1,
max: 65535,
default: 8080,
dependsOn: { key: 'enableVars', value: true },
},
{
key: 'varAppName',
label: '应用名称 (app_name)',
type: 'text',
default: 'myapp',
dependsOn: { key: 'enableVars', value: true },
},
{
key: 'enableEnvironment',
label: '设置环境变量',
type: 'switch',
default: false,
},
{
key: 'envHttpProxy',
label: 'HTTP_PROXY',
type: 'text',
placeholder: 'http://proxy.example.com:8080',
default: 'http://proxy.example.com:8080',
dependsOn: { key: 'enableEnvironment', value: true },
},
{
key: 'envHttpsProxy',
label: 'HTTPS_PROXY',
type: 'text',
placeholder: 'http://proxy.example.com:8080',
default: 'http://proxy.example.com:8080',
dependsOn: { key: 'enableEnvironment', value: true },
},
],
},
{
title: '前置任务 (Pre Tasks)',
fields: [
{
key: 'enablePretasks',
label: '添加前置任务',
type: 'switch',
default: false,
},
{
key: 'pretaskUpdateCache',
label: '更新包管理器缓存',
type: 'switch',
default: true,
dependsOn: { key: 'enablePretasks', value: true },
},
],
},
{
title: 'Tasks — 包管理',
fields: [
{
key: 'taskInstallPackages',
label: '安装软件包',
type: 'switch',
default: false,
},
{
key: 'packagesToInstall',
label: '包名列表',
type: 'text',
placeholder: 'nginx, curl, vim (逗号分隔)',
default: 'nginx, curl',
dependsOn: { key: 'taskInstallPackages', value: true },
tip: '多个包用逗号分隔',
},
{
key: 'packageState',
label: '安装状态',
type: 'select',
options: [
{ label: 'present - 确保已安装', value: 'present' },
{ label: 'latest - 更新到最新版', value: 'latest' },
{ label: 'absent - 卸载', value: 'absent' },
],
default: 'present',
dependsOn: { key: 'taskInstallPackages', value: true },
},
],
},
{
title: 'Tasks — 服务管理',
fields: [
{
key: 'taskManageService',
label: '管理服务',
type: 'switch',
default: false,
},
{
key: 'serviceName',
label: '服务名称',
type: 'text',
placeholder: 'nginx',
default: 'nginx',
dependsOn: { key: 'taskManageService', value: true },
},
{
key: 'serviceState',
label: '服务状态',
type: 'select',
options: [
{ label: 'started - 启动', value: 'started' },
{ label: 'stopped - 停止', value: 'stopped' },
{ label: 'restarted - 重启', value: 'restarted' },
{ label: 'reloaded - 重载配置', value: 'reloaded' },
],
default: 'started',
dependsOn: { key: 'taskManageService', value: true },
},
{
key: 'serviceEnabled',
label: '开机自启',
type: 'switch',
default: true,
dependsOn: { key: 'taskManageService', value: true },
},
],
},
{
title: 'Tasks — 文件管理',
fields: [
{
key: 'taskCopyFile',
label: '复制文件到远程',
type: 'switch',
default: false,
},
{
key: 'copySrc',
label: '本地源文件路径',
type: 'text',
placeholder: './files/index.html',
default: './files/index.html',
dependsOn: { key: 'taskCopyFile', value: true },
},
{
key: 'copyDest',
label: '远程目标路径',
type: 'text',
placeholder: '/var/www/html/index.html',
default: '/var/www/html/index.html',
dependsOn: { key: 'taskCopyFile', value: true },
},
{
key: 'taskCreateDir',
label: '创建目录',
type: 'switch',
default: false,
},
{
key: 'dirPath',
label: '目录路径',
type: 'text',
placeholder: '/var/www/myapp',
default: '/var/www/myapp',
dependsOn: { key: 'taskCreateDir', value: true },
},
{
key: 'dirOwner',
label: '目录所有者',
type: 'text',
default: 'www-data',
dependsOn: { key: 'taskCreateDir', value: true },
},
{
key: 'dirMode',
label: '目录权限',
type: 'text',
default: '0755',
dependsOn: { key: 'taskCreateDir', value: true },
},
],
},
{
title: 'Tasks — 模板渲染',
fields: [
{
key: 'taskTemplate',
label: '渲染 Jinja2 模板',
type: 'switch',
default: false,
},
{
key: 'templateSrc',
label: '模板文件路径',
type: 'text',
placeholder: './templates/nginx.conf.j2',
default: './templates/nginx.conf.j2',
dependsOn: { key: 'taskTemplate', value: true },
},
{
key: 'templateDest',
label: '远程目标路径',
type: 'text',
placeholder: '/etc/nginx/nginx.conf',
default: '/etc/nginx/nginx.conf',
dependsOn: { key: 'taskTemplate', value: true },
},
{
key: 'templateOwner',
label: '文件所有者',
type: 'text',
default: 'root',
dependsOn: { key: 'taskTemplate', value: true },
},
{
key: 'templateMode',
label: '文件权限',
type: 'text',
default: '0644',
dependsOn: { key: 'taskTemplate', value: true },
},
],
},
{
title: 'Tasks — 执行命令',
fields: [
{
key: 'taskShell',
label: '执行 Shell 命令',
type: 'switch',
default: false,
},
{
key: 'shellCommand',
label: '命令内容',
type: 'text',
placeholder: 'systemctl daemon-reload',
default: 'systemctl daemon-reload',
dependsOn: { key: 'taskShell', value: true },
},
],
},
{
title: '后置任务 (Post Tasks) 与处理器',
fields: [
{
key: 'enableHandlers',
label: '定义处理器 (Handlers)',
type: 'switch',
default: false,
tip: '由 notify 触发的任务,如重启服务',
},
{
key: 'handlerName',
label: '处理器名称',
type: 'text',
default: 'restart nginx',
dependsOn: { key: 'enableHandlers', value: true },
},
{
key: 'handlerService',
label: '重启的服务',
type: 'text',
default: 'nginx',
dependsOn: { key: 'enableHandlers', value: true },
},
],
},
],
}
export function generateAnsiblePlaybookYaml(config) {
const indent = (str, n) => str.split('\n').map(l => ' '.repeat(n) + l).join('\n')
const lines = []
lines.push(`# Ansible Playbook - 由 ConfTemplate 生成`)
lines.push(`# 生成时间: ${new Date().toLocaleString('zh-CN')}`)
lines.push(`# 执行命令: ansible-playbook ${config.fileName || 'playbook.yaml'}`)
lines.push(``)
lines.push(`- name: ${config.playName}`)
lines.push(` hosts: ${config.hosts}`)
if (config.become) {
lines.push(` become: true`)
}
lines.push(` gather_facts: ${config.gatherFacts ? 'true' : 'false'}`)
// 变量
if (config.enableVars) {
lines.push(``)
lines.push(` vars:`)
lines.push(` app_port: ${config.varAppPort}`)
lines.push(` app_name: ${config.varAppName}`)
}
// 环境变量
if (config.enableEnvironment) {
lines.push(``)
lines.push(` environment:`)
lines.push(` HTTP_PROXY: ${config.envHttpProxy}`)
lines.push(` HTTPS_PROXY: ${config.envHttpsProxy}`)
}
// 前置任务
if (config.enablePretasks) {
lines.push(``)
lines.push(` pre_tasks:`)
if (config.pretaskUpdateCache) {
lines.push(` - name: Update apt cache`)
lines.push(` apt:`)
lines.push(` update_cache: yes`)
lines.push(` cache_valid_time: 3600`)
lines.push(` when: ansible_os_family == "Debian"`)
lines.push(``)
lines.push(` - name: Update yum cache`)
lines.push(` yum:`)
lines.push(` update_cache: yes`)
lines.push(` when: ansible_os_family == "RedHat"`)
}
}
// 主任务
lines.push(``)
lines.push(` tasks:`)
let taskNum = 0
// 安装包
if (config.taskInstallPackages) {
taskNum++
const pkgs = config.packagesToInstall.split(',').map(s => s.trim()).filter(Boolean)
lines.push(` - name: Install packages`)
lines.push(` ansible.builtin.package:`)
lines.push(` name:`)
pkgs.forEach(p => lines.push(` - ${p}`))
lines.push(` state: ${config.packageState}`)
lines.push(``)
}
// 文件复制
if (config.taskCopyFile) {
taskNum++
lines.push(` - name: Copy file to remote host`)
lines.push(` ansible.builtin.copy:`)
lines.push(` src: ${config.copySrc}`)
lines.push(` dest: ${config.copyDest}`)
lines.push(` owner: root`)
lines.push(` mode: '0644'`)
if (config.enableHandlers && config.handlerName) {
lines.push(` notify: ${config.handlerName}`)
}
lines.push(``)
}
// 创建目录
if (config.taskCreateDir) {
taskNum++
lines.push(` - name: Create application directory`)
lines.push(` ansible.builtin.file:`)
lines.push(` path: ${config.dirPath}`)
lines.push(` state: directory`)
lines.push(` owner: ${config.dirOwner}`)
lines.push(` mode: '${config.dirMode}'`)
lines.push(``)
}
// 模板渲染
if (config.taskTemplate) {
taskNum++
lines.push(` - name: Deploy configuration from template`)
lines.push(` ansible.builtin.template:`)
lines.push(` src: ${config.templateSrc}`)
lines.push(` dest: ${config.templateDest}`)
lines.push(` owner: ${config.templateOwner}`)
lines.push(` mode: '${config.templateMode}'`)
if (config.enableHandlers && config.handlerName) {
lines.push(` notify: ${config.handlerName}`)
}
lines.push(``)
}
// Shell 命令
if (config.taskShell) {
taskNum++
lines.push(` - name: Execute shell command`)
lines.push(` ansible.builtin.shell:`)
lines.push(` cmd: ${config.shellCommand}`)
lines.push(` changed_when: true`)
lines.push(``)
}
// 服务管理
if (config.taskManageService) {
taskNum++
lines.push(` - name: Manage service ${config.serviceName}`)
lines.push(` ansible.builtin.service:`)
lines.push(` name: ${config.serviceName}`)
lines.push(` state: ${config.serviceState}`)
lines.push(` enabled: ${config.serviceEnabled ? 'true' : 'false'}`)
lines.push(``)
}
// 处理器
if (config.enableHandlers && config.handlerName) {
lines.push(` handlers:`)
lines.push(` - name: ${config.handlerName}`)
lines.push(` ansible.builtin.service:`)
lines.push(` name: ${config.handlerService}`)
lines.push(` state: restarted`)
}
return lines.join('\n')
}
+284
View File
@@ -0,0 +1,284 @@
export const ansibleSchema = {
id: 'ansible',
name: 'Ansible',
icon: 'Files',
category: '自动化运维',
description: '自动化配置管理与应用部署工具',
format: 'cfg',
fileName: 'ansible.cfg',
groups: [
{
title: '基础配置',
fields: [
{
key: 'inventory',
label: 'Inventory 文件路径',
type: 'text',
default: '/etc/ansible/hosts',
tip: '主机清单文件路径',
},
{
key: 'remoteUser',
label: '远程用户',
type: 'text',
placeholder: 'root',
default: 'root',
},
{
key: 'hostKeyChecking',
label: 'SSH 主机密钥检查',
type: 'switch',
default: false,
tip: '首次连接是否检查主机密钥,测试环境建议关闭',
},
{
key: 'retryFilesEnabled',
label: '启用重试文件',
type: 'switch',
default: false,
tip: '失败时生成 .retry 文件',
},
],
},
{
title: 'SSH 连接',
fields: [
{
key: 'privateKeyFile',
label: 'SSH 私钥路径',
type: 'text',
placeholder: '~/.ssh/id_rsa',
default: '~/.ssh/id_rsa',
},
{
key: 'sshPort',
label: 'SSH 默认端口',
type: 'number',
min: 1,
max: 65535,
default: 22,
},
{
key: 'timeout',
label: '连接超时 (秒)',
type: 'number',
min: 5,
max: 300,
default: 30,
},
{
key: 'pipelining',
label: '开启 Pipelining',
type: 'switch',
default: true,
tip: '减少 SSH 连接次数,提升执行效率',
},
{
key: 'sshArgs',
label: 'SSH 额外参数',
type: 'text',
placeholder: '-o ControlMaster=auto -o ControlPersist=60s',
default: '-o ControlMaster=auto -o ControlPersist=60s',
tip: '控制 SSH 连接复用',
},
],
},
{
title: '权限提升 (Become)',
fields: [
{
key: 'become',
label: '默认开启提权',
type: 'switch',
default: false,
tip: '是否默认使用 sudo 提权',
},
{
key: 'becomeMethod',
label: '提权方式',
type: 'select',
options: [
{ label: 'sudo', value: 'sudo' },
{ label: 'su', value: 'su' },
{ label: 'pbrun', value: 'pbrun' },
{ label: 'pfexec', value: 'pfexec' },
],
default: 'sudo',
dependsOn: { key: 'become', value: true },
},
{
key: 'becomeUser',
label: '提权目标用户',
type: 'text',
default: 'root',
dependsOn: { key: 'become', value: true },
},
{
key: 'becomeAskPass',
label: '询问提权密码',
type: 'switch',
default: false,
dependsOn: { key: 'become', value: true },
},
],
},
{
title: '执行控制',
fields: [
{
key: 'forks',
label: '并发进程数 (forks)',
type: 'number',
min: 1,
max: 200,
default: 20,
tip: '同时操作的主机数量',
},
{
key: 'pollInterval',
label: '轮询间隔 (秒)',
type: 'number',
min: 1,
max: 60,
default: 15,
},
{
key: 'timeoutTask',
label: '任务超时 (秒)',
type: 'number',
min: 10,
max: 3600,
default: 300,
},
],
},
{
title: '日志与输出',
fields: [
{
key: 'logPath',
label: '日志文件路径',
type: 'text',
placeholder: '/var/log/ansible.log',
default: '',
tip: '留空表示不记录到文件',
},
{
key: 'stdoutCallback',
label: '输出回调插件',
type: 'select',
options: [
{ label: 'default - 默认格式', value: 'default' },
{ label: 'yaml - YAML 格式 (推荐)', value: 'yaml' },
{ label: 'json - JSON 格式', value: 'json' },
{ label: 'minimal - 最小化输出', value: 'minimal' },
{ label: 'dense - 密集输出', value: 'dense' },
],
default: 'yaml',
},
{
key: 'displaySkippedHosts',
label: '显示跳过的主机',
type: 'switch',
default: false,
},
{
key: 'displayOkHosts',
label: '显示成功的主机',
type: 'switch',
default: true,
},
],
},
{
title: '事实收集',
fields: [
{
key: 'gathering',
label: '事实收集策略',
type: 'select',
options: [
{ label: 'smart - 智能缓存 (推荐)', value: 'smart' },
{ label: 'implicit - 每次收集', value: 'implicit' },
{ label: 'explicit - 仅显式收集', value: 'explicit' },
],
default: 'smart',
},
{
key: 'factCaching',
label: '事实缓存方式',
type: 'select',
options: [
{ label: 'memory - 不缓存 (默认)', value: 'memory' },
{ label: 'jsonfile - JSON 文件缓存', value: 'jsonfile' },
{ label: 'redis - Redis 缓存', value: 'redis' },
],
default: 'memory',
},
{
key: 'factCachingConnection',
label: '缓存路径/连接',
type: 'text',
placeholder: '/tmp/ansible_facts_cache',
default: '/tmp/ansible_facts_cache',
dependsOn: { key: 'factCaching', value: 'jsonfile' },
},
],
},
],
}
export function generateAnsibleCfg(config) {
const lines = []
lines.push(`# Ansible 配置文件 - 由 ConfTemplate 生成`)
lines.push(`# 生成时间: ${new Date().toLocaleString('zh-CN')}`)
lines.push(``)
lines.push(`[defaults]`)
lines.push(`inventory = ${config.inventory}`)
lines.push(`remote_user = ${config.remoteUser}`)
lines.push(`host_key_checking = ${config.hostKeyChecking ? 'True' : 'False'}`)
lines.push(`retry_files_enabled = ${config.retryFilesEnabled ? 'True' : 'False'}`)
lines.push(`forks = ${config.forks}`)
lines.push(`poll_interval = ${config.pollInterval}`)
lines.push(`timeout = ${config.timeoutTask}`)
lines.push(`stdout_callback = ${config.stdoutCallback}`)
lines.push(`display_skipped_hosts = ${config.displaySkippedHosts ? 'True' : 'False'}`)
lines.push(`display_ok_hosts = ${config.displayOkHosts ? 'True' : 'False'}`)
lines.push(`gathering = ${config.gathering}`)
if (config.factCaching !== 'memory') {
lines.push(`fact_caching = ${config.factCaching}`)
lines.push(`fact_caching_connection = ${config.factCachingConnection}`)
lines.push(`fact_caching_timeout = 86400`)
}
if (config.logPath) {
lines.push(`log_path = ${config.logPath}`)
}
lines.push(``)
lines.push(`[ssh_connection]`)
lines.push(`ssh_args = ${config.sshArgs}`)
lines.push(`pipelining = ${config.pipelining ? 'True' : 'False'}`)
lines.push(`control_path = /tmp/ansible-%%h-%%r`)
lines.push(`timeout = ${config.timeout}`)
if (config.privateKeyFile) {
lines.push(`private_key_file = ${config.privateKeyFile}`)
}
if (config.become) {
lines.push(``)
lines.push(`[privilege_escalation]`)
lines.push(`become = True`)
lines.push(`become_method = ${config.becomeMethod}`)
lines.push(`become_user = ${config.becomeUser}`)
lines.push(`become_ask_pass = ${config.becomeAskPass ? 'True' : 'False'}`)
}
lines.push(``)
lines.push(`[inventory]`)
lines.push(`enable_plugins = host_list, script, yaml, ini, auto`)
return lines.join('\n')
}
+16 -1
View File
@@ -1,23 +1,32 @@
import { nginxSchema, generateNginxConf } from './nginx'
import { redisSchema, generateRedisConf } from './redis'
import { mysqlSchema, generateMysqlConf } from './mysql'
import { mongodbSchema, generateMongodbConf } from './mongodb'
import { k8sDeploymentSchema, generateK8sDeploymentYaml } from './k8s-deployment'
import { k8sServiceSchema, generateK8sServiceYaml } from './k8s-service'
import { ansibleSchema, generateAnsibleCfg } from './ansible'
import { ansiblePlaybookSchema, generateAnsiblePlaybookYaml } from './ansible-playbook'
export const schemas = {
nginx: nginxSchema,
redis: redisSchema,
mysql: mysqlSchema,
mongodb: mongodbSchema,
'k8s-deployment': k8sDeploymentSchema,
'k8s-service': k8sServiceSchema,
ansible: ansibleSchema,
'ansible-playbook': ansiblePlaybookSchema,
}
export const generators = {
nginx: generateNginxConf,
redis: generateRedisConf,
mysql: generateMysqlConf,
mongodb: generateMongodbConf,
'k8s-deployment': generateK8sDeploymentYaml,
'k8s-service': generateK8sServiceYaml,
ansible: generateAnsibleCfg,
'ansible-playbook': generateAnsiblePlaybookYaml,
}
export const categories = [
@@ -34,13 +43,18 @@ export const categories = [
{
name: '数据库',
icon: 'Coin',
items: ['mysql'],
items: ['mysql', 'mongodb'],
},
{
name: '云原生',
icon: 'Box',
items: ['k8s-deployment', 'k8s-service'],
},
{
name: '自动化运维',
icon: 'Files',
items: ['ansible', 'ansible-playbook'],
},
]
export function getDefaultValues(schema) {
@@ -57,6 +71,7 @@ export function getLanguage(format) {
const map = {
conf: 'ini',
cnf: 'ini',
cfg: 'ini',
yaml: 'yaml',
json: 'json',
toml: 'toml',
+317
View File
@@ -0,0 +1,317 @@
export const mongodbSchema = {
id: 'mongodb',
name: 'MongoDB',
icon: 'Coin',
category: '数据库',
description: '面向文档的 NoSQL 数据库',
format: 'conf',
fileName: 'mongod.conf',
groups: [
{
title: '基础配置',
fields: [
{
key: 'port',
label: '监听端口',
type: 'number',
min: 1,
max: 65535,
default: 27017,
},
{
key: 'bindIp',
label: '绑定地址',
type: 'text',
default: '0.0.0.0',
tip: '0.0.0.0 允许所有地址连接',
},
{
key: 'dbPath',
label: '数据目录',
type: 'text',
default: '/var/lib/mongodb',
},
{
key: 'logPath',
label: '日志文件路径',
type: 'text',
default: '/var/log/mongodb/mongod.log',
},
{
key: 'fork',
label: '守护进程模式',
type: 'switch',
default: true,
},
],
},
{
title: '安全认证',
fields: [
{
key: 'auth',
label: '开启身份认证',
type: 'switch',
default: true,
tip: '生产环境必须开启',
},
{
key: 'authorization',
label: '授权模式',
type: 'select',
options: [
{ label: 'enabled - 基于角色的访问控制 (推荐)', value: 'enabled' },
{ label: 'disabled - 无访问控制', value: 'disabled' },
],
default: 'enabled',
dependsOn: { key: 'auth', value: true },
},
{
key: 'enableTls',
label: '开启 TLS/SSL',
type: 'switch',
default: false,
},
{
key: 'tlsCertFile',
label: 'TLS 证书文件',
type: 'text',
placeholder: '/etc/ssl/mongodb.pem',
default: '/etc/ssl/mongodb.pem',
dependsOn: { key: 'enableTls', value: true },
},
{
key: 'tlsKeyFile',
label: 'TLS 私钥文件',
type: 'text',
placeholder: '/etc/ssl/mongodb-key.pem',
default: '/etc/ssl/mongodb-key.pem',
dependsOn: { key: 'enableTls', value: true },
},
],
},
{
title: '存储引擎',
fields: [
{
key: 'engine',
label: '存储引擎',
type: 'select',
options: [
{ label: 'WiredTiger (默认,推荐)', value: 'wiredTiger' },
],
default: 'wiredTiger',
},
{
key: 'cacheSizeGB',
label: 'WiredTiger 缓存大小 (GB)',
type: 'select',
options: [
{ label: '自动 (物理内存的 50%)', value: '' },
{ label: '1 GB', value: '1' },
{ label: '2 GB', value: '2' },
{ label: '4 GB', value: '4' },
{ label: '8 GB', value: '8' },
{ label: '16 GB', value: '16' },
],
default: '',
tip: '默认为 (物理内存 - 1GB) 的 50%',
},
{
key: 'journalEnabled',
label: '开启 Journal 日志',
type: 'switch',
default: true,
tip: '保证数据持久性,单节点必须开启',
},
{
key: 'directoryPerDb',
label: '每个数据库独立目录',
type: 'switch',
default: false,
},
],
},
{
title: '网络与连接',
fields: [
{
key: 'maxConns',
label: '最大连接数',
type: 'number',
min: 10,
max: 65536,
default: 65536,
},
{
key: 'ipv6',
label: '启用 IPv6',
type: 'switch',
default: false,
},
{
key: 'httpInterface',
label: '开启 HTTP 接口',
type: 'switch',
default: false,
tip: '生产环境建议关闭',
},
],
},
{
title: '操作日志 (Oplog)',
fields: [
{
key: 'oplogSizeMB',
label: 'Oplog 大小 (MB)',
type: 'number',
min: 0,
max: 102400,
step: 512,
default: 0,
tip: '0 表示使用默认值(磁盘的 5%)',
},
{
key: 'replSetName',
label: '副本集名称',
type: 'text',
placeholder: '留空表示不启用副本集',
default: '',
tip: '设置后启用副本集模式',
},
],
},
{
title: '性能调优',
fields: [
{
key: 'wiredTigerCollectionBlockCompressor',
label: '压缩算法',
type: 'select',
options: [
{ label: 'snappy (默认,平衡)', value: 'snappy' },
{ label: 'zlib (高压缩率)', value: 'zlib' },
{ label: 'zstd (最佳压缩)', value: 'zstd' },
{ label: 'none (不压缩)', value: 'none' },
],
default: 'snappy',
},
{
key: 'profileLevel',
label: 'Profiling 级别',
type: 'select',
options: [
{ label: '0 - 关闭 (推荐生产)', value: '0' },
{ label: '1 - 慢操作', value: '1' },
{ label: '2 - 所有操作', value: '2' },
],
default: '0',
tip: '性能分析,调试时开启',
},
{
key: 'slowOpThresholdMs',
label: '慢操作阈值 (毫秒)',
type: 'number',
min: 0,
max: 60000,
default: 100,
dependsOn: { key: 'profileLevel', valueNotIn: ['0'] },
},
],
},
],
}
export function generateMongodbConf(config) {
const lines = []
lines.push(`# MongoDB 配置文件 - 由 ConfTemplate 生成`)
lines.push(`# 生成时间: ${new Date().toLocaleString('zh-CN')}`)
lines.push(``)
lines.push(`# ======================== 系统日志 ========================`)
lines.push(`systemLog:`)
lines.push(` destination: file`)
lines.push(` path: ${config.logPath}`)
lines.push(` logAppend: true`)
lines.push(``)
lines.push(`# ======================== 存储 ========================`)
lines.push(`storage:`)
lines.push(` dbPath: ${config.dbPath}`)
lines.push(` engine: ${config.engine}`)
lines.push(` directoryPerDB: ${config.directoryPerDb}`)
if (config.journalEnabled) {
lines.push(` journal:`)
lines.push(` enabled: true`)
}
if (config.cacheSizeGB) {
lines.push(` wiredTiger:`)
lines.push(` engineConfig:`)
lines.push(` cacheSizeGB: ${config.cacheSizeGB}`)
lines.push(` collectionConfig:`)
lines.push(` blockCompressor: ${config.wiredTigerCollectionBlockCompressor}`)
} else {
lines.push(` wiredTiger:`)
lines.push(` collectionConfig:`)
lines.push(` blockCompressor: ${config.wiredTigerCollectionBlockCompressor}`)
}
lines.push(``)
lines.push(`# ======================== 网络 ========================`)
lines.push(`net:`)
lines.push(` port: ${config.port}`)
lines.push(` bindIp: ${config.bindIp}`)
lines.push(` maxIncomingConnections: ${config.maxConns}`)
if (config.ipv6) {
lines.push(` ipv6: true`)
}
if (config.httpInterface) {
lines.push(` http:`)
lines.push(` enabled: true`)
}
if (config.enableTls) {
lines.push(` tls:`)
lines.push(` mode: requireTLS`)
lines.push(` certificateKeyFile: ${config.tlsCertFile}`)
}
lines.push(``)
lines.push(`# ======================== 安全 ========================`)
lines.push(`security:`)
if (config.auth) {
lines.push(` authorization: ${config.authorization}`)
} else {
lines.push(` authorization: disabled`)
}
if (config.replSetName) {
lines.push(``)
lines.push(`# ======================== 副本集 ========================`)
lines.push(`replication:`)
lines.push(` replSetName: ${config.replSetName}`)
if (config.oplogSizeMB > 0) {
lines.push(` oplogSizeMB: ${config.oplogSizeMB}`)
}
}
if (config.profileLevel !== '0') {
lines.push(``)
lines.push(`# ======================== 操作日志 ========================`)
lines.push(`operationProfiling:`)
lines.push(` mode: ${parseInt(config.profileLevel) === 1 ? 'slowOp' : 'all'}`)
lines.push(` slowOpThresholdMs: ${config.slowOpThresholdMs}`)
}
lines.push(``)
lines.push(`# ======================== 进程管理 ========================`)
lines.push(`processManagement:`)
lines.push(` fork: ${config.fork}`)
lines.push(` pidFilePath: /var/run/mongodb/mongod.pid`)
lines.push(` timeZoneInfo: /usr/share/zoneinfo`)
return lines.join('\n')
}