Compare commits

..
599 Commits
Author SHA1 Message Date
zhengkunwang223 11ae05163c fix: 解决旧版本安装的应用升级之后状态异常的问题 (#1327) 2023-06-09 15:40:11 +00:00
wangdan-fit2cloud 0275716ff5 feat: 优化页面兼容移动端问题 (#1320)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-06-09 15:38:15 +00:00
ssongliu e9bdca5279 fix: 解决终端全屏及缩放的菜单显示问题 (#1316) 2023-06-09 08:56:11 +00:00
ssongliu cd84116a03 fix: 解决终端意外退出全屏导致菜单无法显示的问题 (#1314) 2023-06-09 08:02:12 +00:00
wangdan-fit2cloud 457effae85 fix: 终端全屏问题 (#1313)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-06-09 07:52:10 +00:00
zhengkunwang223 9361c358f1 style: 修改安装应用提示语句 (#1308) 2023-06-09 03:48:11 +00:00
ssongliu 39f952e460 fix: 优化 ssh 登录日志查询速度 (#1307) 2023-06-09 03:44:12 +00:00
ssongliu 7c600a357c fix: 解决应用备份或升级失败的问题 (#1306) 2023-06-09 03:42:11 +00:00
吴小白 8f036a0c3d feat: 上传文件到 OSS (#1304) 2023-06-09 10:47:09 +08:00
ssongliu 1184ae2b52 fix: 容器日志切割样式修改 (#1303) 2023-06-09 02:30:11 +00:00
zhengkunwang223 de7ef19034 fix: 解决系统启动时同步应用导致的报错 (#1301) 2023-06-08 15:20:11 +00:00
ssongliu e91b7caf4f fix: 解决 mysql 日志清空错误的问题 (#1298) 2023-06-08 13:50:11 +00:00
zhengkunwang223 033b3c10c0 feat: 应用详情适配夜间模式 (#1297) 2023-06-08 11:00:11 +00:00
ssongliu 97774c88d5 fix: 解决 sftp 上传大文件失败的问题 (#1294) 2023-06-08 10:58:15 +00:00
zhengkunwang223 95e1c73ced feat: 删除无用的文件 (#1289) 2023-06-08 03:36:10 +00:00
zhengkunwang223 d2a067db77 feat: 修改前端打包方式 (#1288) 2023-06-08 03:14:10 +00:00
ssongliu 586dee9e70 fix: 解决计划任务报告未显示执行周期的问题 (#1287) 2023-06-08 03:12:15 +00:00
ssongliu 6a717b2517 fix: 兼容 mysql 5.7.42 (#1286) 2023-06-08 03:00:12 +00:00
zhengkunwang223 203af988fa fix: 修复启动 panic 问题 (#1285) 2023-06-08 02:58:10 +00:00
zhengkunwang223 911166152a fix: 解决 MYSQL 不显示升级的问题 (#1283) 2023-06-07 11:09:23 +00:00
ssongliu b3ecddb20f feat: 计划任务创建增加第三方备份账号跳转 (#1282) 2023-06-07 10:23:24 +00:00
zhengkunwang223 a41d4e55aa feat: 删除域名的时候同步删除 ipv6 的端口监听 (#1281) 2023-06-07 10:21:24 +00:00
zhengkunwang223 c7a3ef7d72 style: 修改 logo 路径 (#1279) 2023-06-07 08:31:25 +00:00
zhengkunwang223 b7495a63e9 fix: 解决网站导入自签证书报错的问题 (#1278) 2023-06-07 08:09:25 +00:00
ssongliu 6b3093aa09 fix: 计划任务执行周期校验修改 (#1277) 2023-06-07 07:59:28 +00:00
zhengkunwang223 8f8369c989 feat: 创建 DNS 账号禁止输入空格 (#1276) 2023-06-07 07:03:25 +00:00
zhengkunwang223 f79293be69 feat: 修改一些提示信息 (#1274) 2023-06-07 06:55:24 +00:00
ssongliu 4631da2212 feat: 版本更新检查错误信息优化 (#1273) 2023-06-07 06:53:24 +00:00
ssongliu e2a7c51de0 fix: 备份适配 redis 版本 (#1271) 2023-06-07 02:49:22 +00:00
ssongliu 633e26b1de fix: 工作目录切换逻辑修改 (#1269) 2023-06-06 10:29:22 +00:00
zhengkunwang223 08992f83b5 fix: 解决导入 cloudflare 证书域名显示错误的问题 (#1268)
Refs https://github.com/1Panel-dev/1Panel/issues/1184
2023-06-06 08:29:22 +00:00
ssongliu 921e886e71 fix: 应用默认配置路径修改 (#1267) 2023-06-06 08:03:22 +00:00
ssongliu 9fc4cad80e fix: 操作日志内容修改 (#1266) 2023-06-06 03:33:21 +00:00
ssongliu 4fdb81642a fix: 修改 ssh 登录日志排序规则 (#1264) 2023-06-06 03:31:26 +00:00
dependabot[bot] 056c771d2e build(deps-dev): bump vite from 2.9.15 to 2.9.16 in /frontend (#1265)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 2.9.15 to 2.9.16.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v2.9.16/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v2.9.16/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-06 11:25:17 +08:00
ssongliu 84183bdfeb fix: 容器详情抽屉高度自适应 (#1262) 2023-06-05 10:37:21 +00:00
ssongliu 4e786fee31 fix: 日志拦截解压方式判断修改 (#1260) 2023-06-05 10:35:25 +00:00
zhengkunwang223 9f4e5050dd feat: acme 账号增加提示信息 (#1259) 2023-06-05 10:33:29 +00:00
ssongliu bb49a610a2 fix: 计划任务排除规则改为换行切割 (#1255) 2023-06-05 10:31:26 +00:00
&nbsp 5e3e580f51 perf: 浏览器失去焦点停止查询、节省开销 (#1256) 2023-06-05 17:52:53 +08:00
ssongliu 75fa498a7c fix: 恢复密码过期跳转 (#1252) 2023-06-05 07:01:21 +00:00
zhengkunwang223 05e5f06cf1 feat: 修改应用容器名称增加校验 (#1251) 2023-06-05 06:59:26 +00:00
ssongliu 3a17f4f29f fix: 面板设置提示信息修改 (#1249) 2023-06-05 05:47:21 +00:00
zhengkunwang223 5e7524e4f8 fix: 解决本地应用升级失败的问题 (#1248) 2023-06-05 05:45:26 +00:00
zhengkunwang223 b2e17d4c42 feat: 防盗链响应增加状态码判断 (#1242) 2023-06-03 05:21:20 +00:00
dependabot[bot] b88303d36a build(deps): bump @antfu/utils, unplugin-auto-import and unplugin-vue-components (#1243)
Bumps [@antfu/utils](https://github.com/antfu/utils) to 0.7.4 and updates ancestor dependencies [@antfu/utils](https://github.com/antfu/utils), [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import) and [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components). These dependencies need to be updated together.


Updates `@antfu/utils` from 0.4.0 to 0.7.4
- [Release notes](https://github.com/antfu/utils/releases)
- [Commits](https://github.com/antfu/utils/compare/v0.4.0...v0.7.4)

Updates `unplugin-auto-import` from 0.6.9 to 0.16.4
- [Release notes](https://github.com/antfu/unplugin-auto-import/releases)
- [Commits](https://github.com/antfu/unplugin-auto-import/compare/v0.6.9...v0.16.4)

Updates `unplugin-vue-components` from 0.17.21 to 0.25.0
- [Release notes](https://github.com/antfu/unplugin-vue-components/releases)
- [Commits](https://github.com/antfu/unplugin-vue-components/compare/v0.17.21...v0.25.0)

---
updated-dependencies:
- dependency-name: "@antfu/utils"
  dependency-type: indirect
- dependency-name: unplugin-auto-import
  dependency-type: direct:development
- dependency-name: unplugin-vue-components
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-03 13:20:54 +08:00
zhengkunwang223 5a5b0e3a1b fix: 解决同步应用之后旧版本被删除的问题 (#1241) 2023-06-03 05:19:23 +00:00
ssongliu e504e55a34 feat: 容器日志切割增加回显 (#1239) 2023-06-02 09:49:19 +00:00
zhengkunwang223 b6758ff92d feat: 安装应用自动填写名称 (#1238) 2023-06-02 09:47:23 +00:00
zhengkunwang223 957499e4d7 fix: 解决应用内存限制回显失败的问题 (#1237) 2023-06-02 09:45:24 +00:00
wanghe-fit2cloud 3773d64aa7 chore: 删除 docker.sh 脚本引用 2023-06-02 17:43:45 +08:00
ssongliu d89f823bef fix: 版本升级适配 armv7 (#1236) 2023-06-02 09:03:20 +00:00
zhengkunwang223 a8b7c3d8c5 feat: 增加一些提示信息 (#1234) 2023-06-02 06:31:19 +00:00
zhengkunwang223 9a45ce3110 feat: 限制已废弃应用升级和备份 (#1233) 2023-06-02 06:25:19 +00:00
zhengkunwang223 3ad3b180af feat: 增加应用商店定时同步 (#1231) 2023-06-02 06:23:24 +00:00
ssongliu 6919ce7b5c fix: 概览页磁盘大小自适应 (#1232) 2023-06-02 06:19:19 +00:00
zhengkunwang223 e7a9c3814b fix: 解决打开防盗链报错的问题 (#1230) 2023-06-02 05:53:25 +00:00
ssongliu 488eb319a1 fix: 优化监控页空数据显示 (#1229) 2023-06-02 03:50:27 +00:00
zhengkunwang223 4f650cad9d fix: 解决PHP上传限制清空之后可以上传的问题 (#1227) 2023-06-02 03:12:28 +00:00
dependabot[bot] ce9c2e6d3c build(deps): bump github.com/gin-gonic/gin from 1.9.0 to 1.9.1 (#1228)
Bumps [github.com/gin-gonic/gin](https://github.com/gin-gonic/gin) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/gin-gonic/gin/releases)
- [Changelog](https://github.com/gin-gonic/gin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gin-gonic/gin/compare/v1.9.0...v1.9.1)

---
updated-dependencies:
- dependency-name: github.com/gin-gonic/gin
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-02 11:10:40 +08:00
zhengkunwang223 90a5e741fd fix: 解决本地应用升级失败的问题 (#1226) 2023-06-02 02:26:27 +00:00
ssongliu bfedd02d1d fix: 解决容器配置失败的问题 (#1225) 2023-06-02 02:24:29 +00:00
ssongliu 0187d2f5c1 fix: ssh 登录日志时区修改 (#1223) 2023-06-01 14:04:57 +00:00
ssongliu 7d968348f5 fix: ssh 登录日志归属地获取方式修改 (#1221) 2023-06-01 10:27:53 +00:00
zhengkunwang223 317017a2b4 fix: 解决应用升级失败的问题 (#1220) 2023-06-01 09:05:14 +00:00
ssongliu 35ca52620c feat: 计划任务报告页增加计划任务名称显示 (#1219) 2023-06-01 09:03:21 +00:00
ssongliu 01ed60fcb7 fix: 解决编辑已停止计划任务导致任务执行的问题 (#1218) 2023-06-01 07:05:14 +00:00
zhengkunwang223 80599a3576 feat: 删除 AppStoreVersion 参数 (#1217) 2023-06-01 06:47:13 +00:00
zhengkunwang223 d40b2734a9 feat: 减少 badger 的内存占用 (#1216) 2023-06-01 06:45:18 +00:00
zhengkunwang223 6abd313bd2 fix: 解决解压 GBK 格式的 zip 文件中文乱码的问题 (#1214)
Refs https://github.com/1Panel-dev/1Panel/issues/1209
2023-06-01 05:51:11 +00:00
wanghe 88f573e2a6 Update .goreleaser.yaml 2023-06-01 10:58:03 +08:00
ssongliu eb55e16465 fix: 拦截中间件数据改为实时获取 (#1213) 2023-06-01 02:38:11 +00:00
ssongliu bb48964cca fix: 优化未启用安全入口跳转逻辑 (#1210) 2023-06-01 02:14:11 +00:00
zhengkunwang223 cbdf1ad7b7 fix: 解决应用无法升级的问题 (#1208) 2023-05-31 15:27:03 +00:00
zhengkunwang223 df77ac4318 style: 网站设置页面手机端适配 (#1207) 2023-05-31 15:25:07 +00:00
zhengkunwang223 b3caa343d2 feat: 编辑应用增加编辑 docker-compose.yml (#1206) 2023-05-31 07:59:00 +00:00
wanghe-fit2cloud 49f4f316f8 refactor: goreleaser 增加 dodocker.sh 2023-05-31 15:44:18 +08:00
zhengkunwang223 2207711400 feat: 编辑应用 cpu 和内存限制增加校验 (#1205) 2023-05-31 07:41:02 +00:00
zhengkunwang223 763f450f43 feat: 创建应用容器名称增加校验 (#1204) 2023-05-31 07:39:04 +00:00
zhengkunwang223 0fa11213bb feat: 本地应用同步增加日志 (#1203) 2023-05-31 06:51:01 +00:00
wangdan-fit2cloud c743775a1e feat: 移动端样式优化 (#1202)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-31 06:05:01 +00:00
ssongliu b854aa3bfe fix: 默认时区获取方式修改 (#1200) 2023-05-31 06:03:04 +00:00
zhengkunwang223 8dfba82a70 fix: 解决备份文件过大导致下载超时问题 (#1199)
Refs https://github.com/1Panel-dev/1Panel/issues/1191
2023-05-31 06:01:01 +00:00
zhengkunwang223 824051e89e feat: 限制删除运行环境中使用的应用版本 (#1197) 2023-05-30 13:54:58 +00:00
wanghe ab45cc27d5 Update .goreleaser.yaml (#1196)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [x] Made sure tests are passing and test coverage is added if needed.
- [x] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [x] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-30 08:52:57 +00:00
zhengkunwang223 627e467fdf fix: 解决申请证书 多个域名下显示异常的问题 (#1195)
Refs https://github.com/1Panel-dev/1Panel/issues/996
2023-05-30 08:48:58 +00:00
zhengkunwang223 ca3b4b02e0 fix: 解决网站的默认文档不能设置为子目录的文件的问题 (#1194)
Refs https://github.com/1Panel-dev/1Panel/issues/720
2023-05-30 08:24:57 +00:00
ssongliu 34ac685e65 fix: 面板设置输入增加校验及提示信息 (#1193) 2023-05-30 07:46:58 +00:00
ssongliu 7a66e71215 fix: 统一修改代码拼写错误 (#1192) 2023-05-30 07:30:57 +00:00
zhengkunwang223 1e96a1ae84 fix: 解决 halo 用户名设置为大写之后导致安装失败的问题 (#1190)
Refs https://github.com/1Panel-dev/1Panel/issues/1161
2023-05-30 07:04:57 +00:00
zhengkunwang223 ce0342e235 fix: 解决 nexus 安装失败的问题 (#1189)
Refs https://github.com/1Panel-dev/1Panel/issues/1179
2023-05-30 06:46:57 +00:00
zhengkunwang223 a48ea497b0 feat: 网站增加 IPV6 监听设置 (#1188) 2023-05-30 06:22:57 +00:00
ssongliu 4b3c9419f3 fix: 镜像仓库校验判断修改 (#1187) 2023-05-30 05:56:57 +00:00
zhengkunwang223 f51b09dc40 style: 修改日志审计-网站日志样式 (#1185) 2023-05-30 03:02:56 +00:00
zhengkunwang223 800f9e2d38 feat: 优化大文件下载 (#1183)
Refs https://github.com/1Panel-dev/1Panel/issues/1165
2023-05-29 16:00:56 +00:00
ssongliu b5093e4d93 fix: 补全缺失的组件引用 (#1181) 2023-05-29 10:10:56 +00:00
ssongliu 10684f9aac fix: 解决浏览器关闭后重新打开不需要登录验证的问题 (#1180) 2023-05-29 09:32:55 +00:00
ssongliu 7c0327c1b8 fix: 修复概览页数据加载失败的问题 (#1178) 2023-05-29 07:10:40 +00:00
ssongliu 9f5a03419e fix: 面板设置界面样式统一 (#1177) 2023-05-29 15:08:54 +08:00
ssongliu ec843f2396 feat: docker 配置界面样式统一 (#1173) 2023-05-29 11:24:28 +08:00
zhengkunwang223 2d6925ac4f feat: 文件列表增加批量上传功能 (#1168) 2023-05-27 23:15:30 +08:00
zhengkunwang223 7cbaa4f63d fix: 解决高级设置CPU和内存限制删除之后安装报错的问题 (#1167) 2023-05-27 23:13:47 +08:00
ssongliu ebb9e7a2a0 feat: 概览界面针对磁盘显示优化 2023-05-26 16:49:03 +08:00
吴小白 84e44127b3 feat: 更新 npm 依赖 (#1154) 2023-05-26 13:44:27 +08:00
吴小白 0b66bb5eff perf: 更新 arm 文件名规则 (#1153) 2023-05-26 13:43:58 +08:00
zhengkunwang223 e70ec0e978 feat: 网站增加防盗链设置 (#1151)
Refs https://github.com/1Panel-dev/1Panel/issues/1149
2023-05-26 02:40:21 +00:00
吴小白 d62f566bb3 build(deps): bump github.com/shirou/gopsutil/v3 from v3.23.1 to v3.23.4 (#1152) 2023-05-26 10:40:17 +08:00
吴小白 4e1c3be03a perf: 默认构建 armv7 (#1148) 2023-05-25 21:42:31 +08:00
ssongliu 792e96e95f feat: 优化监控界面无数据时显示样式 (#1147) 2023-05-25 10:50:18 +00:00
ssongliu c1acd8f5f0 feat: 监控增加数据采集间隔设置 (#1146) 2023-05-25 10:02:17 +00:00
吴小白 d64e1713fb fix: 修正 actions 构建错误 (#1145) 2023-05-25 16:46:39 +08:00
吴小白 3e6fefe1b7 feat: 支持更多 linux 架构 (#1144) 2023-05-25 15:48:00 +08:00
ssongliu 48e3ef3e73 fix: 修改计划任务报告样式 (#1142) 2023-05-25 07:12:16 +00:00
zhengkunwang223 c76c24e102 feat: 适配 Linux 多架构打包 (#1143) 2023-05-25 07:06:16 +00:00
zhengkunwang223 4b25dafb92 feat: 修改同步应用列表方式 (#1141) 2023-05-25 06:58:16 +00:00
ssongliu c8237d59be fix: 计划任务删除弹窗优化 (#1140) 2023-05-25 02:48:10 +00:00
wangdan-fit2cloud c2629e3945 feat: 调整网站设置页面 (#1139)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-25 02:22:10 +00:00
吴小白 b5864ca3a3 修复: 修正 goreleaser 构建失败 (#1136) 2023-05-24 21:40:51 +08:00
zhengkunwang223 b84c983727 feat: 网站日志增加清空功能 (#1134) 2023-05-24 13:40:35 +00:00
zhengkunwang223 aa3e8783ae feat: PHP 网站增加配置上传限制功能 (#1133) 2023-05-24 10:38:50 +00:00
ssongliu f65f0d86aa feat: 计划任务增加每隔 n 秒执行 (#1132) 2023-05-24 10:36:41 +00:00
zhengkunwang223 93b03c7212 style: 删除无用代码 2023-05-24 17:26:14 +08:00
ssongliu c96b999b2c feat: 计划任务增加时间同步选项 (#1128) 2023-05-24 09:25:35 +00:00
吴小白 da155fadf2 feat: 使用 goreleaser 构建包 (#829)
* feat: 使用 goreleaser 构建包

Signed-off-by: 吴小白 <296015668@qq.com>
2023-05-24 16:46:28 +08:00
ssongliu c69a1c8ec2 fix: 计划任务脚本执行设置执行路径 (#1127) 2023-05-24 08:39:36 +00:00
wangdan-fit2cloud 83ac2f1ff7 feat: 兼容移动端 (#1126)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-24 08:36:54 +00:00
zhengkunwang223 f77972fa38 feat: PHP 网站增加禁用函数设置 (#1125)
Refs https://github.com/1Panel-dev/1Panel/issues/663
2023-05-24 08:31:18 +00:00
ssongliu d7c08295f8 fix: 解决容器进程异常退出的问题 (#1124) 2023-05-24 07:45:12 +00:00
ssongliu be6b7157f4 fix: 系统时间同步样式修改 (#1123) 2023-05-24 07:43:21 +00:00
zhengkunwang223 b979c2574c feat: 网站密码访问限制没有用户的情况下启用 (#1120)
Refs https://github.com/1Panel-dev/1Panel/issues/1113
2023-05-24 06:17:11 +00:00
wangdan-fit2cloud f7c76c012f feat: 应用商店兼容移动端 (#1119)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-23 13:40:03 +00:00
zhengkunwang223 13abe8cb66 feat: 网站 HTTPS 配置增加阻止 IP 访问 TLS 握手 (#1118)
Refs https://github.com/1Panel-dev/1Panel/issues/849
2023-05-23 11:02:02 +00:00
ssongliu 7596099aa1 feat: 增加容器、镜像、网络、存储卷清理功能 (#1117) 2023-05-23 11:00:06 +00:00
zhengkunwang223 626782102a feat: 计划任务增加网站日志切割 (#1116)
Refs https://github.com/1Panel-dev/1Panel/issues/495
2023-05-23 10:54:05 +00:00
zhengkunwang223 3e068a0020 feat: 日志审计增加网站日志 (#1114) 2023-05-23 07:47:43 +00:00
ssongliu 09af1e9cdf fix: 解决代码合并冲突 (#1112) 2023-05-23 07:45:47 +00:00
ssongliu 5ac9298db0 feat: 增加容器日志清理功能 (#1111) 2023-05-23 07:43:51 +00:00
wangdan-fit2cloud 0d084861e0 feat: 概览兼容移动端 (#1109)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-23 05:51:43 +00:00
zhengkunwang223 c052887d58 feat: 应用商店支持多容器的本地应用 (#1108)
Refs https://github.com/1Panel-dev/1Panel/issues/635
2023-05-23 02:31:45 +00:00
zhengkunwang223 f5cd45438b feat: 应用列表增加已安装提示 (#1107)
Refs https://github.com/1Panel-dev/1Panel/issues/972
2023-05-22 13:39:42 +00:00
ssongliu a0a1cc410f feat: 日志菜单样式调整 (#1106) 2023-05-22 13:29:43 +00:00
zhengkunwang223 74cfc11a37 feat: 创建应用增加 compose 文件配置功能 (#1105)
Refs https://github.com/1Panel-dev/1Panel/issues/301
2023-05-22 11:19:40 +00:00
ssongliu 53600900f2 feat: 时间同步增加时区、同步地址自定义设置 (#1102) 2023-05-22 09:45:39 +00:00
zhengkunwang223 ce19107c95 feat: 已安装应用增加打开安装目录功能 (#1100) 2023-05-22 09:10:51 +00:00
zhengkunwang223 7c56ed7b16 feat: 取消网站 ipv6 的默认设置 (#1099) 2023-05-22 03:03:19 +00:00
ssongliu 152cc76e3f feat: 1pctl reset 命令改为多级 (#1098) 2023-05-22 03:01:47 +00:00
ssongliu 8fd4060562 feat: 实现域名绑定与授权 ip 功能 (#1089) 2023-05-19 13:47:46 +00:00
zhengkunwang223 c2f5908a9d fix: 解决首页控制台报错的问题 (#1087) 2023-05-19 09:50:12 +00:00
zhengkunwang223 57aa2aba74 fix: 解决伪静态页面光标丢失的问题 (#1086) 2023-05-19 07:53:10 +00:00
zhengkunwang223 d851aeed45 fix: 解决搜索子目录模糊查询失败的问题 (#1085)
Refs https://github.com/1Panel-dev/1Panel/issues/1049
2023-05-19 07:51:09 +00:00
zhengkunwang223 03d338d6c9 fix: 解决打开编辑文件页面确认按钮可能看不到的问题 (#1084)
Refs https://github.com/1Panel-dev/1Panel/issues/1042
2023-05-19 06:25:09 +00:00
zhengkunwang223 a74cdcc061 fix: 解决反向代理 1Panel 并启用 auth_basic 的时候无法登录的问题 (#1083)
Refs https://github.com/1Panel-dev/1Panel/issues/1082
2023-05-19 04:21:06 +00:00
xin.yang 4fca9aeb48 修复首页推荐应用处在窄窗口时显示异常的问题 2023-05-18 19:54:38 +08:00
zhengkunwang223 205e32dde8 feat: 创建运行环境逻辑修改 (#1079) 2023-05-18 11:08:20 +00:00
zhengkunwang223 d065558865 feat: 增加创建本地应用默认文件指令 (#1076) 2023-05-18 11:06:23 +00:00
ssongliu 950c6b9d08 feat: 容器增加日志切割 (#1077) 2023-05-18 10:38:19 +00:00
zhengkunwang223 d20d5946f2 feat: 优化应用升级逻辑 (#1075) 2023-05-18 08:48:19 +00:00
ssongliu 72bc99bddc fix: docker 状态判断逻辑修改 (#1073) 2023-05-18 16:46:13 +08:00
ssongliu 8c4016792b feat: 增加 ssh 相关接口文档 2023-05-18 16:45:54 +08:00
ssongliu 2975cf6d5a feat: sshd 支持重启、停止等操作,增加状态条 2023-05-18 16:45:54 +08:00
ssongliu 73d93d6104 feat: 面板设置中冗余系统日志 2023-05-18 16:45:54 +08:00
ssongliu 7452cc19e0 feat: 配置修改后重启,适配 SELinux 策略 2023-05-18 16:45:54 +08:00
ssongliu efd545882f feat: 增加 ssh 登录日志功能 2023-05-18 16:45:54 +08:00
ssongliu b19cdd9339 fix: 生成 ssh 密钥加密文件 2023-05-18 16:45:54 +08:00
ssongliu da54794aca feat: 完成 ssh 配置前端界面实现 2023-05-18 16:45:54 +08:00
zhengkunwang223 a8df6d0668 feat: 升级 distribution 版本到 v2.8.2 (#1067) 2023-05-17 15:08:09 +00:00
zhengkunwang223 1f65d2243e feat: 创建一键部署网站和运行环境增加高级设置 (#1064) 2023-05-17 13:48:09 +00:00
zhengkunwang223 36db30471c feat: 编辑应用增加高级设置 (#1062) 2023-05-17 07:46:29 +00:00
zhengkunwang223 80e22ffc82 feat: 创建应用增加高级设置 (#1060) 2023-05-17 05:46:28 +00:00
zhengkunwang223 872581fa4b feat: 修改本地应用同步逻辑 2023-05-16 17:45:19 +08:00
zhengkunwang223 aeabed70db feat: 应用商店对接远程应用服务 2023-05-16 17:45:19 +08:00
zhengkunwang223 d443103e2c style: 修改应用商店样式 2023-05-16 17:45:19 +08:00
ssongliu c1332235a0 fix: 右侧抽屉宽度调整 (#1047) 2023-05-15 02:36:47 +00:00
ssongliu 212c8634ea fix: 容器配置界面样式调整 (#1045) 2023-05-15 02:22:47 +00:00
zhengkunwang223 b966ab3e11 fix: 解决创建数据库超时问题 (#1037) 2023-05-14 01:34:31 +00:00
zhengkunwang223 25c2246782 fix: 解决默认网站开启 https 443 端口没有设置 default_server 的问题 (#1034) 2023-05-14 01:04:31 +00:00
ssongliu 2ae1db4730 fix: 解决 ssl 启用和端口修改跳转问题 (#1030) 2023-05-13 12:20:30 +00:00
ssongliu 43652b2a54 fix: 解决数据库上传备份恢复失败的问题 (#1027) 2023-05-13 07:32:28 +00:00
ssongliu 574a504ec3 fix: 增加初始化逻辑 (#1026) 2023-05-13 04:20:29 +00:00
zhengkunwang223 52a8331c78 fix: 解决网站设置 https 情况下,设置默认网站失败的问题 (#1023) 2023-05-12 15:08:28 +00:00
ssongliu afa9eecf35 fix: 补全 swagger 文档 (#1022) 2023-05-12 22:30:50 +08:00
ssongliu 46e13d754f fix: 解决计划任务未勾选同步到本地造成的备份恢复问题 (#1021) 2023-05-12 22:30:26 +08:00
zhengkunwang223 0157326d61 fix: 限制应用失败情况下启动应用 (#1020) 2023-05-12 22:30:02 +08:00
ssongliu 7d08875f95 fix: 解决数据库用户指定多个 ip 无效的问题 (#1019) 2023-05-12 17:48:31 +08:00
zhengkunwang223 bd2a49e299 fix: 解决网站设置切换到 HTTPS 控制台报错的问题 (#1016)
fix https://github.com/1Panel-dev/1Panel/issues/672
2023-05-12 07:08:23 +00:00
ssongliu 06f1d03b93 fix: 端口校验正则表达式修改 (#1009) 2023-05-12 03:36:23 +00:00
Mystery0 M 4c39955f2f fix: 获取网站日志时,先检查一下日志文件大小,超过10M时直接报错 (#1011)
#### What this PR does / why we need it?

修复网站日志文件较大时,在界面上查看日志会导致系统短时间卡住的问题

相关Issue https://github.com/1Panel-dev/1Panel/issues/495
该提交可优化这个Issue的问题

#### Summary of your change

在获取文件内容之前,通过os.Stat获取文件的信息,并对文件大小进行判断,如果过大(目前是>10MB),则抛出错误中止流程

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [x] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-12 02:54:23 +00:00
maninhill 56f92310f8 Update README.md (#1005) 2023-05-11 23:27:01 +08:00
maninhill cb47806fd6 Update README.md 2023-05-11 21:28:57 +08:00
maninhill 16ae193e9f Update README.md 2023-05-11 15:33:17 +08:00
fossabot 8770939328 Add license scan report and status
Signed off by: fossabot <badges@fossa.com>
2023-05-11 15:33:17 +08:00
ssongliu d5bff6473e fix: 解决安全入口跳转失败的问题 (#995) 2023-05-10 15:28:18 +00:00
ssongliu a1c0408aae fix: 解决安全入口情况下升级后页面无法打开的问题 (#994) 2023-05-10 15:16:48 +00:00
ssongliu ab523b6879 fix: 解决密码过期后重定向到登录页的问题 (#990) 2023-05-10 09:12:18 +00:00
zhengkunwang223 740b4c52d2 fix: 修复已安装页面 php 应用丢失的问题 (#989) 2023-05-10 08:52:16 +00:00
ssongliu dbb94942df fix: 镜像导出增加默认值 (#988) 2023-05-10 08:16:15 +00:00
zhengkunwang223 1e4ea2f8c3 feat: 文件操作增加名称显示 (#985)
resolve  https://github.com/1Panel-dev/1Panel/issues/975
2023-05-10 07:02:15 +00:00
ssongliu 8083837333 fix: 容器监控适配部分单核系统 (#984) 2023-05-10 06:48:15 +00:00
ssongliu dd89933613 fix: ntp 依赖修改 (#983) 2023-05-10 06:36:15 +00:00
ssongliu 5101dace59 fix: 优化抽屉中操作对象的名称显示 (#982) 2023-05-10 06:34:19 +00:00
zhengkunwang223 81c56a740c feat: 限制 PHP 应用升级 (#981) 2023-05-10 06:32:23 +00:00
zhengkunwang223 27cc3bcccd fix: 解决运行环境版本与已安装应用版本不一致的问题 (#980)
Closes https://github.com/1Panel-dev/1Panel/issues/978
2023-05-10 06:20:16 +00:00
ssongliu 8ddaa26a57 fix: 解决本地备份账号更新失败的问题 (#977)
Closes #966
2023-05-10 06:08:14 +00:00
ssongliu 3a848428c3 fix: 忽略概览页异常数据 (#971) 2023-05-10 02:52:14 +00:00
ssongliu 4c18f3aa1d fix: 解决验证码加载失败的问题 (#970) 2023-05-10 02:50:18 +00:00
maninhill be6278c0b7 Update README.md 2023-05-09 23:50:17 +08:00
maninhill d5e08d5db2 Update README.md 2023-05-09 23:49:24 +08:00
zhengkunwang223 2d321b4a79 feat: app.yaml 增加 username 和 password 参数 (#960) 2023-05-09 09:31:44 +00:00
zhengkunwang223 fcd764d521 feat: 应用商店同步改为异步操作 (#956) 2023-05-09 07:47:43 +00:00
ssongliu 7d4a8782d8 fix: 解决登录情况下,输入任意路由跳转到安全入口的问题 (#954) 2023-05-09 07:45:47 +00:00
zhengkunwang223 eea28e8481 feat: 升级badger版本到v4 (#951) 2023-05-09 07:23:43 +00:00
FoXiMao 71d679d426 Fix maccms rewrite configuration file error (#948)
修复maccms rewrite 配置文件错误导致登陆时提示ERR_TOO_MANY_REDIRECTS 重定向次数过多的问题

#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [x] Made sure tests are passing and test coverage is added if needed.
- [x] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-09 07:21:47 +00:00
zhengkunwang223 2b23523bec fix: 修复文件列表总共条数显示问题 (#952) 2023-05-09 07:17:47 +00:00
wangdan-fit2cloud 149c26728c fix: 夜间模式ui优化(https://github.com/1Panel-dev/1Panel/issues/938) (#953)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-05-09 07:15:46 +00:00
zhengkunwang223 8c5c2440fe fix: 解决定时任务停止网站失败的问题 (#933) 2023-05-08 09:03:41 +00:00
ssongliu f22caed20c fix: 提示信息国际化修改 (#931) 2023-05-08 08:49:41 +00:00
zhengkunwang223 ed3e7e7c26 fix: 解决停止一键部署网站失败的问题 (#930) 2023-05-08 08:39:41 +00:00
zhengkunwang223 54bc33a1a2 fix: 解决删除 Openresty 之后网站列表页面报错的问题 (#926) 2023-05-08 07:11:39 +00:00
ssongliu 900e141297 feat: 增加 iptables 设置修改提示信息 (#925) 2023-05-08 06:57:39 +00:00
zhengkunwang223 ca1eca476c feat: 解决时区获取不到导致的网站自动停止的问题 (#921) 2023-05-08 05:01:39 +00:00
ssongliu c4d2593a42 feat: 更新 ip 地址库 (#922) 2023-05-08 04:55:39 +00:00
zhengkunwang223 932811c167 feat: 文件搜索框样式调整 (#919) 2023-05-08 03:23:37 +00:00
zhengkunwang223 95ad101a08 fix: 解决同名反向代理失败导致文件被删除的问题 (#910) 2023-05-06 11:13:34 +00:00
zhengkunwang223 a0c329019f fix: 解决应用列表页面搜索之后点击安装没响应的问题 (#909) 2023-05-06 09:57:34 +00:00
ssongliu 8a92913230 fix: 解决计划任务部分脚本执行没有输出的问题 (#908) 2023-05-06 09:23:34 +00:00
ssongliu 5a8deddc63 feat: ssl 设置增加重启提示信息 (#905) 2023-05-06 08:51:34 +00:00
ssongliu 2a1e60da44 fix: 创建编排时,默认显示编辑模式 (#904) 2023-05-06 08:49:38 +00:00
ssongliu 6ca3deeac1 fix: 优化编排删除提示信息 (#902) 2023-05-06 08:09:33 +00:00
zhengkunwang223 1b2edbb79a feat: 非静态网站和运行环境网站隐藏网站目录权限设置 (#901) 2023-05-06 08:07:38 +00:00
zhengkunwang223 49c9929a53 feat: 网站域名跳转增加端口 (#900) 2023-05-06 07:49:33 +00:00
zhengkunwang223 8ce73a38dd feat: 网站新增域名,自动放开相应端口 (#899) 2023-05-06 07:27:34 +00:00
zhengkunwang223 28ebf7a0cc fix: 解决文件搜索不存在的资源后,点击下面存在的目录也会提示资源不存在的问题 (#896) 2023-05-06 06:49:33 +00:00
ssongliu 4f168656fc fix: mfa 启用时,增加时间同步提示信息 (#895) 2023-05-06 06:27:33 +00:00
zhengkunwang223 7f1f758e60 feat: 网站列表增加网站目录跳转功能 (#892) 2023-05-06 04:05:33 +00:00
maninhill f8ab71953d chore: remove console.log 2023-05-06 11:22:24 +08:00
ssongliu eb50ee1c03 fix: 数据库创建重名用户问题修改 (#887) 2023-05-06 02:15:32 +00:00
ssongliu a184cb9bc4 fix: 证书创建校验修改 (#884) 2023-05-05 10:31:30 +00:00
zhengkunwang223 0b50a10fb8 feat: 搜索子目录增加提示 (#883) 2023-05-05 09:35:30 +00:00
zhengkunwang223 9bafdc1b0b 增加安全问题联系人 (#882) 2023-05-05 09:33:34 +00:00
ssongliu 63af54353b feat: 监控设置改到【主机-监控】菜单内 (#881) 2023-05-05 09:31:31 +00:00
ssongliu b67739af13 feat: 面板设置统一改为抽屉实现 (#880) 2023-05-05 07:54:52 +00:00
zhengkunwang223 40633619ca fix: 解决解压 mac 压缩文件失败的问题 (#879) 2023-05-05 07:50:52 +00:00
zhengkunwang223 e672d1d896 fix: 解决反向代理网站停止不生效的问题 (#878) 2023-05-05 07:02:54 +00:00
zhengkunwang223 c69d162f5a fix: 修改用户名长度限制 (#877) 2023-05-05 06:42:52 +00:00
ssongliu 2fd97b1753 fix: 解决列表查询输入框刷新的问题 (#876) 2023-05-05 06:16:52 +00:00
zhengkunwang223 5f893929da fix: 解决反向代理停用无法删除的问题 (#875) 2023-05-05 06:14:56 +00:00
ssongliu 1c06b7b608 fix: 删除初始化用户界面及接口 (#874) 2023-05-05 03:56:52 +00:00
ssongliu 3ac64d65b6 fix: 修改初始化错误返回 (#873) 2023-05-05 03:40:51 +00:00
ssongliu f4f83283d3 fix: 容器创建端口校验修改 (#872) 2023-05-05 10:17:28 +07:00
zhengkunwang223 aed4a55655 feat: 升级 gin 版本到 v1.9.0 (#871) 2023-05-05 02:56:56 +00:00
ssongliu 5f55a56a9e fix: 指定 IP 输入增加提示信息 (#867) 2023-05-04 11:12:52 +00:00
ssongliu e95e79b572 fix: 限制描述长度 (#866) 2023-05-04 09:44:41 +00:00
ssongliu 15c0d0074b fix: 安全入口逻辑调整 (#863) 2023-05-04 08:40:37 +00:00
zhengkunwang223 f4716cb62f feat: 创建网站支持 ipv6 (#861) 2023-05-04 06:28:38 +00:00
ssongliu 1f2dfce7d1 fix: 初始化密码时,对密码进行加密操作 (#860) 2023-05-04 06:14:38 +00:00
ssongliu c679631440 fix: 时区问题修改 (#855) 2023-05-04 04:00:37 +00:00
zhengkunwang223 c62fd4841a feat: 增加已安装应用操作的执行时间 (#854) 2023-05-04 03:58:41 +00:00
ssongliu a073113817 fix: redis 按钮位置调整 (#856) 2023-05-04 03:56:37 +00:00
ssongliu 09d462b829 feat: 验证码输入判断逻辑修改 (#842) 2023-04-30 15:58:24 +00:00
ssongliu 379b171f0a fix: 解决容器创建批量端口失败的问题 (#830) 2023-04-28 14:46:20 +00:00
ssongliu c424e22924 fix: 两步验证样式调整 (#827) 2023-04-28 07:58:19 +00:00
zhengkunwang223 18e171446e feat: 解决文件上传成功后再次点击“确认”会重新上传一遍的问题 (#826) 2023-04-28 07:50:18 +00:00
zhengkunwang223 c0a1555c73 style: 网站列表增加 WAF 入口 (#825) 2023-04-28 07:18:19 +00:00
ssongliu 3b0c844f33 fix: 解决回车导致页面刷新的问题 (#824) 2023-04-28 07:16:22 +00:00
ssongliu 566a4f3568 fix: 面板设置证书改为抽屉实现 (#823) 2023-04-28 06:48:19 +00:00
ssongliu 2c8b19bff2 feat: 两步验证增加手动输入选项 (#822) 2023-04-28 03:42:16 +00:00
ssongliu 292dca6419 fix: 安全入口逻辑调整 (#821) 2023-04-27 14:44:16 +00:00
zhengkunwang223 ebe0f98209 feat: 文件搜索增加搜索子目录功能 (#819) 2023-04-27 21:31:52 +08:00
zhengkunwang223 eba1e5495f style: 运行环境页面增加提示 (#820) 2023-04-27 12:52:20 +00:00
ssongliu 0ebd04f012 feat: 1pctl 支持 mfa、ssl 和安全入口关闭 (#818) 2023-04-27 11:06:15 +00:00
maninhill c5e8a3fa04 Update README.md (#817)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-04-27 09:36:15 +00:00
maninhill 42b76fd82d Update README.md 2023-04-27 17:21:58 +08:00
zhengkunwang223 bbf610569d fix: 解决本地应用升级失败的问题 (#813) 2023-04-27 07:30:15 +00:00
ssongliu eeb5fa81a1 feat: 安全登录界面样式优化 (#814) 2023-04-27 07:18:16 +00:00
zhengkunwang223 f65ca6678f style: 网站-密码访问 名称 改为 用户名 (#812) 2023-04-27 06:02:15 +00:00
zhengkunwang223 680f48dcba feat: 文件权限增加修改子文件功能 (#811) 2023-04-27 05:54:15 +00:00
ssongliu 8947e00302 fix: 面板设置样式调整 (#810) 2023-04-27 04:46:14 +00:00
ssongliu b42cf32326 feat: 编排删除增加删除文件勾选 (#808) 2023-04-27 04:44:18 +00:00
ssongliu 5b68332b9a fix: compose 验证、提交按钮合并 (#806) 2023-04-27 02:24:14 +00:00
zhengkunwang223 d7f53862e9 fix: 解决文件编辑之后大小没有改变的 BUG (#804) 2023-04-26 14:30:14 +00:00
zhengkunwang223 7887bf96de feat: 文件管理增加用户/用户组设置 (#803) 2023-04-26 14:18:16 +00:00
zhengkunwang223 db2aa35b2f fix: 解决文件复制到原路径导致文件内容清空的 BUG (#798) 2023-04-26 12:30:14 +00:00
ssongliu 936b0e59ab fix: 修复概览页流量显示问题 (#797) 2023-04-26 10:56:14 +00:00
zhengkunwang223 6e3923d0da feat: 优化文件复制粘贴逻辑 (#796) 2023-04-26 09:58:12 +00:00
ssongliu 4377575206 feat: 存储卷创建支持 nfs (#795) 2023-04-26 09:26:12 +00:00
ssongliu 0c09b12680 fix: 编排创建样式调整、日志改为异步加载 (#794) 2023-04-26 09:00:20 +00:00
zhengkunwang223 8a32d8032f feat: 修改反向代理网站创建逻辑 (#793) 2023-04-26 08:06:12 +00:00
zhengkunwang223 9f12a91f4a feat: 页脚增加论坛、文档入口 (#792) 2023-04-26 07:36:11 +00:00
ssongliu dd0ca4bcaf feat: 创建容器时,端口支持多种形式 (#790) 2023-04-26 07:18:13 +00:00
ssongliu 14cc97eb44 fix: 证书校验规则修改 (#788) 2023-04-26 00:04:10 +00:00
ssongliu 2d31c5b005 feat: 容器增加资源使用、端口显示 (#786) 2023-04-25 14:06:17 +00:00
zhengkunwang223 05e7506f61 feat: 1pctl version 增加 mode 参数 (#784) 2023-04-25 13:28:17 +00:00
zhengkunwang223 37806f1113 feat: 网站增加密码访问功能 (#782) 2023-04-25 10:10:17 +00:00
ssongliu 79622f324b feat: 1pctl user-info 返回增加 protocol 信息 (#781) 2023-04-25 10:02:17 +00:00
ssongliu 34e84081e3 feat: 增加系统 ssl 设置功能 (#780) 2023-04-25 06:34:16 +00:00
ssongliu edf07be281 fix: 解决容器终端断开后未退出进程的问题 (#779) 2023-04-25 06:32:16 +00:00
zhengkunwang223 1208514f37 style: 文件列表样式修改 (#775) 2023-04-24 14:10:14 +00:00
你的明明呐丶andblank bfd857ec4b feat: 增加复制路径功能 (#749)
Co-authored-by: blank <admin@zym88.cn>
2023-04-24 18:21:44 +08:00
zhengkunwang223 9435290bb6 feat: 修改 api 文档 2023-04-24 17:53:05 +08:00
zhengkunwang223 acf64dcf25 feat: 反向代理增加编辑源文功能 2023-04-24 17:53:05 +08:00
zhengkunwang223 2dd88364f8 feat: 反向代理增加编辑功能 2023-04-24 17:53:05 +08:00
zhengkunwang223 d900b52a50 feat: 网站增加创建反向代理功能 2023-04-24 17:53:05 +08:00
ssongliu bd8d96be4d fix: 安全入口长度限制改为 6-10 位 2023-04-24 14:30:54 +08:00
ssongliu 17dd07fe32 feat: 概览页增加未启用安全入口提示信息 2023-04-24 14:30:54 +08:00
ssongliu a06e5f28b3 feat: 增加单独的安全入口接口,防止泄漏 2023-04-24 14:30:54 +08:00
ssongliu d5f400670c feat: 增加系统安全入口功能 2023-04-24 14:30:54 +08:00
ssongliu 5222388ba1 fix: 解决中文插件下 ufw 防火墙获取端口列表失败的问题 (#746) 2023-04-21 08:45:22 +00:00
ssongliu 549ccbe6a0 fix: 解决 ufw 防火墙版本加载失败问题 (#742) 2023-04-21 04:28:11 +00:00
邓小明 7fd6afb17f 为了安全,使面板首页禁止搜索引擎收录 (#721) 2023-04-21 10:28:59 +08:00
zhengkunwang223 2ff4da5e46 feat: 静态网站默认页增加禁止搜索引擎收录 (#741) 2023-04-21 02:26:11 +00:00
ssongliu 0f6e98be20 fix: 验证码错误后清空验证码输入框 (#740) 2023-04-21 02:08:10 +00:00
ssongliu 4399ffa9a4 fix: 延长备份下载超时时间 (#739) 2023-04-20 15:16:18 +00:00
ssongliu 44a1d9d16c fix: 防火墙端口添加支持输入网段 (#738) 2023-04-20 15:10:17 +00:00
ssongliu 565fd1c605 fix: ufw 增加中文适配 2023-04-20 22:34:50 +08:00
ssongliu 09ac40846f fix: ufw 防火墙增加 sudo 判断 (#733) 2023-04-20 10:44:17 +00:00
zhengkunwang223 a0b820649e fix: 解决网站设置用户/组报错的问题 (#710) 2023-04-19 03:17:00 +00:00
zhengkunwang223 6cee4bfe7c feat: 修改伪静态配置存储目录 (#703) 2023-04-18 15:27:00 +00:00
zhengkunwang223 ad0c859b54 fix: 解决网站目录重复的问题 (#695) 2023-04-18 11:19:00 +00:00
zhengkunwang223 d660b7d315 feat: 网站增加设置目录运行用户和用户组的功能 (#694) 2023-04-18 10:46:58 +00:00
wangdan-fit2cloud 2dbc7f28fd style: 修改网站目录样式 (#693)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-04-18 10:24:59 +00:00
ssongliu e224bc4b24 fix: 延长快照超时时间 (#691) 2023-04-18 09:32:59 +00:00
zhengkunwang223 9c52977825 style: 修改网站目录提示信息 (#688) 2023-04-18 08:02:58 +00:00
zhengkunwang223 cb151dc985 feat: mysql 和 redis 增加连接信息提示 (#687) 2023-04-18 07:30:57 +00:00
zhengkunwang223 24b9f8f705 fix: 解决网站过期时间设置为永久之后再次打开过期时间错误的问题 (#685) 2023-04-18 07:26:57 +00:00
zhengkunwang223 5592063e69 feat: 删除提示页面增加换行 (#684) 2023-04-18 07:25:00 +00:00
zhengkunwang223 7b19aab305 删除无用文件 (#677) 2023-04-17 10:32:36 +00:00
ssongliu 5c50695bdc fix: 登录页样式修改 (#676) 2023-04-17 10:30:40 +00:00
zhengkunwang223 1086597e3a feat: 增加配置网站运行目录功能 (#675) 2023-04-17 08:54:34 +00:00
ssongliu 2944ea508e fix: 容器创建增加镜像存在判断 (#674) 2023-04-17 08:08:28 +00:00
ssongliu 5e887bd00c feat: 备份账号删除时,查询使用情况 (#670) 2023-04-17 08:06:28 +00:00
zhengkunwang223 76b3cf4d2b feat: 运行环境支持手动输入 PHP 扩展 (#668) 2023-04-17 06:04:22 +00:00
ssongliu 4a9895218e fix: 命令执行增加超时时间 (#667) 2023-04-17 06:03:01 +00:00
ssongliu 222593ea69 fix: 页脚特殊符号修改 (#665) 2023-04-17 02:22:14 +00:00
ssongliu 05b7fd1f63 fix: 解决表单回车导致页面刷新的问题 (#664) 2023-04-17 02:20:17 +00:00
ssongliu 256c04f3b8 fix: 修改页脚错误 (#655) 2023-04-15 01:08:10 +00:00
zhengkunwang223 02577ef746 feat: OpenResty 升级提示转到创建网站处 (#647) 2023-04-14 09:18:48 +00:00
zhengkunwang223 059c3a0b80 feat: 创建 PHP 运行环境同步修改index目录文件和文件夹权限 (#644) 2023-04-14 09:16:53 +00:00
ssongliu 5ce1b1591a fix: 防火墙禁 ping 增加判断条件,不存在文件则隐藏 (#643) 2023-04-14 09:14:57 +00:00
zhengkunwang223 6595ad6228 feat: 增加伪静态设置 (#640) 2023-04-14 08:01:06 +00:00
ssongliu e7608673d7 feat: 打开防火墙时,自动放开应用以及 80 443 22 端口 (#637) 2023-04-14 07:10:46 +00:00
ssongliu 4c8fc1defa fix: 防火墙空状态页面样式优化 (#625) 2023-04-14 07:08:51 +00:00
ssongliu 975663f0ff feat: 增加自动更新检测 (#621) 2023-04-14 07:06:55 +00:00
zhengkunwang223 9603389586 feat: 解决编辑镜像之后会删除镜像的问题 (#613) 2023-04-13 06:42:34 +00:00
ssongliu cd79cac0af fix: 前端界面国际化优化 (#612) 2023-04-13 06:30:34 +00:00
zhengkunwang223 d151e98fab feat: PHP 运行环境,限制 Openresty 版本 (#611) 2023-04-13 06:28:33 +00:00
zhengkunwang223 6115ffe0fc fix: 解决删除网站锁库的问题 (#608) 2023-04-13 03:00:33 +00:00
ssongliu b646c5385d fix: 调整监控数据采集间隔 (#607) 2023-04-13 02:40:33 +00:00
ssongliu 04a1cff37e fix: 解决概览页接口报错 500 的问题 (#606) 2023-04-13 02:14:32 +00:00
zhengkunwang223 a5be9ca226 fix: 解决证书定时任务错误执行的问题 (#605) 2023-04-13 00:24:32 +00:00
zhengkunwang223 0356bdbf54 fix: 解决申请证书超时导致的脏数据 (#604) 2023-04-12 15:00:30 +00:00
zhengkunwang223 4c276ff383 feat: 增加 cmd 执行时间 (#603) 2023-04-12 14:46:30 +00:00
zhengkunwang223 f8432ba521 fix: 解决网站停止之后无法启动的问题 (#602) 2023-04-12 13:52:30 +00:00
ssongliu 7f75ea06c2 fix: 防火墙禁 ping 样式优化 (#601) 2023-04-12 10:58:30 +00:00
ssongliu 11d3e98155 fix: 计划任务删除提示样式优化 (#600) 2023-04-12 10:56:33 +00:00
zhengkunwang223 01185306f2 fix: 解决删除本地运行环境报错的问题 (#599) 2023-04-12 09:22:30 +00:00
ssongliu 6ff9c4335f fix: 防火墙 ip 规则取消范围输入 (#598) 2023-04-12 08:32:30 +00:00
ssongliu b2e38c320d fix: 解决计划任务清除所有数据失败的问题 (#597) 2023-04-12 08:26:30 +00:00
zhengkunwang223 c63897ded4 feat: 文件编辑器增加 python 语言 (#595) 2023-04-12 07:28:31 +00:00
ssongliu d6dcb59ab7 fix: 解决 firewalld ip 范围规则不生效的问题 (#594) 2023-04-12 06:50:30 +00:00
zhengkunwang223 bd1ced0af7 feat: 增加修改 PHP 文件的接口 (#593) 2023-04-12 06:48:30 +00:00
zhengkunwang223 1bbf501783 feat: 优化网站、应用删除逻辑 (#592) 2023-04-12 06:22:29 +00:00
zhengkunwang223 b16308b7ea feat: 优化网站创建流程 (#591) 2023-04-12 06:16:29 +00:00
ssongliu 42531dae5a fix: 计划任务列表样式调整 (#589) 2023-04-12 03:40:29 +00:00
ssongliu aeb9135cde fix: 解决系统不存在 netstat 命令的问题 (#588) 2023-04-12 03:22:29 +00:00
ssongliu f092927ab8 fix: 解决开启防火墙未添加系统端口的问题 (#586) 2023-04-12 00:36:29 +00:00
ssongliu 3ac467fc53 fix: 解决操作日志解析失败的问题 (#585) 2023-04-11 15:52:28 +00:00
ssongliu b9e1de8446 fix: 增加七牛云加速域名提示信息 (#584) 2023-04-11 15:50:33 +00:00
ssongliu 245bbf651b fix: 解决计划任务下载失败的问题 (#581) 2023-04-11 14:26:28 +00:00
ssongliu a8b83cf4ed feat: 计划任务删除时增加删除数据提示 (#580) 2023-04-11 10:48:28 +00:00
zhengkunwang223 38725097a6 feat: 删除运行环境级联删除镜像 (#579) 2023-04-11 09:08:29 +00:00
ssongliu e935fa128f fix: 解决备份所有时,保留份数错误的问题 (#578) 2023-04-11 09:00:29 +00:00
ssongliu ef16934952 fix: 防火墙禁 ping 方式修改 (#577) 2023-04-11 08:58:33 +00:00
zhengkunwang223 550872a564 fix: 解决安装应用锁库的问题 (#576) 2023-04-11 06:38:27 +00:00
ssongliu e746a959af fix: 补全备份列表返回信息 (#575) 2023-04-11 04:10:25 +00:00
ssongliu ab0f4380b2 fix: 保存主机信息必须先通过连接测试 (#574) 2023-04-11 04:04:25 +00:00
ssongliu 7c236ccc3a feat: 数据库增加 ServiceName 显示 (#573) 2023-04-11 02:26:25 +00:00
zhengkunwang223 52030dbea0 style: runtime列表样式修改 (#571) 2023-04-11 02:18:25 +00:00
wanghe-fit2cloud 4e20ec1c9b refactor: 修改容器镜像加速描述信息 2023-04-10 22:13:16 +08:00
ssongliu 0ddbdfeac9 feat: 主机增加记住密码,支持带密码私钥连接 (#570) 2023-04-10 13:50:24 +00:00
zhengkunwang223 a5fd55e90e style: 取消一行同步应用的日志打印 (#569) 2023-04-10 10:50:24 +00:00
zhengkunwang223 844a6c11b4 feat: 本地运行环境限制编辑 PHP 文件 (#568) 2023-04-10 10:32:23 +00:00
ssongliu a4cab09b62 fix: 解决编辑主机信息时,未输入密码或密钥测试连接失败的问题 (#567) 2023-04-10 09:56:24 +00:00
zhengkunwang223 12d010351a fix: 解决本地运行环境网站被删除之后 误删其他应用的BUG (#566) 2023-04-10 09:32:22 +00:00
zhengkunwang223 d00e5b0421 fix: 解决修改分组之后 网站页面过滤条件分组没有刷新的问题 (#565) 2023-04-10 09:30:23 +00:00
ssongliu 4c2fb7095d fix: 解决 Swarm 模式下,启用 live-restore 重启失败的问题 (#564) 2023-04-10 09:04:23 +00:00
zhengkunwang223 cca1406f0f feat: 应用更新端口之后放开相应防火墙端口 (#563) 2023-04-10 08:26:22 +00:00
zhengkunwang223 1bba2664b6 feat: 网站列表增加运行环境字段 (#562) 2023-04-10 08:24:26 +00:00
ssongliu cc51eaef3f fix: 容器创建中命令输入方式修改 (#561) 2023-04-10 08:22:29 +00:00
ssongliu 2bd289defa fix: 防火墙端口校验规则修改 (#560) 2023-04-10 06:46:22 +00:00
zhengkunwang223 47d090d481 fix: 解决已安装应用包含大写字母,启动失败的BUG (#559) 2023-04-10 06:44:23 +00:00
ssongliu 4a4c2b24dd fix: 解决禁 ping 状态获取失败的问题 (#557) 2023-04-10 04:58:13 +00:00
ssongliu 8603d4347b feat: mysql root 密码增加随机和复制按钮 (#556) 2023-04-10 04:56:16 +00:00
ssongliu 188a3e0ac5 feat: 数据库创建支持随机密码 (#555) 2023-04-10 03:52:15 +00:00
ssongliu a22efc90f6 fix: 解决用户授权失败的问题 (#554) 2023-04-10 03:32:13 +00:00
wanghe-fit2cloud d0d76c023f refactor: edit Makefile 2023-04-10 10:35:53 +08:00
ssongliu 241a4e62ac fix: 容器配置文件为空时,删除配置文件 (#553) 2023-04-09 15:58:13 +00:00
ssongliu 295f2a5cf2 fix: 解决禁 ping 状态切换失败的问题 (#552) 2023-04-09 14:54:13 +00:00
ssongliu e3cf522565 fix: 解决表单修改 iptables 失败的问题 (#551) 2023-04-09 14:40:12 +00:00
zhengkunwang223 0f1107314f fix: 解决创建运行环境报错的 BUG (#550) 2023-04-09 14:32:12 +00:00
zhengkunwang223 18c5c99705 feat: 创建运行环境增加版本校验 (#549) 2023-04-09 14:30:16 +00:00
ssongliu 18b4c98daa feat: 计划任务支持自定义日志保留份数 (#548) 2023-04-09 14:22:13 +00:00
zhengkunwang223 24246da71c feat: 创建应用忽略创建默认 network (#546) 2023-04-09 13:00:13 +00:00
zhengkunwang223 49ab26200d feat: 运行环境应用和版本增加联动 (#545) 2023-04-09 12:58:16 +00:00
gengxin 5c524f0d23 feat: 文件支持URL直接访问 (#543) 2023-04-09 10:18:04 +08:00
zhengkunwang223 15d7d74c1b fix: 解决 echart 前端报错 (#542) 2023-04-08 14:56:11 +00:00
zhengkunwang223 29979b23c2 feat: 优化前端页面打开速度 (#541) 2023-04-08 14:46:12 +00:00
zhengkunwang223 3de223144d feat: 前端启动配置可以通过 IP 访问 (#538) 2023-04-08 06:04:11 +00:00
zhengkunwang223 18029d8369 feat: 增加同步本地应用功能 (#537) 2023-04-08 06:02:14 +00:00
ssongliu fb62ac17e5 fix: 完善系统操作日志 (#536) 2023-04-07 09:46:10 +00:00
ssongliu dbe70ecc28 fix: docker 配置增加 iptables (#535) 2023-04-07 09:44:15 +00:00
Wankko Ree 74b6af64e9 fix: 对于 Redis 终端、容器终端也同步改造 2023-04-07 17:37:14 +08:00
Wankko Ree fa83199d7b feat: 抽象出终端为独立组件 2023-04-07 17:37:14 +08:00
Wankko Ree 750a2a445e feat: 增加终端的网络延迟显示 2023-04-07 17:37:14 +08:00
Wankko Ree 6fb1e690aa feat: 添加终端心跳包,增强连接稳定性,并为后续延迟检测做准备 2023-04-07 17:37:14 +08:00
Wankko Ree 77c0eb99f0 fix: 更改 WebSocket 编码为 json ,抛弃使用xterm-addon-attach插件,其特性不利于后续功能扩展,见:https://github.com/xtermjs/xterm.js/issues/1301 2023-04-07 17:37:14 +08:00
Wankko Ree db64cf02bd fix: 合并终端返回数据的代码 2023-04-07 17:37:14 +08:00
Wankko Ree 57a6417812 fix: 修复AttachAddon会将数据以raw形式重复发送的问题 2023-04-07 17:37:14 +08:00
Wankko Ree 12beef49b5 fix: 修改一处let和ref混用的奇怪声明 2023-04-07 17:37:14 +08:00
zhengkunwang223 155363afa6 fix: 解决升级应用失败的 BUG (#534) 2023-04-07 08:46:11 +00:00
ssongliu 3b3fad7278 fix: 监控界面时间控件居中显示 (#533) 2023-04-07 08:42:09 +00:00
ssongliu b6c4c4539f fix: 解决 docker 配置修改提示信息错误的问题 (#530) 2023-04-07 06:46:10 +00:00
ssongliu 807302f6cd feat: 计划任务记录增加定时刷新 (#529) 2023-04-07 06:44:14 +00:00
ssongliu 8902111c23 feat: 增加计划任务记录清空按钮 (#528) 2023-04-07 04:02:10 +00:00
ssongliu e45ef455ef fix: 解决 go 版本升级导致的代码警告 (#527) 2023-04-07 03:30:10 +00:00
ssongliu 0eb25d8413 feat: 计划任务支持备份所有 (#526) 2023-04-07 02:18:10 +00:00
zhengkunwang223 a0e4c266a1 fix: 解决安装应用同步之后变为失败的 BUG (#525) 2023-04-07 01:16:09 +00:00
zhengkunwang223 e452dfdb1f fix: 解决应用一直安装中的 BUG (#522) 2023-04-06 10:32:16 +00:00
zhengkunwang223 e3b542665d feat: 文件增加批量删除功能 (#521) 2023-04-06 09:58:17 +00:00
zhengkunwang223 a481a8b322 feat: 创建应用放开相应端口 (#520) 2023-04-06 09:16:16 +00:00
zhengkunwang223 1b5387dc5a feat: 运行环境样式修改 (#519) 2023-04-06 08:38:16 +00:00
ssongliu 281cf48aaa fix: 解决备份账号创建后,未重制 bucket 选项的问题 (#518) 2023-04-06 06:42:16 +00:00
ssongliu ce2b92ee01 fix: 调整服务未启动的遮罩样式 (#517) 2023-04-06 06:34:15 +00:00
zhengkunwang223 daba12ee42 fix: 处理 docker 漏洞 (#516) 2023-04-06 03:16:16 +00:00
ssongliu 363a67b0f2 fix: 防火墙样式调整 (#515) 2023-04-06 03:12:15 +00:00
zhengkunwang223 1a1a14719d feat: 处理合并代码依赖 2023-04-06 10:38:14 +08:00
zhengkunwang223 5706de5ca7 feat: 增加 PHP 相关配置修改功能 2023-04-06 10:38:14 +08:00
zhengkunwang223 947293f34e feat: 增加数据库日志配置 2023-04-06 10:38:14 +08:00
zhengkunwang223 04a76fd94d feat: 增加配置 php 配置文件功能 2023-04-06 10:38:14 +08:00
zhengkunwang223 c629fa9575 feat: 增加创建运行环境类型网站 2023-04-06 10:38:14 +08:00
zhengkunwang223 d4c1caa26a feat: 增加运行环境编辑功能 2023-04-06 10:38:14 +08:00
zhengkunwang223 22d9bdacf6 feat: runtime 增加删除功能 2023-04-06 10:38:14 +08:00
zhengkunwang223 64a954df53 feat: 增加创建 php 运行环境功能 2023-04-06 10:38:14 +08:00
zhengkunwang223 1949be2490 feat: 菜单增加运行环境 2023-04-06 10:38:14 +08:00
zhengkunwang223 8be00dad7f feat: 代码规范性修改 2023-04-06 10:38:14 +08:00
zhengkunwang223 bf9a37623a feat: 对接 docker compose SDK 2023-04-06 10:38:14 +08:00
zhengkunwang223 3de0ae1b0f feat: 升级 Go 版本到 v1.19 2023-04-06 10:38:14 +08:00
ssongliu 57a2c2616b feat: 增加 S3 兼容存储对象文档跳转 (#514) 2023-04-06 02:20:16 +00:00
ssongliu c63967158b fix: 监控数据改为批量插入 (#512) 2023-04-06 02:18:15 +00:00
ssongliu 8902fdc78a feat: 同步修改防火墙端口 2023-04-06 09:01:57 +08:00
ssongliu 1c5d01b11c feat: 实现禁 ping 功能 2023-04-06 09:01:57 +08:00
ssongliu c1c324af23 feat: 增加防火墙开关及行状态切换功能 2023-04-06 09:01:57 +08:00
ssongliu db74d010d7 feat: 实现防火墙批量删除及修改功能 2023-04-06 09:01:57 +08:00
ssongliu c9d36d84f7 feat: 完成 firewalld 与 ufw 列表显示 2023-04-06 09:01:57 +08:00
ssongliu d5f446d7cf feat: 完成前端端口规则设置功能 2023-04-06 09:01:57 +08:00
ssongliu a2fcdabb7b feat: 封装防火墙 firewalld 相关操作 2023-04-06 09:01:57 +08:00
ssongliu a434bbbc12 feat: 页面增加腾讯云、阿里云备份账号 2023-04-06 09:01:33 +08:00
ssongliu 2585801f8a feat: 增加后端对七牛云、腾讯云的适配 2023-04-06 09:01:33 +08:00
Wankko Ree c501d9fefe fix: 修复终端在网络环境较差时无法正常初始化全屏尺寸的问题 (#505) (#507) 2023-04-05 14:04:15 +00:00
Wankko Ree 1d99559d4c fix: 修复前端开发时后端接口代理无法正常连接 WebSocket 的问题 (#506)
不确定开发团队是否有碰到这个问题,我这边将后端接口代理到自己服务器时, WebSocket 无法正常建立连接,需要添加参数才行。

另外,官网的开发文档可以做一些补充,如只需要调试前端开发环境时,可以将代理指向在线服务器的后端接口,而不是在本地起一个后端。
2023-04-05 14:02:19 +00:00
ssongliu 1d5797fe68 fix: 修复了执行周期更新失败的问题 2023-03-31 17:23:30 +08:00
zhengkunwang223 bbe08ed218 style: 修改编辑器行尾符提示 (#465) 2023-03-31 07:18:15 +00:00
ssongliu 6e12eba356 fix: 修复了重启后计划任务执行周期错误的问题 (#462) 2023-03-31 04:34:14 +00:00
zhengkunwang223 3457b99df6 fix: 解决 nexus 安装失败的问题 (#461) 2023-03-31 04:16:14 +00:00
ssongliu 4ad3b82c84 fix: 解决 opencontainers/runc 系统漏洞 (#459) 2023-03-31 03:22:13 +00:00
ssongliu 85fc07c900 fix: 概览页磁盘显示过滤规则修改 (#458) 2023-03-31 03:20:19 +00:00
gengxin d71e2a74b4 feat: xterm-Support for Ctrl+MouseWheel to scaling fonts (#448)
#### What this PR does / why we need it?
#284 
Support for scaling fonts using Ctrl+mouse wheel

#446 
support Editor config the eol.
Currently, 1Panel only supports Linux, so directly set the default EOL to LF and add a new configuration item 

#### Summary of your change

#### Please indicate you've done the following:

- [x] Made sure tests are passing and test coverage is added if needed.
- [x] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-03-31 03:16:15 +00:00
zhengkunwang223 a18105349b fix: 解决某些版本的 ubuntu 启动不了的 BUG (#451) 2023-03-30 07:08:13 +00:00
wangdan-fit2cloud 6472227b6b fix: 修复登录页面从大屏切换小屏填写信息消失问题 (#450)
#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
2023-03-30 06:42:13 +00:00
ssongliu c927132aa6 fix: 优化了概览页、监控页选项排序 2023-03-29 23:00:32 +08:00
ssongliu b06058ec18 fix: 修复了概览页未显示挂载磁盘信息的问题 (#442) 2023-03-29 13:28:13 +00:00
ssongliu 57329a26c8 fix: 修复了概览页 io 延迟数据错误的问题 (#441) 2023-03-29 12:56:13 +00:00
ssongliu 4a1aa84fa8 fix: 修改 jwt 超时时间为 1 小时 (#437) 2023-03-29 07:34:13 +00:00
ssongliu cbe9c83515 fix: 修复了 jwt 无法登录的问题 (#436) 2023-03-29 03:46:14 +00:00
ssongliu 67479e7060 fix: 修复了创建容器自动拉取镜像失败的问题 (#433) 2023-03-28 11:02:11 +00:00
ssongliu b454c959b4 fix: 修复了部分容器创建完直接退出的问题 (#432) 2023-03-28 09:50:11 +00:00
wangdan-fit2cloud e2d39b9ed0 fix: 登录页面优化适配 (#425) 2023-03-27 23:07:32 +08:00
maninhill b9fbcb0e73 chore: 简化社区软件协议文案 2023-03-26 10:14:25 +08:00
ssongliu 30cb471629 fix: 修改默认升级版本 (#390) 2023-03-24 03:52:10 +00:00
ssongliu d70c22dde8 fix: 解决设置默认分组的问题 (#385) 2023-03-23 12:58:33 +00:00
ssongliu 01bb6b7c01 fix: 解决 mfa 验证回车时触发页面刷新的问题 (#383) 2023-03-23 12:34:33 +00:00
ssongliu 4f4879759e fix: 修改主机默认分组名称 (#381) 2023-03-23 08:26:33 +00:00
ssongliu 92a410fcea fix: 修改构建失败判断条件 (#380) 2023-03-23 08:24:36 +00:00
zhengkunwang223 5d1fced8e9 feat: 网站分组删除校验 (#377) 2023-03-23 04:14:31 +00:00
liqiang-fit2cloud a56e5a8abe Pr@dev@docs add readme en.md (#378)
* docs: add README_EN.md.

* docs: add README_EN.md.

* docs: add README_EN.md.

* docs: add README_EN.md.
2023-03-23 11:43:43 +08:00
liqiang-fit2cloud 28ae7f3a0c docs: add README_EN.md. (#375) 2023-03-23 11:08:11 +08:00
zhengkunwang223 8d675c81c5 feat: 优化网站分组 (#372) 2023-03-22 13:42:30 +00:00
ssongliu 66a345364f fix: 优化分组显示 (#371) 2023-03-22 10:48:29 +00:00
zhengkunwang223 a3cb8be08f feat: 修改文件上传错误处理 (#370) 2023-03-22 10:34:29 +00:00
zhengkunwang223 0861b30a7b fix: 解决应用创建没有默认网络创建失败的BUG (#369) 2023-03-22 10:22:29 +00:00
ssongliu 36f2a3eb4b fix: 优化计划任务记录查询返回 (#364) 2023-03-22 10:16:29 +00:00
zhengkunwang223 092cbbf8da feat: 应用编辑增加 select 类型处理 (#363) 2023-03-22 07:38:30 +00:00
ssongliu 39e3e8f214 fix: 优化容器菜单页面状态加载样式 (#356) 2023-03-22 07:32:29 +00:00
ssongliu fa983bdcc9 fix: 优化导入备份限制 (#361) 2023-03-22 07:20:30 +00:00
zhengkunwang223 67bb30c10c fix: 解决文件编辑,快捷提示不显示的 BUG (#355) 2023-03-22 11:56:09 +08:00
ssongliu e85340ca5d fix: 数据库启用 WAL 模式,增加连接数与超时设置 (#349)
fix: 数据库启用 WAL 模式,增加连接数与超时设置
2023-03-21 11:00:28 +00:00
ssongliu a3a1e17849 fix: 解决监控时间控件显示不全的问题 (#348)
fix: 解决监控时间控件显示不全的问题
2023-03-21 10:48:27 +00:00
ssongliu 2601135225 fix: 解决快照同步恢复失败的问题 (#345)
fix: 解决快照同步恢复失败的问题
2023-03-21 10:46:31 +00:00
ssongliu c556affc91 fix: 解决数据库密码修改未同步到应用的问题 (#343)
fix: 解决数据库密码修改未同步到应用的问题
2023-03-21 10:44:35 +00:00
ssongliu 6ee9789a2f fix: 修改镜像构建和编排创建路径限制,增加 config 校验 (#342)
fix: 修改镜像构建和编排创建路径限制,增加 config 校验
2023-03-21 10:42:37 +00:00
ssongliu 68a457ae89 fix: 升级逻辑调整 (#341)
fix: 升级逻辑调整
2023-03-21 07:16:28 +00:00
zhengkunwang223 72237596f3 feat: 证书列表增加设置自动续签功能 (#337) 2023-03-21 14:42:50 +08:00
zhengkunwang223 f516333682 删除 issue 处理相关 workflow (#339) 2023-03-21 06:40:31 +00:00
zhengkunwang223 873af25684 fix: 解决网站定时任务没有执行的BUG (#333) 2023-03-21 05:10:27 +00:00
zhengkunwang223 8b058a873e feat: 登录增加社区软件许可协议同意选项 (#322) 2023-03-20 11:26:27 +00:00
ssongliu 0c5a5a6454 fix: 创建编排改为异步操作 (#318)
fix:  创建编排改为异步操作
2023-03-20 10:16:26 +00:00
zhengkunwang223 2096049708 feat: 删除自动创建 pr 的 workflow (#313) 2023-03-20 14:07:11 +08:00
1Panel-bot 1095aa2b65 fix: 解决镜像构建输出部分丢失的问题 (#310)
fix: 解决镜像构建输出部分丢失的问题
2023-03-20 03:34:09 +00:00
Ikko Eltociear Ashimine 13679ff301 Fix typo in image.go (#306)
lenth -> length
2023-03-20 10:41:54 +08:00
1Panel-botandzhengkunwang223 89b7a06662 feat: 系统启动增加同步已安装应用步骤 (#295)
Co-authored-by: zhengkunwang223 <zhengkun@fit2cloud.com>
2023-03-20 10:38:39 +08:00
maninhill e8582bea75 Update README.md 2023-03-19 15:59:11 +08:00
wanghe 9af7926eb9 Create SECURITY.md 2023-03-18 23:08:08 +08:00
BugKing bdcdf7e181 ci: add workflow to sync to Gitee repo 2023-03-18 22:48:17 +08:00
ssongliu 887db0aff7 fix: 页面切换时,隐藏默认配置提示 2023-03-18 09:28:30 +00:00
ssongliu 4a974b7e0a fix: 解决计划任务备份文件失效仍能下载的问题 2023-03-18 03:06:31 +00:00
ssongliu fb286d2def fix: 解决慢日志开启后未刷新导致无法关闭的问题 2023-03-17 14:58:31 +00:00
ssongliu 89cb9e6693 fix: 解决 mysql 数据库带 - 字符授权失败的问题 2023-03-17 11:48:30 +00:00
ssongliu 927def4472 fix: 解决 compose 创建错误未存库的问题 2023-03-17 11:40:30 +00:00
ssongliu 84fcd31704 fix: 升级版本判断逻辑修改 2023-03-17 10:12:30 +00:00
maninhill 005e5cc01f Update README.md 2023-03-17 17:46:34 +08:00
ssongliu 2896409b3a fix: 解决计划任务保存到第三方备份账号不生效的问题 2023-03-17 09:08:31 +00:00
zhengkunwang223 791641f3e1 feat: 修改 .gitignore 规则 2023-03-17 09:02:29 +00:00
wangdan 79f266bbda fix: 修复国际化问题 2023-03-17 08:06:30 +00:00
maninhill c9edaf0d1d Update README.md 2023-03-17 14:37:53 +08:00
ssongliu ac5f73c687 fix: 国际化换行问题修改 2023-03-17 04:20:29 +00:00
ssongliu cc0667429a fix: redis 最大连接数限制 2023-03-17 04:18:29 +00:00
zhengkunwang223 92a5d6faeb style: 网站跳转按钮挪到网站域名设置页面 2023-03-17 04:16:30 +00:00
ssongliu 1111b6b494 fix: 增加 ip 或 域名正则校验 2023-03-17 03:28:29 +00:00
zhengkunwang223 be5a7c99e1 feat: 删除自动关闭 issue 的 action 2023-03-17 03:16:29 +00:00
ssongliu d6a963c087 fix: 容器创建默认值修改 2023-03-17 02:04:29 +00:00
ssongliu af753bdffe fix: 表格可点击列超长样式优化 2023-03-16 14:50:29 +00:00
zhengkunwang223 59b025353f fix: 解决手动解析模式 申请证书失败的BUG 2023-03-16 11:34:28 +00:00
zhengkunwang223 355a6b0205 feat: 网站一键部署应用,名称与单独部署应用保持一致 2023-03-16 09:46:30 +00:00
zhengkunwang223 7de80e9d5a fix: 解决打开文件编辑,控制台报错的问题 2023-03-16 09:44:28 +00:00
ssongliu 4c6d8cd20c fix: 备份恢复增加一些失败日志打印 2023-03-16 09:42:28 +00:00
ssongliu 31da89d63a fix: 数据库重启等操作增加 loading 2023-03-16 09:40:32 +00:00
zhengkunwang223 e044ca7d12 style: 修改停用提示的样式 2023-03-16 07:52:28 +00:00
ssongliu 7c037b68cd fix: 容器删除使用中对象提示信息优化 2023-03-16 07:48:28 +00:00
ssongliu 9080824a59 fix: 解决 mysql 慢日志设置修改失败的问题 2023-03-16 06:06:32 +00:00
zhengkunwang223 11f4bc2c89 fix: 解决文件和网站名称过长只显示...的问题 2023-03-16 06:04:28 +00:00
zhengkunwang223 a64ddd1eb8 feat: 修改 action name 2023-03-15 18:25:34 +08:00
1Panel-bot 2fdaecfafe feat: 删除不必要的action (#228)
feat: 删除不必要的action
2023-03-15 10:20:26 +00:00
1Panel-bot 6d1fe20736 feat: 增加 actions (#226)
feat: 增加 actions
2023-03-15 10:08:28 +00:00
wanghe f61bc047cd Update README.md 2023-03-15 17:47:18 +08:00
ssongliu 4f52580938 fix: 容器部分已知问题修改 (#224)
1. 删除存储卷增加使用中判断
2. 容器操作时增加来源判断
3. 解决删除镜像后页面没有自动刷新的问题
2023-03-15 08:48:26 +00:00
ssongliu 281d0cf880 fix: 敏感字符增加传输加密 (#219)
1. 敏感字符增加传输加密
2023-03-15 07:58:26 +00:00
zhengkunwang223 fdf9215d43 fix: 解决打开应用详情页,控制台报错的 BUG (#218) 2023-03-15 07:56:29 +00:00
zhengkunwang223 8c182e907d feat: 增加 OWNERS 文件 2023-03-15 15:39:02 +08:00
ssongliu e55af04568 fix: 移除调试打印信息 2023-03-15 13:00:31 +08:00
wanghe-fit2cloud 2462ffdbab refactor: issue template 2023-03-15 11:42:45 +08:00
ssongliu bfeb57e24f fix: oss 改用分片上传与下载 2023-03-15 11:19:25 +08:00
maninhill 9bb28cda27 Update README.md 2023-03-15 09:28:37 +08:00
ssongliu 42e522abe1 fix: 升级 1pctl 被覆盖后,手动替换 BASE_DIR 2023-03-14 23:17:54 +08:00
zhengkunwang223 fb5c3429e5 feat: 文件下载页面增加 loading 2023-03-14 23:06:19 +08:00
ssongliu 0fe1fd3c7b fix: 初始化安装时,增加默认版本 2023-03-14 19:27:46 +08:00
ssongliu bdcca7f380 fix: 调整上传文件夹 2023-03-14 19:27:46 +08:00
ssongliu 796d47d60e fix: 计划任务分页调整 2023-03-14 19:27:46 +08:00
ssongliu a9a45ce5ac fix: 调整升级逻辑 2023-03-14 19:27:46 +08:00
ssongliu d04121c551 fix: 解决镜像构建失败的问题 2023-03-14 19:27:46 +08:00
ssongliu dd06ff73e6 fix: redis aof 备份恢复与版本匹配 2023-03-14 19:27:46 +08:00
wangdan 24b3501f38 feat: 优化关于页面的版本信息 2023-03-14 19:07:54 +08:00
zhengkunwang223 ed11c0a4a6 fix: 解决删除MYSQL应用没有同步删除表数据的BUG 2023-03-14 18:18:49 +08:00
zhengkunwang223 7591a716f4 fix: 解决应用删除提示页面没有实时刷新的 BUG 2023-03-14 17:37:19 +08:00
zhengkunwang223 ce44ccdedb style: 修改接口过期时间 2023-03-14 17:27:11 +08:00
zhengkunwang223 521fca93bd style: 修改样式 2023-03-14 17:27:11 +08:00
zhengkunwang223 d6a0dc0125 feat: 修改前端超时时间为10秒 2023-03-14 15:44:36 +08:00
zhengkunwang223 0a483383b4 style: 删除无用代码 2023-03-14 15:44:36 +08:00
zhengkunwang223 6c99e04aee feat: 增加判断系统是否是 demo 接口 2023-03-14 15:05:44 +08:00
zhengkunwang223 e120bb0612 feat: 编辑器增加 plaintext 类型 2023-03-14 15:05:44 +08:00
zhengkunwang223 92a11863a7 feat: 已安装应用改为同步 2023-03-14 15:05:44 +08:00
zhengkunwang223 2091fdbe5d feat: 增加应用列表更新提示 2023-03-14 15:05:44 +08:00
zhengkunwang223 b518463c90 style: 取消网站页面的提示 2023-03-14 10:59:32 +08:00
ssongliu 94fbb265fa fix: 数据库权限去掉 localhost 2023-03-14 10:34:17 +08:00
ssongliu daefd650a5 fix: 修复计划任务编辑失败的问题 2023-03-14 10:34:17 +08:00
ssongliu 4994cc39f1 fix: 解决主机密钥连接失败的问题 2023-03-14 10:34:17 +08:00
ssongliu 2dec0bfb3c fix: 容器创建增加端口判断 2023-03-14 10:34:17 +08:00
ssongliu eb56b918a6 fix: 增加一些校验规则 2023-03-14 10:34:17 +08:00
ssongliu 35098ce79c fix: 解决删除应用时,未删除备份记录的问题 2023-03-14 10:34:17 +08:00
ssongliu 5a3a123be7 fix: 解决 compose 创建失败的问题 2023-03-14 10:34:17 +08:00
ssongliu a94e78d31e fix: 解决面板设置部分界面密码过期仍然能访问的问题 2023-03-14 10:34:17 +08:00
ssongliu 5527ef73ad fix: 登录页背景图替换 2023-03-14 10:34:17 +08:00
ssongliu f1ed976c17 fix: 解决错误容器终端参数导致页面卡死的问题 2023-03-14 10:34:17 +08:00
zhengkunwang223 471bbb5c43 feat: 解决 amd64 环境下的打包问题 2023-03-14 10:10:08 +08:00
zhengkunwang223 4ae8e580b9 style: 修改样式 2023-03-13 18:02:48 +08:00
zhengkunwang223 ffb0e72a5b feat: 删除无用代码 2023-03-13 18:02:48 +08:00
zhengkunwang223 7f9793e4bb feat: 增加 SystemUpgrade 组件 2023-03-13 18:02:48 +08:00
zhengkunwang223 c332d0284b feat: 修改 code-editor 样式 2023-03-13 18:02:48 +08:00
zhengkunwang223 8b3d84d667 feat: 增加右下角检查更新功能 2023-03-13 18:02:48 +08:00
zhengkunwang223 f009e6414a feat: 限制上传文件数量 2023-03-13 18:02:48 +08:00
zhengkunwang223 e36cbb0eb7 feat: 前端增加 msg-info 组件 2023-03-13 18:02:48 +08:00
zhengkunwang223 2fbddf3f30 fix: 解决zip文件压缩报错的BUG 2023-03-13 18:02:48 +08:00
zhengkunwang223 8927b59bae fix: 解决cc防护填写数字报错的BUG 2023-03-13 18:02:48 +08:00
zhengkunwang223 90c7f9cc2c fix: 解决上传报错的BUG 2023-03-13 18:02:48 +08:00
zhengkunwang223 83ca72e153 feat: 统一限制最大数字输入位数为15位 2023-03-13 18:02:48 +08:00
zhengkunwang223 9571d82932 fix: 解决创建软连接失败的BUG 2023-03-13 18:02:48 +08:00
zhengkunwang223 c54451c733 feat: 限制数字输入的最大长度 2023-03-13 18:02:48 +08:00
zhengkunwang223 e52ddd3f39 fix: 解决申请证书,域名无效导致的 panic 2023-03-13 18:02:48 +08:00
wangdan c488507d96 feat: 优化样式 2023-03-13 17:37:34 +08:00
maninhill db5853df7d Update README.md 2023-03-13 15:58:38 +08:00
maninhill eb2e533d14 Update README.md 2023-03-13 15:57:30 +08:00
585 changed files with 40141 additions and 20002 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ body:
required: true
attributes:
label: "1Panel 版本"
description: "可通过系统右上角下拉菜单中的`关于`选项,或查看安装目录中的 version 文件获取。"
description: "登录 1Panel Web 控制台,在页面右下角查看当前版本。"
- type: markdown
id: details
attributes:
+1 -1
View File
@@ -14,7 +14,7 @@ body:
required: true
attributes:
label: "1Panel 版本"
description: "可通过系统右上角下拉菜单中的`关于`选项,或查看安装目录中的 version 文件获取。"
description: "登录 1Panel Web 控制台,在页面右下角查看当前版本。"
- type: markdown
id: details
attributes:
+17
View File
@@ -0,0 +1,17 @@
on: pull_request
name: 1Panel 通用 PR 处理
permissions:
pull-requests: write
jobs:
generic_handler:
name: 为 PR 添加标签
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-ecosystem/action-add-labels@v1
with:
github_token: ${{ secrets.GITHUBTOKEN }}
labels: ${{ github.base_ref }}
+36
View File
@@ -0,0 +1,36 @@
on:
pull_request:
branches:
- dev
push:
branches:
- dev
name: Build Test
jobs:
build-linux-binary:
runs-on: ubuntu-latest
steps:
- name: Install cross-compilers
run: sudo apt-get update && sudo apt-get -y install gcc-x86-64-linux-gnu gcc-aarch64-linux-gnu gcc-arm-linux-gnueabi gcc-powerpc64le-linux-gnu gcc-s390x-linux-gnu
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18.14'
- name: Build Web
id: build_frontend
run: |
cd frontend && npm install && npm run build:dev
env:
NODE_OPTIONS: --max-old-space-size=8192
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.20.x'
- name: Build Server
uses: goreleaser/goreleaser-action@v4
with:
args: release --snapshot --clean
+17
View File
@@ -0,0 +1,17 @@
on:
schedule:
- cron: "0 1 * * *"
name: Check recent handle issues
jobs:
check-recent-issues-not-handle:
runs-on: ubuntu-latest
steps:
- name: Check recent issues and send msg
uses: jumpserver/action-issues-alert@master
with:
hook: ${{ secrets.WECHAT_GROUP_WEB_HOOK }}
type: recent
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,17 @@
on:
schedule:
- cron: "0 9 * * 1-5"
name: Check untimely handle issues
jobs:
check-untimely-handle-issues:
runs-on: ubuntu-latest
steps:
- name: Check untimely issues and send msg
uses: jumpserver/action-issues-alert@master
with:
hook: ${{ secrets.WECHAT_GROUP_WEB_HOOK }}
type: untimely
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+52
View File
@@ -0,0 +1,52 @@
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
name: Create Release And Upload assets
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- name: Install cross-compilers
run: sudo apt-get update && sudo apt-get -y install gcc-x86-64-linux-gnu gcc-aarch64-linux-gnu gcc-arm-linux-gnueabi gcc-powerpc64le-linux-gnu gcc-s390x-linux-gnu
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18.14'
- name: Build Web
run: |
cd frontend && npm install && npm run build:dev
env:
NODE_OPTIONS: --max-old-space-size=8192
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.20.x'
- name: Build Release
uses: goreleaser/goreleaser-action@v4
with:
args: release --skip-publish --clean
- name: Upload Assets
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
draft: true
files: |
dist/*.tar.gz
dist/checksums.txt
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Setup OSSUTIL
uses: yizhoumo/setup-ossutil@v1
with:
endpoint: ${{ secrets.OSS_ENDPOINT }}
access-key-id: ${{ secrets.OSS_ACCESS_KEY_ID }}
access-key-secret: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
ossutil-version: '1.7.14'
- name: Upload Assets to OSS
- run: ossutil cp -r dist/ oss://resource-fit2cloud-com/1panel/package/stable/${{ github.ref_name }}/release/ --include "*.tar.gz" --include "checksums.txt" --only-current-dir
+16
View File
@@ -0,0 +1,16 @@
name: sync2gitee
on: [push]
jobs:
repo-sync:
runs-on: ubuntu-latest
steps:
- name: Mirror the Github organization repos to Gitee.
uses: Yikun/hub-mirror-action@master
with:
src: 'github/1Panel-dev'
dst: 'gitee/fit2cloud-xlab'
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
static_list: "1Panel"
force_update: true
+9 -1
View File
@@ -22,5 +22,13 @@ cmd/server/__debug_bin
cmd/server/web/assets
cmd/server/web/monacoeditorwork
cmd/server/web/index.html
cmd/server/web/favicon.png
frontend/auto-imports.d.ts
frontend/components.d.ts
.history/
dist/
1pctl
1panel.service
install.sh
cmd/server/web/.DS_Store
cmd/server/.DS_Store
+68
View File
@@ -0,0 +1,68 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# - export NODE_OPTIONS="--max-old-space-size=8192"
# - make build_web
- chmod +x ./script.sh
- ./script.sh
- sed -i 's@ORIGINAL_VERSION=.*@ORIGINAL_VERSION=v{{ .Version }}@g' 1pctl
- go mod tidy
builds:
- main: ./cmd/server/main.go
binary: 1panel
flags:
- -trimpath
ldflags:
- -w -s
- --extldflags "-static -fpic"
tags:
- osusergo
env:
- CGO_ENABLED=1
- >-
{{- if eq .Arch "amd64"}}CC=x86_64-linux-gnu-gcc{{- end }}
{{- if eq .Arch "arm64"}}CC=aarch64-linux-gnu-gcc{{- end }}
{{- if eq .Arch "arm"}}CC=arm-linux-gnueabi-gcc{{- end }}
{{- if eq .Arch "loong64"}}CC=loongarch64-linux-gnu-gcc{{- end }}
{{- if eq .Arch "ppc64le"}}CC=powerpc64le-linux-gnu-gcc{{- end }}
{{- if eq .Arch "s390x"}}CC=s390x-linux-gnu-gcc{{- end }}
goos:
- linux
goarm:
- 7
goarch:
- amd64
- arm64
- arm
- ppc64le
- s390x
archives:
- format: tar.gz
name_template: "1panel-v{{ .Version }}-{{ .Os }}-{{ .Arch }}{{- if .Arm }}v{{ .Arm }}{{ end }}"
wrap_in_directory: true
files:
- 1pctl
- 1panel.service
- install.sh
- README.md
- LICENSE
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
release:
draft: true
mode: append
extra_files:
- glob: dist/*.tar.gz
- glob: dist/checksums.txt
name_template: "Release {{.Tag}}"
# The lines beneath this are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
+3
View File
@@ -0,0 +1,3 @@
{
"ansible.python.interpreterPath": "/opt/homebrew/bin/python3"
}
+34
View File
@@ -0,0 +1,34 @@
FROM node:18.14 as build_web
ARG TARGETARCH
ARG NPM_REGISTRY="https://registry.npmmirror.com"
ENV NODE_OPTIONS="--max-old-space-size=4096"
WORKDIR /data
RUN set -ex \
&& npm config set registry ${NPM_REGISTRY}
ADD . /data
RUN set -ex \
&& cd /data/frontend \
&& npm install
RUN set -ex \
&& cd /data/frontend \
&& npm run build:dev
FROM golang:1.20
ARG TARGETARCH
ARG GOPROXY="https://goproxy.cn,direct"
COPY --from=build_web /data /data
WORKDIR /data
RUN set -ex \
&& go env -w GOPROXY=${GOPROXY} \
&& go install github.com/goreleaser/goreleaser@latest \
&& goreleaser build --single-target --snapshot --clean
CMD ["/bin/bash"]
+19 -6
View File
@@ -10,16 +10,29 @@ WEB_PATH=$(BASE_PAH)/frontend
SERVER_PATH=$(BASE_PAH)/backend
MAIN= $(BASE_PAH)/cmd/server/main.go
APP_NAME=1panel
ASSERT_PATH= $(BASE_PAH)/cmd/server/web/assets
build_web:
cd $(WEB_PATH) && npm install && npm run build:dev
clean_assets:
rm -rf $(ASSERT_PATH)
build_bin:
upx_bin:
upx $(BUILD_PATH)/$(APP_NAME)
build_frontend:
cd $(WEB_PATH) && npm install && npm run build:pro
build_backend_on_linux:
cd $(SERVER_PATH) \
&& CGO_ENABLED=1 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w --extldflags "-static -fpic"' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
&& CGO_ENABLED=1 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w --extldflags "-static -fpic"' -tags 'osusergo,netgo' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
build_linux_on_mac:
build_backend_on_darwin:
cd $(SERVER_PATH) \
&& CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CXX=x86_64-linux-musl-g++ $(GOBUILD) -trimpath -ldflags '-s -w --extldflags "-static -fpic"' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
build_all: build_web build_bin
build_backend_on_archlinux:
cd $(SERVER_PATH) \
&& CGO_ENABLED=1 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w --extldflags "-fpic"' -tags osusergo -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
build_all: build_frontend build_backend_on_linux
build_on_local: clean_assets build_frontend build_backend_on_darwin upx_bin
+11
View File
@@ -0,0 +1,11 @@
reviewers:
- zhengkunwang223
- ssongliu
- wanghe-fit2cloud
- wangdan-fit2cloud
approvers:
- zhengkunwang223
- ssongliu
- wanghe-fit2cloud
- wangdan-fit2cloud
+22 -15
View File
@@ -1,3 +1,4 @@
[README_EN.md](README_EN.md)
<p align="center"><a href="https://1panel.cn"><img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
<p align="center"><b>现代化、开源的 Linux 服务器运维管理面板</b></p>
<p align="center">
@@ -5,20 +6,21 @@
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel.svg?type=shield" alt="FOSSA Status"></a>
</p>
------------------------------
1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。1Panel 的功能和优势包括:
- **快速建站**:深度集成 Wordpress 和 Halo,域名绑定、SSL 证书配置等一键搞定;
- **高效管理**:通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理及常用应用软件管理;
- **安全可靠**:最小漏洞暴露面,提供防火墙和安全审计等功能;
- **一键备份**:支持一键备份和恢复,备份数据云端存储,永不丢失。
- **快速建站**:深度集成 Wordpress 和 [Halo](https://github.com/halo-dev/halo/),域名绑定、SSL 证书配置等一键搞定;
- **高效管理**:通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理等;
- **安全可靠**:基于容器来管理和部署应用,最小漏洞暴露面,提供防火墙和日志审计等功能;
- **一键备份**:支持一键备份和恢复,备份数据到各类云端存储,永不丢失。
## UI 展示
![UI展示](https://1panel.oss-cn-hangzhou.aliyuncs.com/img/overview.png)
![UI展示](https://resource.fit2cloud.com/1panel/img/overview.png)
## 快速开始
@@ -30,7 +32,7 @@
**一键安装**
以 root 用户执行如下命令一键安装 1Panel:
执行如下命令一键安装 1Panel:
```sh
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
@@ -39,26 +41,31 @@ curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_
**学习资料**
- [在线文档](https://1panel.cn/docs/)
- [入门视频](https://1panel.cn/video.html)
- [教学视频](https://space.bilibili.com/510493147/channel/collectiondetail?sid=1199760)
- [社区论坛](https://bbs.fit2cloud.com/c/1p/7)
## 社区
**加入微信交流群**
如果您在使用过程中有任何疑问或对建议,欢迎提交 GitHub Issue 或加入到我们微信交流群进行交流沟通。
**微信交流群**
<img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/wechat-group.jpg" width="156" height="156"/>
<img src="https://1panel.cn/img/wechat-group.jpg" width="156" height="156"/>
## 安全说明
如果您在使用过程中发现任何安全问题,请通过以下方式直接联系我们:
- 邮箱:support@fit2cloud.com
- 邮箱:support@fit2cloud.com
- 电话:400-052-0755
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=1Panel-dev/1Panel&type=Date)](https://star-history.com/#1Panel-dev/1Panel&Date)
## FOSSA Status
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_large)
## License
Copyright (c) 2014-2023 飞致云 FIT2CLOUD, All rights reserved.
Copyright (c) 2014-2023 [FIT2CLOUD 飞致云](https://fit2cloud.com/), All rights reserved.
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+72
View File
@@ -0,0 +1,72 @@
[中文 README.md](README.md)
<p align="center"><a href="https://1panel.cn"><img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
<p align="center"><b>Modern and Open-Source Linux Server Operation and Management Panel</b></p>
<p align="center">
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel" alt="License: GPL v3"></a>
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
</p>
------------------------------
1Panel is a modern and Open-Source linux server operation and management panel, the functions and advantages of 1Panel include:
- **Quick website building**: Deeply integrated with Wordpress and [Halo](https://github.com/halo-dev/halo/), with one-click solutions for domain name binding, SSL certificate configuration, and more;
- **Efficient management**: Easily manage Linux servers through the web interface, including application management, host monitoring, file management, database management, container management, and more;
- **Secure and reliable**: Minimal vulnerability exposure, with firewall and security audit functions provided;
- **One-click backup**: Support for one-click backup and restore, with backup data stored in the cloud and never lost.
## UI Display
![UI Display](https://resource.fit2cloud.com/1panel/img/overview_en.png)
## Quick Start
**Online Demo**
- Address: <https://demo.1panel.cn/>
- Username: demo
- Password: 1panel
**One-Click Installation**
Execute the following command to install 1Panel with one click:
```sh
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
```
**Learning Materials**
- [Online Documentation](https://1panel.cn/docs/)
- [Teaching Videos](https://space.bilibili.com/510493147/channel/collectiondetail?sid=1199760)
## Community
If you have any questions or suggestions, please submit a GitHub Issue or join our WeChat group for communication.
**WeChat Group**
<img src="https://1panel.cn/img/wechat-group.jpg" width="156" height="156"/>
## Security Information
If you discover any security issues, please contact us through:
- Email: support@fit2cloud.com
- Phone: 400-052-0755
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=1Panel-dev/1Panel&type=Date)](https://star-history.com/#1Panel-dev/1Panel&Date)
## License
Copyright (c) 2014-2023 [FIT2CLOUD 飞致云](https://fit2cloud.com/), All rights reserved.
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
<https://www.gnu.org/licenses/gpl-3.0.html>
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+21
View File
@@ -0,0 +1,21 @@
# 安全说明
如果您发现安全问题,请直接联系我们:
- wanghe@fit2cloud.com
- zhengkun@fit2cloud.com
- support@fit2cloud.com
- 400-052-0755
感谢您的支持!
# Security Policy
All security bugs should be reported to the contact as below:
- wanghe@fit2cloud.com
- zhengkun@fit2cloud.com
- support@fit2cloud.com
- 400-052-0755
Thanks for your support!
+60 -9
View File
@@ -5,6 +5,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/i18n"
"github.com/gin-gonic/gin"
)
@@ -38,13 +39,24 @@ func (b *BaseApi) SearchApp(c *gin.Context) {
// @Router /apps/sync [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"应用商店同步","formatEN":"App store synchronization"}
func (b *BaseApi) SyncApp(c *gin.Context) {
global.LOG.Infof("sync app list start ...")
if err := appService.SyncAppList(); err != nil {
global.LOG.Errorf("sync app list error [%s]", err.Error())
go appService.SyncAppListFromLocal()
res, err := appService.GetAppUpdate()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
global.LOG.Infof("sync app list success!")
if !res.CanUpdate {
helper.SuccessWithMsg(c, i18n.GetMsgByKey("AppStoreIsUpToDate"))
return
}
go func() {
global.LOG.Infof("sync app list start ...")
if err := appService.SyncAppListFromRemote(); err != nil {
global.LOG.Errorf("sync app list error [%s]", err.Error())
} else {
global.LOG.Infof("sync app list success!")
}
}()
helper.SuccessWithData(c, "")
}
@@ -71,14 +83,15 @@ func (b *BaseApi) GetApp(c *gin.Context) {
}
// @Tags App
// @Summary Search app detail by id
// @Description 通过 id 获取应用详情
// @Summary Search app detail by appid
// @Description 通过 appid 获取应用详情
// @Accept json
// @Param appId path integer true "app id"
// @Param version path string true "app 版本"
// @Param version path string true "app 类型"
// @Success 200 {object} response.AppDetailDTO
// @Security ApiKeyAuth
// @Router /apps/detail/:appId/:version [get]
// @Router /apps/detail/:appId/:version/:type [get]
func (b *BaseApi) GetAppDetail(c *gin.Context) {
appId, err := helper.GetIntParamByKey(c, "appId")
if err != nil {
@@ -86,7 +99,30 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
return
}
version := c.Param("version")
appDetailDTO, err := appService.GetAppDetail(appId, version)
appType := c.Param("type")
appDetailDTO, err := appService.GetAppDetail(appId, version, appType)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, appDetailDTO)
}
// @Tags App
// @Summary Get app detail by id
// @Description 通过 id 获取应用详情
// @Accept json
// @Param appId path integer true "id"
// @Success 200 {object} response.AppDetailDTO
// @Security ApiKeyAuth
// @Router /apps/details/:id [get]
func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
appDetailID, err := helper.GetIntParamByKey(c, "id")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
appDetailDTO, err := appService.GetAppDetailByID(appDetailID)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -102,7 +138,7 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
// @Success 200 {object} model.AppInstall
// @Security ApiKeyAuth
// @Router /apps/install [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"name","input_value":"name","isList":false,"db":"app_installs","output_colume":"app_id","output_value":"appId"},{"info":"appId","isList":false,"db":"apps","output_colume":"key","output_value":"appKey"}],"formatZH":"安装应用 [appKey]-[name]","formatEN":"Install app [appKey]-[name]"}
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[{"input_column":"name","input_value":"name","isList":false,"db":"app_installs","output_column":"app_id","output_value":"appId"},{"info":"appId","isList":false,"db":"apps","output_column":"key","output_value":"appKey"}],"formatZH":"安装应用 [appKey]-[name]","formatEN":"Install app [appKey]-[name]"}
func (b *BaseApi) InstallApp(c *gin.Context) {
var req request.AppInstallCreate
if err := c.ShouldBindJSON(&req); err != nil {
@@ -128,3 +164,18 @@ func (b *BaseApi) GetAppTags(c *gin.Context) {
}
helper.SuccessWithData(c, tags)
}
// @Tags App
// @Summary Get app list update
// @Description 获取应用更新版本
// @Success 200
// @Security ApiKeyAuth
// @Router /apps/checkupdate [get]
func (b *BaseApi) GetAppListUpdate(c *gin.Context) {
res, err := appService.GetAppUpdate()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, res)
}
+8 -8
View File
@@ -93,24 +93,24 @@ func (b *BaseApi) LoadPort(c *gin.Context) {
// @Tags App
// @Summary Search app password by key
// @Description 获取应用密码
// @Description 获取应用连接信息
// @Accept json
// @Param key path string true "request"
// @Success 200 {string} password
// @Success 200 {string} response.DatabaseConn
// @Security ApiKeyAuth
// @Router /apps/installed/loadpassword/:key [get]
func (b *BaseApi) LoadPassword(c *gin.Context) {
// @Router /apps/installed/conninfo/:key [get]
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
key, ok := c.Params.Get("key")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
return
}
password, err := appInstallService.LoadPassword(key)
conn, err := appInstallService.LoadConnInfo(key)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, password)
helper.SuccessWithData(c, conn)
}
// @Tags App
@@ -144,7 +144,7 @@ func (b *BaseApi) DeleteCheck(c *gin.Context) {
// @Router /apps/installed/sync [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"同步已安装应用列表","formatEN":"Sync the list of installed apps"}
func (b *BaseApi) SyncInstalled(c *gin.Context) {
if err := appInstallService.SyncAll(); err != nil {
if err := appInstallService.SyncAll(false); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@@ -159,7 +159,7 @@ func (b *BaseApi) SyncInstalled(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /apps/installed/op [post]
// @x-panel-log {"bodyKeys":["installId","operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"installId","isList":false,"db":"app_installs","output_colume":"app_id","output_value":"appId"},{"input_colume":"id","input_value":"installId","isList":false,"db":"app_installs","output_colume":"name","output_value":"appName"},{"input_colume":"id","input_value":"appId","isList":false,"db":"apps","output_colume":"key","output_value":"appKey"}],"formatZH":"[appKey] 应用 [appName] [operate]","formatEN":"[appKey] App [appName] [operate]"}
// @x-panel-log {"bodyKeys":["installId","operate"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"installId","isList":false,"db":"app_installs","output_column":"app_id","output_value":"appId"},{"input_column":"id","input_value":"installId","isList":false,"db":"app_installs","output_column":"name","output_value":"appName"},{"input_column":"id","input_value":"appId","isList":false,"db":"apps","output_column":"key","output_value":"appKey"}],"formatZH":"[operate] 应用 [appKey][appName]","formatEN":"[operate] App [appKey][appName]"}
func (b *BaseApi) OperateInstalled(c *gin.Context) {
var req request.AppInstalledOperate
if err := c.ShouldBindJSON(&req); err != nil {
+19 -66
View File
@@ -1,8 +1,6 @@
package v1
import (
"errors"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model"
@@ -28,9 +26,11 @@ func (b *BaseApi) Login(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := captcha.VerifyCode(req.CaptchaID, req.Captcha); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
if req.AuthMethod != "jwt" && !req.IgnoreCaptcha {
if err := captcha.VerifyCode(req.CaptchaID, req.Captcha); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
}
user, err := authService.Login(c, req)
@@ -100,71 +100,24 @@ func (b *BaseApi) Captcha(c *gin.Context) {
// @Summary Load safety status
// @Description 获取系统安全登录状态
// @Success 200
// @Failure 402
// @Router /auth/status [get]
func (b *BaseApi) GetSafetyStatus(c *gin.Context) {
if err := authService.SafetyStatus(c); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, err)
return
}
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) SafeEntrance(c *gin.Context) {
code, exist := c.Params.Get("code")
if !exist {
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
return
}
ok, err := authService.VerifyCode(code)
// @Router /auth/issafety [get]
func (b *BaseApi) CheckIsSafety(c *gin.Context) {
code := c.DefaultQuery("code", "")
status, err := authService.CheckIsSafety(code)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
return
}
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
return
}
if err := authService.SafeEntrance(c, code); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Auth
// @Summary Check is First login
// @Description 判断是否为首次登录
// @Success 200
// @Router /auth/status [get]
func (b *BaseApi) CheckIsFirstLogin(c *gin.Context) {
helper.SuccessWithData(c, authService.CheckIsFirst())
}
// @Tags Auth
// @Summary Init user
// @Description 初始化用户
// @Accept json
// @Param request body dto.InitUser true "request"
// @Success 200
// @Router /auth/init [post]
func (b *BaseApi) InitUserInfo(c *gin.Context) {
var req dto.InitUser
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := authService.InitUser(c, req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
helper.SuccessWithData(c, status)
}
// @Tags Auth
// @Summary Check System isDemo
// @Description 判断是否为demo环境
// @Success 200
// @Router /auth/demo [get]
func (b *BaseApi) CheckIsDemo(c *gin.Context) {
helper.SuccessWithData(c, global.CONF.System.IsDemo)
}
func saveLoginLogs(c *gin.Context, err error) {
+68 -5
View File
@@ -1,6 +1,10 @@
package v1
import (
"encoding/base64"
"fmt"
"path"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
@@ -27,6 +31,23 @@ func (b *BaseApi) CreateBackup(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Credential) != 0 {
credential, err := base64.StdEncoding.DecodeString(req.Credential)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Credential = string(credential)
}
if len(req.AccessKey) != 0 {
accessKey, err := base64.StdEncoding.DecodeString(req.AccessKey)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.AccessKey = string(accessKey)
}
if err := backupService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -52,6 +73,23 @@ func (b *BaseApi) ListBuckets(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Credential) != 0 {
credential, err := base64.StdEncoding.DecodeString(req.Credential)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Credential = string(credential)
}
if len(req.AccessKey) != 0 {
accessKey, err := base64.StdEncoding.DecodeString(req.AccessKey)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.AccessKey = string(accessKey)
}
buckets, err := backupService.GetBuckets(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -68,9 +106,9 @@ func (b *BaseApi) ListBuckets(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"backup_accounts","output_colume":"type","output_value":"types"}],"formatZH":"删除备份账号 [types]","formatEN":"delete backup account [types]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":true,"db":"backup_accounts","output_column":"type","output_value":"types"}],"formatZH":"删除备份账号 [types]","formatEN":"delete backup account [types]"}
func (b *BaseApi) DeleteBackup(c *gin.Context) {
var req dto.BatchDeleteReq
var req dto.OperateByID
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@@ -80,7 +118,7 @@ func (b *BaseApi) DeleteBackup(c *gin.Context) {
return
}
if err := backupService.BatchDelete(req.Ids); err != nil {
if err := backupService.Delete(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@@ -139,7 +177,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
c.File(filePath)
helper.SuccessWithData(c, filePath)
}
// @Tags Backup Account
@@ -150,7 +188,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/record/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"backup_records","output_colume":"file_name","output_value":"files"}],"formatZH":"删除备份记录 [files]","formatEN":"delete backup records [files]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"backup_records","output_column":"file_name","output_value":"files"}],"formatZH":"删除备份记录 [files]","formatEN":"delete backup records [files]"}
func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
var req dto.BatchDeleteReq
if err := c.ShouldBindJSON(&req); err != nil {
@@ -188,6 +226,23 @@ func (b *BaseApi) UpdateBackup(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Credential) != 0 {
credential, err := base64.StdEncoding.DecodeString(req.Credential)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Credential = string(credential)
}
if len(req.AccessKey) != 0 {
accessKey, err := base64.StdEncoding.DecodeString(req.AccessKey)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.AccessKey = string(accessKey)
}
if err := backupService.Update(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -303,6 +358,14 @@ func (b *BaseApi) Recover(c *gin.Context) {
return
}
if req.Source != "LOCAL" {
downloadPath, err := backupService.DownloadRecord(dto.DownloadRecord{Source: req.Source, FileDir: path.Dir(req.File), FileName: path.Base(req.File)})
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, fmt.Errorf("download file failed, err: %v", err))
return
}
req.File = downloadPath
}
switch req.Type {
case "mysql":
if err := backupService.MysqlRecover(req); err != nil {
+1 -1
View File
@@ -85,7 +85,7 @@ func (b *BaseApi) ListCommand(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/command/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"commands","output_colume":"name","output_value":"names"}],"formatZH":"删除快捷命令 [names]","formatEN":"delete quick command [names]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"commands","output_column":"name","output_value":"names"}],"formatZH":"删除快捷命令 [names]","formatEN":"delete quick command [names]"}
func (b *BaseApi) DeleteCommand(c *gin.Context) {
var req dto.BatchDeleteReq
if err := c.ShouldBindJSON(&req); err != nil {
+2 -2
View File
@@ -87,7 +87,7 @@ func (b *BaseApi) ListComposeTemplate(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/template/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"compose_templates","output_colume":"name","output_value":"names"}],"formatZH":"删除 compose 模版 [names]","formatEN":"delete compose template [names]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"compose_templates","output_column":"name","output_value":"names"}],"formatZH":"删除 compose 模版 [names]","formatEN":"delete compose template [names]"}
func (b *BaseApi) DeleteComposeTemplate(c *gin.Context) {
var req dto.BatchDeleteReq
if err := c.ShouldBindJSON(&req); err != nil {
@@ -114,7 +114,7 @@ func (b *BaseApi) DeleteComposeTemplate(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/template/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"compose_templates","output_colume":"name","output_value":"name"}],"formatZH":"更新 compose 模版 [name]","formatEN":"update compose template information [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"compose_templates","output_column":"name","output_value":"name"}],"formatZH":"更新 compose 模版 [name]","formatEN":"update compose template information [name]"}
func (b *BaseApi) UpdateComposeTemplate(c *gin.Context) {
var req dto.ComposeTemplateUpdate
if err := c.ShouldBindJSON(&req); err != nil {
+88 -6
View File
@@ -70,6 +70,34 @@ func (b *BaseApi) SearchCompose(c *gin.Context) {
})
}
// @Tags Container Compose
// @Summary Test compose
// @Description 测试 compose 是否可用
// @Accept json
// @Param request body dto.ComposeCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/compose/test [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测 compose [name] 格式","formatEN":"check compose [name]"}
func (b *BaseApi) TestCompose(c *gin.Context) {
var req dto.ComposeCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
isOK, err := containerService.TestCompose(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, isOK)
}
// @Tags Container Compose
// @Summary Create compose
// @Description 创建容器编排
@@ -90,11 +118,12 @@ func (b *BaseApi) CreateCompose(c *gin.Context) {
return
}
if err := containerService.CreateCompose(req); err != nil {
log, err := containerService.CreateCompose(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
helper.SuccessWithData(c, log)
}
// @Tags Container Compose
@@ -150,6 +179,59 @@ func (b *BaseApi) ContainerCreate(c *gin.Context) {
helper.SuccessWithData(c, nil)
}
// @Tags Container
// @Summary Clean container
// @Description 容器清理
// @Accept json
// @Param request body dto.ContainerPrune true "request"
// @Success 200 {object} dto.ContainerPruneReport
// @Security ApiKeyAuth
// @Router /containers/prune [post]
// @x-panel-log {"bodyKeys":["pruneType"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清理容器 [pruneType]","formatEN":"clean container [pruneType]"}
func (b *BaseApi) ContainerPrune(c *gin.Context) {
var req dto.ContainerPrune
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
report, err := containerService.Prune(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, report)
}
// @Tags Container
// @Summary Clean container log
// @Description 清理容器日志
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/clean/log [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清理容器 [name] 日志","formatEN":"clean container [name] logs"}
func (b *BaseApi) CleanContainerLog(c *gin.Context) {
var req dto.OperationWithName
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := containerService.ContainerLogClean(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Container
// @Summary Operate Container
// @Description 容器操作
@@ -313,13 +395,13 @@ func (b *BaseApi) DeleteNetwork(c *gin.Context) {
// @Summary Create network
// @Description 创建容器网络
// @Accept json
// @Param request body dto.NetworkCreat true "request"
// @Param request body dto.NetworkCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/network [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器网络 name","formatEN":"create container network [name]"}
func (b *BaseApi) CreateNetwork(c *gin.Context) {
var req dto.NetworkCreat
var req dto.NetworkCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@@ -416,13 +498,13 @@ func (b *BaseApi) DeleteVolume(c *gin.Context) {
// @Summary Create volume
// @Description 创建容器存储卷
// @Accept json
// @Param request body dto.VolumeCreat true "request"
// @Param request body dto.VolumeCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/volume [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器存储卷 [name]","formatEN":"create container volume [name]"}
func (b *BaseApi) CreateVolume(c *gin.Context) {
var req dto.VolumeCreat
var req dto.VolumeCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
+37 -11
View File
@@ -7,6 +7,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/common"
"github.com/gin-gonic/gin"
)
@@ -77,8 +78,9 @@ func (b *BaseApi) SearchJobRecords(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.StartTime = req.StartTime.Add(8 * time.Hour)
req.EndTime = req.EndTime.Add(8 * time.Hour)
loc, _ := time.LoadLocation(common.LoadTimeZone())
req.StartTime = req.StartTime.In(loc)
req.EndTime = req.EndTime.In(loc)
total, list, err := cronjobService.SearchRecords(req)
if err != nil {
@@ -92,17 +94,41 @@ func (b *BaseApi) SearchJobRecords(c *gin.Context) {
})
}
// @Tags Cronjob
// @Summary Clean job records
// @Description 清空计划任务记录
// @Accept json
// @Param request body dto.CronjobClean true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /cronjobs/records/clean [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"清空计划任务记录 [name]","formatEN":"clean cronjob [name] records"}
func (b *BaseApi) CleanRecord(c *gin.Context) {
var req dto.CronjobClean
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := cronjobService.CleanRecord(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Cronjob
// @Summary Delete cronjob
// @Description 删除计划任务
// @Accept json
// @Param request body dto.BatchDeleteReq true "request"
// @Param request body dto.CronjobBatchDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /cronjobs/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"cronjobs","output_colume":"name","output_value":"names"}],"formatZH":"删除计划任务 [names]","formatEN":"delete cronjob [names]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"cronjobs","output_column":"name","output_value":"names"}],"formatZH":"删除计划任务 [names]","formatEN":"delete cronjob [names]"}
func (b *BaseApi) DeleteCronjob(c *gin.Context) {
var req dto.BatchDeleteReq
var req dto.CronjobBatchDelete
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@@ -112,7 +138,7 @@ func (b *BaseApi) DeleteCronjob(c *gin.Context) {
return
}
if err := cronjobService.Delete(req.Ids); err != nil {
if err := cronjobService.Delete(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@@ -127,7 +153,7 @@ func (b *BaseApi) DeleteCronjob(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /cronjobs/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"cronjobs","output_colume":"name","output_value":"name"}],"formatZH":"更新计划任务 [name]","formatEN":"update cronjob [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"更新计划任务 [name]","formatEN":"update cronjob [name]"}
func (b *BaseApi) UpdateCronjob(c *gin.Context) {
var req dto.CronjobUpdate
if err := c.ShouldBindJSON(&req); err != nil {
@@ -154,7 +180,7 @@ func (b *BaseApi) UpdateCronjob(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /cronjobs/status [post]
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"cronjobs","output_colume":"name","output_value":"name"}],"formatZH":"修改计划任务 [name] 状态为 [status]","formatEN":"change the status of cronjob [name] to [status]."}
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"修改计划任务 [name] 状态为 [status]","formatEN":"change the status of cronjob [name] to [status]."}
func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
var req dto.CronjobUpdateStatus
if err := c.ShouldBindJSON(&req); err != nil {
@@ -181,7 +207,7 @@ func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /cronjobs/download [post]
// @x-panel-log {"bodyKeys":["recordID"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"recordID","isList":false,"db":"job_records","output_colume":"file","output_value":"file"}],"formatZH":"下载计划任务记录 [file]","formatEN":"download the cronjob record [file]"}
// @x-panel-log {"bodyKeys":["recordID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"recordID","isList":false,"db":"job_records","output_column":"file","output_value":"file"}],"formatZH":"下载计划任务记录 [file]","formatEN":"download the cronjob record [file]"}
func (b *BaseApi) TargetDownload(c *gin.Context) {
var req dto.CronjobDownload
if err := c.ShouldBindJSON(&req); err != nil {
@@ -198,7 +224,7 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
c.File(filePath)
helper.SuccessWithData(c, filePath)
}
// @Tags Cronjob
@@ -209,7 +235,7 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /cronjobs/handle [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"cronjobs","output_colume":"name","output_value":"name"}],"formatZH":"手动执行计划任务 [name]","formatEN":"manually execute the cronjob [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"手动执行计划任务 [name]","formatEN":"manually execute the cronjob [name]"}
func (b *BaseApi) HandleOnce(c *gin.Context) {
var req dto.OperateByID
if err := c.ShouldBindJSON(&req); err != nil {
+23 -4
View File
@@ -2,6 +2,7 @@ package v1
import (
"context"
"encoding/base64"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
@@ -29,6 +30,15 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Password) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = string(password)
}
if _, err := mysqlService.Create(context.Background(), req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -44,7 +54,7 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/description/update [post]
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"mysql 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the mysql database [name] is modified => [description]"}
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"mysql 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the mysql database [name] is modified => [description]"}
func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
var req dto.UpdateDescription
if err := c.ShouldBindJSON(&req); err != nil {
@@ -70,7 +80,7 @@ func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/change/password [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 密码","formatEN":"Update database [name] password"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 密码","formatEN":"Update database [name] password"}
func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
var req dto.ChangeDBInfo
if err := c.ShouldBindJSON(&req); err != nil {
@@ -81,6 +91,15 @@ func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Value) != 0 {
value, err := base64.StdEncoding.DecodeString(req.Value)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Value = string(value)
}
if err := mysqlService.ChangePassword(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -96,7 +115,7 @@ func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/change/access [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 访问权限","formatEN":"Update database [name] access"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 访问权限","formatEN":"Update database [name] access"}
func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
var req dto.ChangeDBInfo
if err := c.ShouldBindJSON(&req); err != nil {
@@ -245,7 +264,7 @@ func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"删除 mysql 数据库 [name]","formatEN":"delete mysql database [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"删除 mysql 数据库 [name]","formatEN":"delete mysql database [name]"}
func (b *BaseApi) DeleteMysql(c *gin.Context) {
var req dto.MysqlDBDelete
if err := c.ShouldBindJSON(&req); err != nil {
+10
View File
@@ -2,6 +2,7 @@ package v1
import (
"bufio"
"encoding/base64"
"fmt"
"os"
@@ -106,6 +107,15 @@ func (b *BaseApi) ChangeRedisPassword(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if len(req.Value) != 0 {
value, err := base64.StdEncoding.DecodeString(req.Value)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Value = string(value)
}
if err := redisService.ChangePassword(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
+28 -5
View File
@@ -1,7 +1,6 @@
package v1
import (
"io/ioutil"
"os"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
@@ -35,7 +34,7 @@ func (b *BaseApi) LoadDaemonJsonFile(c *gin.Context) {
helper.SuccessWithData(c, "daemon.json is not find in path")
return
}
content, err := ioutil.ReadFile(constant.DaemonJsonPath)
content, err := os.ReadFile(constant.DaemonJsonPath)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -59,13 +58,13 @@ func (b *BaseApi) LoadDaemonJson(c *gin.Context) {
// @Summary Update docker daemon.json
// @Description 修改 docker 配置信息
// @Accept json
// @Param request body dto.DaemonJsonConf true "request"
// @Param request body dto.SettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/daemonjson/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 配置","formatEN":"Updated the docker daemon.json configuration"}
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 配置 [key]=>[value]","formatEN":"Updated the docker daemon.json configuration [key]=>[value]"}
func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
var req dto.DaemonJsonConf
var req dto.SettingUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@@ -79,6 +78,30 @@ func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
helper.SuccessWithData(c, nil)
}
// @Tags Container Docker
// @Summary Update docker daemon.json log option
// @Description 修改 docker 日志配置
// @Accept json
// @Param request body dto.LogOption true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/daemonjson/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 日志配置","formatEN":"Updated the docker daemon.json log option"}
func (b *BaseApi) UpdateLogOption(c *gin.Context) {
var req dto.LogOption
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := dockerService.UpdateLogOption(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Container Docker
// @Summary Update docker daemon.json by upload file
// @Description 上传替换 docker 配置文件
+29 -26
View File
@@ -9,41 +9,44 @@ type ApiGroup struct {
var ApiGroupApp = new(ApiGroup)
var (
authService = service.ServiceGroupApp.AuthService
dashboardService = service.ServiceGroupApp.DashboardService
authService = service.NewIAuthService()
dashboardService = service.NewIDashboardService()
appService = service.NewIAppService()
appInstallService = service.ServiceGroupApp.AppInstallService
appInstallService = service.NewIAppInstalledService()
containerService = service.ServiceGroupApp.ContainerService
composeTemplateService = service.ServiceGroupApp.ComposeTemplateService
imageRepoService = service.ServiceGroupApp.ImageRepoService
imageService = service.ServiceGroupApp.ImageService
dockerService = service.ServiceGroupApp.DockerService
containerService = service.NewIContainerService()
composeTemplateService = service.NewIComposeTemplateService()
imageRepoService = service.NewIImageRepoService()
imageService = service.NewIImageService()
dockerService = service.NewIDockerService()
mysqlService = service.ServiceGroupApp.MysqlService
redisService = service.ServiceGroupApp.RedisService
mysqlService = service.NewIMysqlService()
redisService = service.NewIRedisService()
cronjobService = service.ServiceGroupApp.CronjobService
cronjobService = service.NewICronjobService()
hostService = service.ServiceGroupApp.HostService
groupService = service.ServiceGroupApp.GroupService
fileService = service.ServiceGroupApp.FileService
hostService = service.NewIHostService()
groupService = service.NewIGroupService()
fileService = service.NewIFileService()
sshService = service.NewISSHService()
firewallService = service.NewIFirewallService()
settingService = service.ServiceGroupApp.SettingService
backupService = service.ServiceGroupApp.BackupService
settingService = service.NewISettingService()
backupService = service.NewIBackupService()
commandService = service.ServiceGroupApp.CommandService
commandService = service.NewICommandService()
websiteGroupService = service.ServiceGroupApp.WebsiteGroupService
websiteService = service.ServiceGroupApp.WebsiteService
websiteDnsAccountService = service.ServiceGroupApp.WebsiteDnsAccountService
websiteSSLService = service.ServiceGroupApp.WebsiteSSLService
websiteAcmeAccountService = service.ServiceGroupApp.WebsiteAcmeAccountService
websiteService = service.NewIWebsiteService()
websiteDnsAccountService = service.NewIWebsiteDnsAccountService()
websiteSSLService = service.NewIWebsiteSSLService()
websiteAcmeAccountService = service.NewIWebsiteAcmeAccountService()
nginxService = service.ServiceGroupApp.NginxService
nginxService = service.NewINginxService()
logService = service.ServiceGroupApp.LogService
snapshotService = service.ServiceGroupApp.SnapshotService
upgradeService = service.ServiceGroupApp.UpgradeService
logService = service.NewILogService()
snapshotService = service.NewISnapshotService()
upgradeService = service.NewIUpgradeService()
runtimeService = service.NewRuntimeService()
)
+247 -11
View File
@@ -3,6 +3,15 @@ package v1
import (
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
@@ -10,14 +19,10 @@ import (
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/files"
websocket2 "github.com/1Panel-dev/1Panel/backend/utils/websocket"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
)
// @Tags File
@@ -182,7 +187,29 @@ func (b *BaseApi) ChangeFileMode(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
helper.SuccessWithOutData(c)
}
// @Tags File
// @Summary Change file owner
// @Description 修改文件用户/组
// @Accept json
// @Param request body request.FileRoleUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/owner [post]
// @x-panel-log {"bodyKeys":["path","user","group"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改用户/组 [paths] => [user]/[group]","formatEN":"Change owner [paths] => [user]/[group]"}
func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
var req request.FileRoleUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := fileService.ChangeOwner(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags File
@@ -428,17 +455,115 @@ func (b *BaseApi) MoveFile(c *gin.Context) {
// @Router /files/download [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
func (b *BaseApi) Download(c *gin.Context) {
var req request.FileDownload
filePath := c.Query("path")
file, err := os.Open(filePath)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
}
info, _ := file.Stat()
c.Header("Content-Length", strconv.FormatInt(info.Size(), 10))
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(info.Name()))
http.ServeContent(c.Writer, c.Request, info.Name(), info.ModTime(), file)
}
// @Tags File
// @Summary Chunk Download file
// @Description 分片下载下载文件
// @Accept json
// @Param request body request.FileDownload true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/chunkdownload [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
var req request.FileChunkDownload
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
filePath, err := fileService.FileDownload(req)
fileOp := files.NewFileOp()
if !fileOp.Stat(req.Path) {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrPathNotFound, nil)
return
}
filePath := req.Path
fstFile, err := fileOp.OpenFile(filePath)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
c.File(filePath)
info, err := fstFile.Stat()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
if info.IsDir() {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrFileDownloadDir, err)
return
}
c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", req.Name))
c.Writer.Header().Set("Content-Type", "application/octet-stream")
c.Writer.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
c.Writer.Header().Set("Accept-Ranges", "bytes")
if c.Request.Header.Get("Range") != "" {
rangeHeader := c.Request.Header.Get("Range")
rangeArr := strings.Split(rangeHeader, "=")[1]
rangeParts := strings.Split(rangeArr, "-")
startPos, _ := strconv.ParseInt(rangeParts[0], 10, 64)
var endPos int64
if rangeParts[1] == "" {
endPos = info.Size() - 1
} else {
endPos, _ = strconv.ParseInt(rangeParts[1], 10, 64)
}
c.Writer.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", startPos, endPos, info.Size()))
c.Writer.WriteHeader(http.StatusPartialContent)
buffer := make([]byte, 1024*1024)
file, err := os.Open(filePath)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
defer file.Close()
file.Seek(startPos, 0)
reader := io.LimitReader(file, endPos-startPos+1)
_, err = io.CopyBuffer(c.Writer, reader, buffer)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
} else {
c.File(filePath)
}
}
// @Tags File
// @Summary Download file with path
// @Description 下载指定文件
// @Accept json
// @Param request body dto.FilePath true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/download/bypath [post]
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [path]","formatEN":"Download file [path]"}
func (b *BaseApi) DownloadFile(c *gin.Context) {
var req dto.FilePath
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
c.File(req.Path)
}
// @Tags File
@@ -472,7 +597,6 @@ func (b *BaseApi) Size(c *gin.Context) {
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Router /files/loadfile [post]
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"读取文件 [path]","formatEN":"Read file [path]"}
func (b *BaseApi) LoadFromFile(c *gin.Context) {
var req dto.FilePath
if err := c.ShouldBindJSON(&req); err != nil {
@@ -484,7 +608,7 @@ func (b *BaseApi) LoadFromFile(c *gin.Context) {
return
}
content, err := ioutil.ReadFile(req.Path)
content, err := os.ReadFile(req.Path)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -492,6 +616,118 @@ func (b *BaseApi) LoadFromFile(c *gin.Context) {
helper.SuccessWithData(c, string(content))
}
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int) error {
if _, err := os.Stat(path.Dir(dstDir)); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(path.Dir(dstDir), os.ModePerm); err != nil {
return err
}
}
targetFile, err := os.Create(filepath.Join(dstDir, fileName))
if err != nil {
return err
}
defer targetFile.Close()
for i := 0; i < chunkCount; i++ {
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", fileName, i))
chunkData, err := os.ReadFile(chunkPath)
if err != nil {
return err
}
_, err = targetFile.Write(chunkData)
if err != nil {
return err
}
}
return files.NewFileOp().DeleteDir(fileDir)
}
// @Tags File
// @Summary ChunkUpload file
// @Description 分片上传文件
// @Param file formData file true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /files/chunkupload [post]
func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
var err error
fileForm, err := c.FormFile("chunk")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
uploadFile, err := fileForm.Open()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
chunkIndex, err := strconv.Atoi(c.PostForm("chunkIndex"))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
chunkCount, err := strconv.Atoi(c.PostForm("chunkCount"))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
fileOp := files.NewFileOp()
tmpDir := path.Join(global.CONF.System.TmpDir, "upload")
if !fileOp.Stat(tmpDir) {
if err := fileOp.CreateDir(tmpDir, 0755); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
}
filename := c.PostForm("filename")
fileDir := filepath.Join(tmpDir, filename)
_ = os.MkdirAll(fileDir, 0755)
filePath := filepath.Join(fileDir, filename)
defer func() {
if err != nil {
_ = os.Remove(fileDir)
}
}()
var (
emptyFile *os.File
chunkData []byte
)
emptyFile, err = os.Create(filePath)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
defer emptyFile.Close()
chunkData, err = io.ReadAll(uploadFile)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, buserr.WithMap(constant.ErrFileUpload, map[string]interface{}{"name": filename, "detail": err.Error()}, err))
return
}
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", filename, chunkIndex))
err = os.WriteFile(chunkPath, chunkData, 0644)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, buserr.WithMap(constant.ErrFileUpload, map[string]interface{}{"name": filename, "detail": err.Error()}, err))
return
}
if chunkIndex+1 == chunkCount {
err = mergeChunks(filename, fileDir, c.PostForm("path"), chunkCount)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, buserr.WithMap(constant.ErrFileUpload, map[string]interface{}{"name": filename, "detail": err.Error()}, err))
return
}
helper.SuccessWithData(c, true)
} else {
return
}
}
var wsUpgrade = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
-111
View File
@@ -1,111 +0,0 @@
package v1
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/gin-gonic/gin"
)
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int) error {
//fileInfoList, err := ioutil.ReadDir(fileDir)
//if err != nil {
// return err
//}
targetFile, err := os.Create(filepath.Join(dstDir, fileName))
if err != nil {
return err
}
defer targetFile.Close()
for i := 0; i < chunkCount; i++ {
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", fileName, i))
chunkData, err := ioutil.ReadFile(chunkPath)
if err != nil {
return err
}
_, err = targetFile.Write(chunkData)
if err != nil {
return err
}
}
return files.NewFileOp().DeleteDir(fileDir)
}
func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
fileForm, err := c.FormFile("chunk")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
uploadFile, err := fileForm.Open()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
chunkIndex, err := strconv.Atoi(c.PostForm("chunkIndex"))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
chunkCount, err := strconv.Atoi(c.PostForm("chunkCount"))
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
fileOp := files.NewFileOp()
if err := fileOp.CreateDir("uploads", 0755); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
//fileID := uuid.New().String()
filename := c.PostForm("filename")
fileDir := filepath.Join(global.CONF.System.DataDir, "upload", filename)
_ = os.MkdirAll(fileDir, 0755)
filePath := filepath.Join(fileDir, filename)
emptyFile, err := os.Create(filePath)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
emptyFile.Close()
chunkData, err := ioutil.ReadAll(uploadFile)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", filename, chunkIndex))
err = ioutil.WriteFile(chunkPath, chunkData, 0644)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if chunkIndex+1 == chunkCount {
err = mergeChunks(filename, fileDir, c.PostForm("path"), chunkCount)
if err != nil {
fmt.Println(err.Error())
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrAppDelete, err)
return
}
helper.SuccessWithData(c, true)
} else {
return
}
}
+207
View File
@@ -0,0 +1,207 @@
package v1
import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
// @Tags Firewall
// @Summary Load firewall base info
// @Description 获取防火墙基础信息
// @Success 200 {object} dto.FirewallBaseInfo
// @Security ApiKeyAuth
// @Router /hosts/firewall/base [get]
func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) {
data, err := firewallService.LoadBaseInfo()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Firewall
// @Summary Page firewall rules
// @Description 获取防火墙规则列表分页
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Router /hosts/firewall/search [post]
func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
var req dto.RuleSearch
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, list, err := firewallService.SearchWithPage(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Firewall
// @Summary Page firewall status
// @Description 修改防火墙状态
// @Accept json
// @Param request body dto.FirewallOperation true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Router /hosts/firewall/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
func (b *BaseApi) OperateFirewall(c *gin.Context) {
var req dto.FirewallOperation
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.OperateFirewall(req.Operation); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Firewall
// @Summary Create group
// @Description 创建防火墙端口规则
// @Accept json
// @Param request body dto.PortRuleOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/firewall/port [post]
// @x-panel-log {"bodyKeys":["port","strategy"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"添加端口规则 [strategy] [port]","formatEN":"create port rules [strategy][port]"}
func (b *BaseApi) OperatePortRule(c *gin.Context) {
var req dto.PortRuleOperate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.OperatePortRule(req, true); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Firewall
// @Summary Create group
// @Description 创建防火墙 IP 规则
// @Accept json
// @Param request body dto.AddrRuleOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/firewall/ip [post]
// @x-panel-log {"bodyKeys":["strategy","address"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"添加 ip 规则 [strategy] [address]","formatEN":"create address rules [strategy][address]"}
func (b *BaseApi) OperateIPRule(c *gin.Context) {
var req dto.AddrRuleOperate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.OperateAddressRule(req, true); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Firewall
// @Summary Create group
// @Description 批量删除防火墙规则
// @Accept json
// @Param request body dto.BatchRuleOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/firewall/batch [post]
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
var req dto.BatchRuleOperate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.BatchOperateRule(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Firewall
// @Summary Create group
// @Description 更新端口防火墙规则
// @Accept json
// @Param request body dto.PortRuleUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/firewall/update/port [post]
func (b *BaseApi) UpdatePortRule(c *gin.Context) {
var req dto.PortRuleUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.UpdatePortRule(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Firewall
// @Summary Create group
// @Description 更新 ip 防火墙规则
// @Accept json
// @Param request body dto.AddrRuleUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/firewall/update/addr [post]
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
var req dto.AddrRuleUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := firewallService.UpdateAddrRule(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
+6 -6
View File
@@ -15,7 +15,7 @@ import (
// @Param request body dto.GroupCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/group [post]
// @Router /groups [post]
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"}
func (b *BaseApi) CreateGroup(c *gin.Context) {
var req dto.GroupCreate
@@ -41,8 +41,8 @@ func (b *BaseApi) CreateGroup(c *gin.Context) {
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/group/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"groups","output_colume":"name","output_value":"name"},{"input_colume":"id","input_value":"id","isList":false,"db":"groups","output_colume":"type","output_value":"type"}],"formatZH":"删除组 [type][name]","formatEN":"delete group [type][name]"}
// @Router /groups/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"name","output_value":"name"},{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"type","output_value":"type"}],"formatZH":"删除组 [type][name]","formatEN":"delete group [type][name]"}
func (b *BaseApi) DeleteGroup(c *gin.Context) {
var req dto.OperateByID
if err := c.ShouldBindJSON(&req); err != nil {
@@ -68,7 +68,7 @@ func (b *BaseApi) DeleteGroup(c *gin.Context) {
// @Param request body dto.GroupUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/group/update [post]
// @Router /groups/update [post]
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"}
func (b *BaseApi) UpdateGroup(c *gin.Context) {
var req dto.GroupUpdate
@@ -92,9 +92,9 @@ func (b *BaseApi) UpdateGroup(c *gin.Context) {
// @Description 查询系统组
// @Accept json
// @Param request body dto.GroupSearch true "request"
// @Success 200 {anrry} dto.GroupInfo
// @Success 200 {array} dto.GroupInfo
// @Security ApiKeyAuth
// @Router /hosts/group/search [post]
// @Router /groups/search [post]
func (b *BaseApi) ListGroup(c *gin.Context) {
var req dto.GroupSearch
if err := c.ShouldBindJSON(&req); err != nil {
+9
View File
@@ -83,6 +83,15 @@ func SuccessWithData(ctx *gin.Context, data interface{}) {
ctx.Abort()
}
func SuccessWithOutData(ctx *gin.Context) {
res := dto.Response{
Code: constant.CodeSuccess,
Message: "success",
}
ctx.JSON(http.StatusOK, res)
ctx.Abort()
}
func SuccessWithMsg(ctx *gin.Context, msg string) {
res := dto.Response{
Code: constant.CodeSuccess,
+42 -15
View File
@@ -1,12 +1,13 @@
package v1
import (
"encoding/base64"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/copier"
"github.com/1Panel-dev/1Panel/backend/utils/ssh"
"github.com/gin-gonic/gin"
)
@@ -29,6 +30,23 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if req.AuthMode == "password" && len(req.Password) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = string(password)
}
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.PrivateKey = string(privateKey)
}
host, err := hostService.Create(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
@@ -56,17 +74,8 @@ func (b *BaseApi) TestByInfo(c *gin.Context) {
return
}
var connInfo ssh.ConnInfo
if err := copier.Copy(&connInfo, &req); err != nil {
helper.SuccessWithData(c, false)
}
client, err := connInfo.NewClient()
if err != nil {
helper.SuccessWithData(c, false)
}
defer client.Close()
helper.SuccessWithData(c, true)
connStatus := hostService.TestByInfo(req)
helper.SuccessWithData(c, connStatus)
}
// @Tags Host
@@ -174,7 +183,7 @@ func (b *BaseApi) GetHostInfo(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"hosts","output_colume":"addr","output_value":"addrs"}],"formatZH":"删除主机 [addrs]","formatEN":"delete host [addrs]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"hosts","output_column":"addr","output_value":"addrs"}],"formatZH":"删除主机 [addrs]","formatEN":"delete host [addrs]"}
func (b *BaseApi) DeleteHost(c *gin.Context) {
var req dto.BatchDeleteReq
if err := c.ShouldBindJSON(&req); err != nil {
@@ -212,6 +221,22 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if req.AuthMode == "password" && len(req.Password) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.Password = string(password)
}
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.PrivateKey = string(privateKey)
}
upMap := make(map[string]interface{})
upMap["name"] = req.Name
@@ -220,11 +245,13 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
upMap["port"] = req.Port
upMap["user"] = req.User
upMap["auth_mode"] = req.AuthMode
upMap["remember_password"] = req.RememberPassword
if len(req.Password) != 0 {
upMap["password"] = req.Password
}
if len(req.PrivateKey) != 0 {
upMap["private_key"] = req.PrivateKey
upMap["pass_phrase"] = req.PassPhrase
}
upMap["description"] = req.Description
if err := hostService.Update(req.ID, upMap); err != nil {
@@ -241,8 +268,8 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
// @Param request body dto.ChangeHostGroup true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /hosts/update [post]
// @x-panel-log {"bodyKeys":["id","group"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"hosts","output_colume":"addr","output_value":"addr"}],"formatZH":"切换主机[addr]分组 => [group]","formatEN":"change host [addr] group => [group]"}
// @Router /hosts/update/group [post]
// @x-panel-log {"bodyKeys":["id","group"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"hosts","output_column":"addr","output_value":"addr"}],"formatZH":"切换主机[addr]分组 => [group]","formatEN":"change host [addr] group => [group]"}
func (b *BaseApi) UpdateHostGroup(c *gin.Context) {
var req dto.ChangeHostGroup
if err := c.ShouldBindJSON(&req); err != nil {
+3 -3
View File
@@ -93,7 +93,7 @@ func (b *BaseApi) ImageBuild(c *gin.Context) {
// @Success 200 {string} log
// @Security ApiKeyAuth
// @Router /containers/image/pull [post]
// @x-panel-log {"bodyKeys":["repoID","imageName"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"repoID","isList":false,"db":"image_repos","output_colume":"name","output_value":"reponame"}],"formatZH":"镜像拉取 [reponame][imageName]","formatEN":"image pull [reponame][imageName]"}
// @x-panel-log {"bodyKeys":["repoID","imageName"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"镜像拉取 [reponame][imageName]","formatEN":"image pull [reponame][imageName]"}
func (b *BaseApi) ImagePull(c *gin.Context) {
var req dto.ImagePull
if err := c.ShouldBindJSON(&req); err != nil {
@@ -122,7 +122,7 @@ func (b *BaseApi) ImagePull(c *gin.Context) {
// @Success 200 {string} log
// @Security ApiKeyAuth
// @Router /containers/image/push [post]
// @x-panel-log {"bodyKeys":["repoID","tagName","name"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"repoID","isList":false,"db":"image_repos","output_colume":"name","output_value":"reponame"}],"formatZH":"[tagName] 推送到 [reponame][name]","formatEN":"push [tagName] to [reponame][name]"}
// @x-panel-log {"bodyKeys":["repoID","tagName","name"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"[tagName] 推送到 [reponame][name]","formatEN":"push [tagName] to [reponame][name]"}
func (b *BaseApi) ImagePush(c *gin.Context) {
var req dto.ImagePush
if err := c.ShouldBindJSON(&req); err != nil {
@@ -207,7 +207,7 @@ func (b *BaseApi) ImageSave(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/image/tag [post]
// @x-panel-log {"bodyKeys":["repoID","targetName"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"repoID","isList":false,"db":"image_repos","output_colume":"name","output_value":"reponame"}],"formatZH":"tag 镜像 [reponame][targetName]","formatEN":"tag image [reponame][targetName]"}
// @x-panel-log {"bodyKeys":["repoID","targetName"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"tag 镜像 [reponame][targetName]","formatEN":"tag image [reponame][targetName]"}
func (b *BaseApi) ImageTag(c *gin.Context) {
var req dto.ImageTag
if err := c.ShouldBindJSON(&req); err != nil {
+2 -2
View File
@@ -119,7 +119,7 @@ func (b *BaseApi) CreateRepo(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/repo/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"image_repos","output_colume":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"image_repos","output_column":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
func (b *BaseApi) DeleteRepo(c *gin.Context) {
var req dto.ImageRepoDelete
if err := c.ShouldBindJSON(&req); err != nil {
@@ -147,7 +147,7 @@ func (b *BaseApi) DeleteRepo(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/repo/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_colume":"name","output_value":"name"}],"formatZH":"更新镜像仓库 [name]","formatEN":"update image repo information [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_column":"name","output_value":"name"}],"formatZH":"更新镜像仓库 [name]","formatEN":"update image repo information [name]"}
func (b *BaseApi) UpdateRepo(c *gin.Context) {
var req dto.ImageRepoUpdate
if err := c.ShouldBindJSON(&req); err != nil {
+7 -2
View File
@@ -1,6 +1,7 @@
package v1
import (
"sort"
"time"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
@@ -8,6 +9,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/common"
"github.com/gin-gonic/gin"
"github.com/shirou/gopsutil/v3/disk"
"github.com/shirou/gopsutil/v3/net"
@@ -23,8 +25,9 @@ func (b *BaseApi) LoadMonitor(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
req.StartTime = req.StartTime.Add(8 * time.Hour)
req.EndTime = req.EndTime.Add(8 * time.Hour)
loc, _ := time.LoadLocation(common.LoadTimeZone())
req.StartTime = req.StartTime.In(loc)
req.EndTime = req.EndTime.In(loc)
var backdatas []dto.MonitorData
if req.Param == "all" || req.Param == "cpu" || req.Param == "memory" || req.Param == "load" {
@@ -88,6 +91,7 @@ func (b *BaseApi) GetNetworkOptions(c *gin.Context) {
for _, net := range netStat {
options = append(options, net.Name)
}
sort.Strings(options)
helper.SuccessWithData(c, options)
}
@@ -98,5 +102,6 @@ func (b *BaseApi) GetIOOptions(c *gin.Context) {
for _, net := range diskStat {
options = append(options, net.Name)
}
sort.Strings(options)
helper.SuccessWithData(c, options)
}
+1 -1
View File
@@ -53,7 +53,7 @@ func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /openResty/update [post]
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新 nginx 配置 [domain]","formatEN":"Update nginx conf [domain]"}
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新 nginx 配置 [domain]","formatEN":"Update nginx conf [domain]"}
func (b *BaseApi) UpdateNginxConfigByScope(c *gin.Context) {
var req request.NginxConfigUpdate
if err := c.ShouldBindJSON(&req); err != nil {
+123
View File
@@ -0,0 +1,123 @@
package v1
import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/gin-gonic/gin"
)
// @Tags Runtime
// @Summary List runtimes
// @Description 获取运行环境列表
// @Accept json
// @Param request body request.RuntimeSearch true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /runtimes/search [post]
func (b *BaseApi) SearchRuntimes(c *gin.Context) {
var req request.RuntimeSearch
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, items, err := runtimeService.Page(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: items,
})
}
// @Tags Runtime
// @Summary Create runtime
// @Description 创建运行环境
// @Accept json
// @Param request body request.RuntimeCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /runtimes [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建运行环境 [name]","formatEN":"Create runtime [name]"}
func (b *BaseApi) CreateRuntime(c *gin.Context) {
var req request.RuntimeCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := runtimeService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Delete runtime
// @Description 删除运行环境
// @Accept json
// @Param request body request.RuntimeDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /runtimes/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"删除网站 [name]","formatEN":"Delete website [name]"}
func (b *BaseApi) DeleteRuntime(c *gin.Context) {
var req request.RuntimeDelete
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := runtimeService.Delete(req.ID)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Runtime
// @Summary Update runtime
// @Description 更新运行环境
// @Accept json
// @Param request body request.RuntimeUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /runtimes/update [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新运行环境 [name]","formatEN":"Update runtime [name]"}
func (b *BaseApi) UpdateRuntime(c *gin.Context) {
var req request.RuntimeUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := runtimeService.Update(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Runtime
// @Summary Get runtime
// @Description 获取运行环境
// @Accept json
// @Param id path string true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /runtimes/:id [get]
func (b *BaseApi) GetRuntime(c *gin.Context) {
id, err := helper.GetIntParamByKey(c, "id")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
res, err := runtimeService.Get(id)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, res)
}
+70 -16
View File
@@ -2,14 +2,12 @@ package v1
import (
"errors"
"time"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/mfa"
"github.com/1Panel-dev/1Panel/backend/utils/ntp"
"github.com/gin-gonic/gin"
)
@@ -92,6 +90,48 @@ func (b *BaseApi) UpdatePassword(c *gin.Context) {
helper.SuccessWithData(c, nil)
}
// @Tags System Setting
// @Summary Update system ssl
// @Description 修改系统 ssl 登录
// @Accept json
// @Param request body dto.SSLUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/ssl/update [post]
// @x-panel-log {"bodyKeys":["ssl"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改系统 ssl => [ssl]","formatEN":"update system ssl => [ssl]"}
func (b *BaseApi) UpdateSSL(c *gin.Context) {
var req dto.SSLUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := settingService.UpdateSSL(c, req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags System Setting
// @Summary Load system cert info
// @Description 获取证书信息
// @Success 200 {object} dto.SettingInfo
// @Security ApiKeyAuth
// @Router /settings/ssl/info [get]
func (b *BaseApi) LoadFromCert(c *gin.Context) {
info, err := settingService.LoadFromCert()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, info)
}
// @Tags System Setting
// @Summary Update system port
// @Description 更新系统端口
@@ -147,26 +187,40 @@ func (b *BaseApi) HandlePasswordExpired(c *gin.Context) {
}
// @Tags System Setting
// @Summary Sync system time
// @Description 系统时间同步
// @Success 200 {string} ntime
// @Summary Load time zone options
// @Description 加载系统可用时区
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/time/sync [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"系统时间同步","formatEN":"sync system time"}
func (b *BaseApi) SyncTime(c *gin.Context) {
ntime, err := ntp.Getremotetime()
// @Router /settings/time/option [get]
func (b *BaseApi) LoadTimeZone(c *gin.Context) {
zones, err := settingService.LoadTimeZone()
if err != nil {
helper.SuccessWithData(c, time.Now().Format("2006-01-02 15:04:05 MST -0700"))
return
}
ts := ntime.Format("2006-01-02 15:04:05")
if err := ntp.UpdateSystemDate(ts); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, zones)
}
helper.SuccessWithData(c, ntime.Format("2006-01-02 15:04:05 MST -0700"))
// @Tags System Setting
// @Summary Sync system time
// @Description 系统时间同步
// @Accept json
// @Param request body dto.SyncTime true "request"
// @Success 200 {string} ntime
// @Security ApiKeyAuth
// @Router /settings/time/sync [post]
// @x-panel-log {"bodyKeys":["ntpSite"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"系统时间同步[ntpSite]","formatEN":"sync system time [ntpSite]"}
func (b *BaseApi) SyncTime(c *gin.Context) {
var req dto.SyncTime
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := settingService.SyncTime(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags System Setting
+4 -4
View File
@@ -68,7 +68,7 @@ func (b *BaseApi) ImportSnapshot(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/snapshot/description/update [post]
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"快照 [name] 描述信息修改 [description]","formatEN":"The description of the snapshot [name] is modified => [description]"}
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"快照 [name] 描述信息修改 [description]","formatEN":"The description of the snapshot [name] is modified => [description]"}
func (b *BaseApi) UpdateSnapDescription(c *gin.Context) {
var req dto.UpdateDescription
if err := c.ShouldBindJSON(&req); err != nil {
@@ -119,7 +119,7 @@ func (b *BaseApi) SearchSnapshot(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/snapshot/recover [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 恢复","formatEN":"Recover from system backup [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 恢复","formatEN":"Recover from system backup [name]"}
func (b *BaseApi) RecoverSnapshot(c *gin.Context) {
var req dto.SnapshotRecover
if err := c.ShouldBindJSON(&req); err != nil {
@@ -146,7 +146,7 @@ func (b *BaseApi) RecoverSnapshot(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/snapshot/rollback [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 回滚","formatEN":"Rollback from system backup [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 回滚","formatEN":"Rollback from system backup [name]"}
func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
var req dto.SnapshotRecover
if err := c.ShouldBindJSON(&req); err != nil {
@@ -173,7 +173,7 @@ func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/snapshot/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"删除系统快照 [name]","formatEN":"Delete system backup [name]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"删除系统快照 [name]","formatEN":"Delete system backup [name]"}
func (b *BaseApi) DeleteSnapshot(c *gin.Context) {
var req dto.BatchDeleteReq
if err := c.ShouldBindJSON(&req); err != nil {
+185
View File
@@ -0,0 +1,185 @@
package v1
import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
)
// @Tags SSH
// @Summary Load host ssh setting info
// @Description 加载 SSH 配置信息
// @Success 200 {object} dto.SSHInfo
// @Security ApiKeyAuth
// @Router /host/ssh/search [post]
func (b *BaseApi) GetSSHInfo(c *gin.Context) {
info, err := sshService.GetSSHInfo()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, info)
}
// @Tags SSH
// @Summary Operate ssh
// @Description 修改 SSH 服务状态
// @Accept json
// @Param request body dto.Operate true "request"
// @Security ApiKeyAuth
// @Router /host/ssh/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operation] SSH ","formatEN":"[operation] SSH"}
func (b *BaseApi) OperateSSH(c *gin.Context) {
var req dto.Operate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := sshService.OperateSSH(req.Operation); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags SSH
// @Summary Update host ssh setting
// @Description 更新 SSH 配置
// @Accept json
// @Param request body dto.SettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /host/ssh/update [post]
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改 SSH 配置 [key] => [value]","formatEN":"update SSH setting [key] => [value]"}
func (b *BaseApi) UpdateSSH(c *gin.Context) {
var req dto.SettingUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := sshService.Update(req.Key, req.Value); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags SSH
// @Summary Update host ssh setting by file
// @Description 上传文件更新 SSH 配置
// @Accept json
// @Param request body dto.SSHConf true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /host/conffile/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改 SSH 配置文件","formatEN":"update SSH conf"}
func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
var req dto.SSHConf
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := sshService.UpdateByFile(req.File); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags SSH
// @Summary Generate host ssh secret
// @Description 生成 ssh 密钥
// @Accept json
// @Param request body dto.GenerateSSH true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /host/ssh/generate [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
func (b *BaseApi) GenerateSSH(c *gin.Context) {
var req dto.GenerateSSH
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := sshService.GenerateSSH(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags SSH
// @Summary Load host ssh secret
// @Description 获取 ssh 密钥
// @Accept json
// @Param request body dto.GenerateLoad true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /host/ssh/secret [post]
func (b *BaseApi) LoadSSHSecret(c *gin.Context) {
var req dto.GenerateLoad
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := sshService.LoadSSHSecret(req.EncryptionMode)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags SSH
// @Summary Load host ssh logs
// @Description 获取 ssh 登录日志
// @Accept json
// @Param request body dto.SearchSSHLog true "request"
// @Success 200 {object} dto.SSHLog
// @Security ApiKeyAuth
// @Router /host/ssh/logs [post]
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
var req dto.SearchSSHLog
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := sshService.LoadLog(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
}
+70 -8
View File
@@ -1,14 +1,18 @@
package v1
import (
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/1Panel-dev/1Panel/backend/utils/copier"
"github.com/1Panel-dev/1Panel/backend/utils/ssh"
"github.com/1Panel-dev/1Panel/backend/utils/terminal"
@@ -39,9 +43,10 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
return
}
var connInfo ssh.ConnInfo
if err := copier.Copy(&connInfo, &host); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, constant.ErrStructTransform)
return
_ = copier.Copy(&connInfo, &host)
connInfo.PrivateKey = []byte(host.PrivateKey)
if len(host.PassPhrase) != 0 {
connInfo.PassPhrase = []byte(host.PassPhrase)
}
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
@@ -103,14 +108,16 @@ func (b *BaseApi) RedisWsSsh(c *gin.Context) {
return
}
defer wsConn.Close()
commands := fmt.Sprintf("docker exec -it %s redis-cli", redisConf.ContainerName)
commands := "redis-cli"
if len(redisConf.Requirepass) != 0 {
commands = fmt.Sprintf("docker exec -it %s redis-cli -a %s --no-auth-warning", redisConf.ContainerName, redisConf.Requirepass)
commands = fmt.Sprintf("redis-cli -a %s --no-auth-warning", redisConf.Requirepass)
}
slave, err := terminal.NewCommand(commands)
pidMap := loadMapFromDockerTop(redisConf.ContainerName)
slave, err := terminal.NewCommand(fmt.Sprintf("docker exec -it %s %s", redisConf.ContainerName, commands))
if wshandleError(wsConn, err) {
return
}
defer killBash(redisConf.ContainerName, commands, pidMap)
defer slave.Close()
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave)
@@ -156,14 +163,25 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
}
defer wsConn.Close()
cmds := fmt.Sprintf("docker exec %s %s", containerID, command)
if len(user) != 0 {
cmds = fmt.Sprintf("docker exec -u %s %s %s", user, containerID, command)
}
stdout, err := cmd.Exec(cmds)
if wshandleError(wsConn, errors.WithMessage(err, stdout)) {
return
}
commands := fmt.Sprintf("docker exec -it %s %s", containerID, command)
if len(user) != 0 {
commands = fmt.Sprintf("docker exec -it -u %s %s %s", user, containerID, command)
}
pidMap := loadMapFromDockerTop(containerID)
slave, err := terminal.NewCommand(commands)
if wshandleError(wsConn, err) {
return
}
defer killBash(containerID, command, pidMap)
defer slave.Close()
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave)
@@ -187,14 +205,58 @@ func wshandleError(ws *websocket.Conn, err error) bool {
if err != nil {
global.LOG.Errorf("handler ws faled:, err: %v", err)
dt := time.Now().Add(time.Second)
if err := ws.WriteControl(websocket.CloseMessage, []byte(err.Error()), dt); err != nil {
global.LOG.Errorf("websocket writes control message failed, err: %v", err)
if ctlerr := ws.WriteControl(websocket.CloseMessage, []byte(err.Error()), dt); ctlerr != nil {
wsData, err := json.Marshal(terminal.WsMsg{
Type: terminal.WsMsgCmd,
Data: base64.StdEncoding.EncodeToString([]byte(err.Error())),
})
if err != nil {
_ = ws.WriteMessage(websocket.TextMessage, []byte("{\"type\":\"cmd\",\"data\":\"failed to encoding to json\"}"))
} else {
_ = ws.WriteMessage(websocket.TextMessage, wsData)
}
}
return true
}
return false
}
func loadMapFromDockerTop(containerID string) map[string]string {
pidMap := make(map[string]string)
sudo := cmd.SudoHandleCmd()
stdout, err := cmd.Execf("%s docker top %s -eo pid,command ", sudo, containerID)
if err != nil {
return pidMap
}
lines := strings.Split(stdout, "\n")
for _, line := range lines {
parts := strings.Fields(line)
if len(parts) != 2 {
continue
}
pidMap[parts[0]] = parts[1]
}
return pidMap
}
func killBash(containerID, comm string, pidMap map[string]string) {
sudo := cmd.SudoHandleCmd()
newPidMap := loadMapFromDockerTop(containerID)
for pid, command := range newPidMap {
isOld := false
for pid2 := range pidMap {
if pid == pid2 {
isOld = true
break
}
}
if !isOld && command == comm {
_, _ = cmd.Execf("%s kill -9 %s", sudo, pid)
}
}
}
var upGrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024 * 1024 * 10,
+22
View File
@@ -22,6 +22,28 @@ func (b *BaseApi) GetUpgradeInfo(c *gin.Context) {
helper.SuccessWithData(c, info)
}
// @Tags System Setting
// @Summary Load release notes by version
// @Description 获取版本 release notes
// @Accept json
// @Param request body dto.Upgrade true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/upgrade [get]
func (b *BaseApi) GetNotesByVersion(c *gin.Context) {
var req dto.Upgrade
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
notes, err := upgradeService.LoadNotes(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, notes)
}
// @Tags System Setting
// @Summary Upgrade
// @Description 系统更新
+324 -19
View File
@@ -78,14 +78,12 @@ func (b *BaseApi) CreateWebsite(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
tx, ctx := helper.GetTxAndContext()
err := websiteService.CreateWebsite(ctx, req)
err := websiteService.CreateWebsite(req)
if err != nil {
tx.Rollback()
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
tx.Commit()
helper.SuccessWithData(c, nil)
}
@@ -97,7 +95,7 @@ func (b *BaseApi) CreateWebsite(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/operate [post]
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"[operate] 网站 [domain]","formatEN":"[operate] website [domain]"}
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[operate] 网站 [domain]","formatEN":"[operate] website [domain]"}
func (b *BaseApi) OpWebsite(c *gin.Context) {
var req request.WebsiteOp
if err := c.ShouldBindJSON(&req); err != nil {
@@ -120,21 +118,19 @@ func (b *BaseApi) OpWebsite(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"删除网站 [domain]","formatEN":"Delete website [domain]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除网站 [domain]","formatEN":"Delete website [domain]"}
func (b *BaseApi) DeleteWebsite(c *gin.Context) {
var req request.WebsiteDelete
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
tx, ctx := helper.GetTxAndContext()
err := websiteService.DeleteWebsite(ctx, req)
err := websiteService.DeleteWebsite(req)
if err != nil {
tx.Rollback()
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
tx.Commit()
helper.SuccessWithData(c, nil)
}
@@ -189,14 +185,16 @@ func (b *BaseApi) GetWebsite(c *gin.Context) {
// @Param id path integer true "request"
// @Success 200 {object} response.FileInfo
// @Security ApiKeyAuth
// @Router /websites/:id/nginx [get]
// @Router /websites/:id/config/:type [get]
func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
fileInfo, err := websiteService.GetWebsiteNginxConfig(id)
configType := c.Param("type")
fileInfo, err := websiteService.GetWebsiteNginxConfig(id, configType)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@@ -234,7 +232,7 @@ func (b *BaseApi) GetWebDomains(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/domains/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_domains","output_colume":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
var req request.WebsiteDomainDelete
if err := c.ShouldBindJSON(&req); err != nil {
@@ -302,7 +300,7 @@ func (b *BaseApi) GetNginxConfig(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/config/update [post]
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"nginx 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"nginx 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
func (b *BaseApi) UpdateNginxConfig(c *gin.Context) {
var req request.NginxConfigUpdate
if err := c.ShouldBindJSON(&req); err != nil {
@@ -346,7 +344,7 @@ func (b *BaseApi) GetHTTPSConfig(c *gin.Context) {
// @Success 200 {object} response.WebsiteHTTPS
// @Security ApiKeyAuth
// @Router /websites/:id/https [post]
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] https 配置","formatEN":"Update website https [domain] conf"}
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] https 配置","formatEN":"Update website https [domain] conf"}
func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) {
var req request.WebsiteHTTPSOp
if err := c.ShouldBindJSON(&req); err != nil {
@@ -416,7 +414,7 @@ func (b *BaseApi) GetWebsiteWafConfig(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/waf/update [post]
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"WAF 配置修改 [domain]","formatEN":"WAF conf update [domain]"}
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"WAF 配置修改 [domain]","formatEN":"WAF conf update [domain]"}
func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
var req request.WebsiteWafUpdate
if err := c.ShouldBindJSON(&req); err != nil {
@@ -438,7 +436,7 @@ func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/nginx/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"[domain] Nginx 配置修改","formatEN":"[domain] Nginx conf update"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] Nginx 配置修改","formatEN":"[domain] Nginx conf update"}
func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
var req request.WebsiteNginxUpdate
if err := c.ShouldBindJSON(&req); err != nil {
@@ -460,7 +458,7 @@ func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
// @Success 200 {object} response.WebsiteLog
// @Security ApiKeyAuth
// @Router /websites/log [post]
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"[domain][operate] 日志","formatEN":"[domain][operate] logs"}
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain][operate] 日志","formatEN":"[domain][operate] logs"}
func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
var req request.WebsiteLogReq
if err := c.ShouldBindJSON(&req); err != nil {
@@ -483,7 +481,7 @@ func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/default/server [post]
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"修改默认 server => [domain]","formatEN":"Change default server => [domain]"}
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改默认 server => [domain]","formatEN":"Change default server => [domain]"}
func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
var req request.WebsiteDefaultUpdate
if err := c.ShouldBindJSON(&req); err != nil {
@@ -496,3 +494,310 @@ func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
}
helper.SuccessWithData(c, nil)
}
// @Tags Website
// @Summary Load websit php conf
// @Description 获取网站 php 配置
// @Accept json
// @Param id path integer true "request"
// @Success 200 {object} response.PHPConfig
// @Security ApiKeyAuth
// @Router /websites/php/config/:id [get]
func (b *BaseApi) GetWebsitePHPConfig(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}
data, err := websiteService.GetPHPConfig(id)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Website PHP
// @Summary Update website php conf
// @Description 更新 网站 PHP 配置
// @Accept json
// @Param request body request.WebsitePHPConfigUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/php/config [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] PHP 配置修改","formatEN":"[domain] PHP conf update"}
func (b *BaseApi) UpdateWebsitePHPConfig(c *gin.Context) {
var req request.WebsitePHPConfigUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdatePHPConfig(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website PHP
// @Summary Update php conf
// @Description 更新 php 配置
// @Accept json
// @Param request body request.WebsitePHPFileUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/php/update [post]
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"php 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
func (b *BaseApi) UpdatePHPFile(c *gin.Context) {
var req request.WebsitePHPFileUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdatePHPConfigFile(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website
// @Summary Get rewrite conf
// @Description 获取伪静态配置
// @Accept json
// @Param request body request.NginxRewriteReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/rewrite [post]
func (b *BaseApi) GetRewriteConfig(c *gin.Context) {
var req request.NginxRewriteReq
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetRewriteConfig(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website
// @Summary Update rewrite conf
// @Description 更新伪静态配置
// @Accept json
// @Param request body request.NginxRewriteUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/rewrite/update [post]
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"伪静态配置修改 [domain]","formatEN":"Nginx conf rewrite update [domain]"}
func (b *BaseApi) UpdateRewriteConfig(c *gin.Context) {
var req request.NginxRewriteUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateRewriteConfig(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website
// @Summary Update Site Dir
// @Description 更新网站目录
// @Accept json
// @Param request body request.WebsiteUpdateDir true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/dir/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] 目录","formatEN":"Update domain [domain] dir"}
func (b *BaseApi) UpdateSiteDir(c *gin.Context) {
var req request.WebsiteUpdateDir
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateSiteDir(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Update Site Dir permission
// @Description 更新网站目录权限
// @Accept json
// @Param request body request.WebsiteUpdateDirPermission true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/dir/permission [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] 目录权限","formatEN":"Update domain [domain] dir permission"}
func (b *BaseApi) UpdateSiteDirPermission(c *gin.Context) {
var req request.WebsiteUpdateDirPermission
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateSitePermission(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Get proxy conf
// @Description 获取反向代理配置
// @Accept json
// @Param request body request.WebsiteProxyReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/proxies [post]
func (b *BaseApi) GetProxyConfig(c *gin.Context) {
var req request.WebsiteProxyReq
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetProxies(req.ID)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website
// @Summary Update proxy conf
// @Description 修改反向代理配置
// @Accept json
// @Param request body request.WebsiteProxyConfig true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/proxies/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 反向代理配置 ","formatEN":"Update domain [domain] proxy config"}
func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
var req request.WebsiteProxyConfig
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := websiteService.OperateProxy(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Update proxy file
// @Description 更新反向代理文件
// @Accept json
// @Param request body request.NginxProxyUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/proxy/file [post]
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新反向代理文件 [domain]","formatEN":"Nginx conf proxy file update [domain]"}
func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
var req request.NginxProxyUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateProxyFile(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Get AuthBasic conf
// @Description 获取密码访问配置
// @Accept json
// @Param request body request.NginxAuthReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/auths [post]
func (b *BaseApi) GetAuthConfig(c *gin.Context) {
var req request.NginxAuthReq
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetAuthBasics(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website
// @Summary Get AuthBasic conf
// @Description 更新密码访问配置
// @Accept json
// @Param request body request.NginxAuthUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/auths/update [post]
func (b *BaseApi) UpdateAuthConfig(c *gin.Context) {
var req request.NginxAuthUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateAuthBasic(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
// @Tags Website
// @Summary Get AntiLeech conf
// @Description 获取防盗链配置
// @Accept json
// @Param request body request.NginxCommonReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/leech [post]
func (b *BaseApi) GetAntiLeech(c *gin.Context) {
var req request.NginxCommonReq
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
res, err := websiteService.GetAntiLeech(req.WebsiteID)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website
// @Summary Update AntiLeech
// @Description 更新防盗链配置
// @Accept json
// @Param request body request.NginxAntiLeechUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/leech/update [post]
func (b *BaseApi) UpdateAntiLeech(c *gin.Context) {
var req request.NginxAntiLeechUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteService.UpdateAntiLeech(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithOutData(c)
}
+1 -1
View File
@@ -64,7 +64,7 @@ func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/acme/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_acme_accounts","output_colume":"email","output_value":"email"}],"formatZH":"删除网站 acme [email]","formatEN":"Delete website acme [email]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_acme_accounts","output_column":"email","output_value":"email"}],"formatZH":"删除网站 acme [email]","formatEN":"Delete website acme [email]"}
func (b *BaseApi) DeleteWebsiteAcmeAccount(c *gin.Context) {
var req request.WebsiteResourceReq
if err := c.ShouldBindJSON(&req); err != nil {
+1 -1
View File
@@ -85,7 +85,7 @@ func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/dns/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_dns_accounts","output_colume":"name","output_value":"name"}],"formatZH":"删除网站 dns [name]","formatEN":"Delete website dns [name]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_dns_accounts","output_column":"name","output_value":"name"}],"formatZH":"删除网站 dns [name]","formatEN":"Delete website dns [name]"}
func (b *BaseApi) DeleteWebsiteDnsAccount(c *gin.Context) {
var req request.WebsiteResourceReq
if err := c.ShouldBindJSON(&req); err != nil {
-89
View File
@@ -1,89 +0,0 @@
package v1
import (
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/gin-gonic/gin"
)
// @Tags Website Group
// @Summary List website groups
// @Description 获取网站组
// @Success 200 {anrry} model.WebsiteGroup
// @Security ApiKeyAuth
// @Router /websites/groups [get]
func (b *BaseApi) GetWebGroups(c *gin.Context) {
list, err := websiteGroupService.GetGroups()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Website Group
// @Summary Create website group
// @Description 创建网站组
// @Accept json
// @Param request body request.WebsiteGroupCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/groups [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建网站组 [name]","formatEN":"Create website groups [name]"}
func (b *BaseApi) CreateWebGroup(c *gin.Context) {
var req request.WebsiteGroupCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteGroupService.CreateGroup(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website Group
// @Summary Update website group
// @Description 更新网站组
// @Accept json
// @Param request body request.WebsiteGroupUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/groups/update [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新网站组 [name]","formatEN":"Update website groups [name]"}
func (b *BaseApi) UpdateWebGroup(c *gin.Context) {
var req request.WebsiteGroupUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteGroupService.UpdateGroup(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Website Group
// @Summary Delete website group
// @Description 删除网站组
// @Accept json
// @Param request body request.WebsiteResourceReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/groups/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_groups","output_colume":"name","output_value":"name"}],"formatZH":"删除网站组 [name]","formatEN":"Delete website group [name]"}
func (b *BaseApi) DeleteWebGroup(c *gin.Context) {
var req request.WebsiteResourceReq
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteGroupService.DeleteGroup(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
+24 -2
View File
@@ -75,7 +75,7 @@ func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/ssl/renew [post]
// @x-panel-log {"bodyKeys":["SSLId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"SSLId","isList":false,"db":"website_ssls","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"重置 ssl [domain]","formatEN":"Renew ssl [domain]"}
// @x-panel-log {"bodyKeys":["SSLId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"SSLId","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"重置 ssl [domain]","formatEN":"Renew ssl [domain]"}
func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLRenew
if err := c.ShouldBindJSON(&req); err != nil {
@@ -119,7 +119,7 @@ func (b *BaseApi) GetDNSResolve(c *gin.Context) {
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/ssl/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_ssls","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"删除 ssl [domain]","formatEN":"Delete ssl [domain]"}
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除 ssl [domain]","formatEN":"Delete ssl [domain]"}
func (b *BaseApi) DeleteWebsiteSSL(c *gin.Context) {
var req request.WebsiteResourceReq
if err := c.ShouldBindJSON(&req); err != nil {
@@ -176,3 +176,25 @@ func (b *BaseApi) GetWebsiteSSLById(c *gin.Context) {
}
helper.SuccessWithData(c, websiteSSL)
}
// @Tags Website SSL
// @Summary Update ssl
// @Description 更新 ssl
// @Accept json
// @Param request body request.WebsiteSSLUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/ssl/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新证书设置 [domain]","formatEN":"Update ssl config [domain]"}
func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := websiteSSLService.Update(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
+58 -19
View File
@@ -1,7 +1,7 @@
package dto
import (
"encoding/json"
"github.com/1Panel-dev/1Panel/backend/app/model"
)
type AppDatabase struct {
@@ -32,19 +32,47 @@ type AppVersion struct {
}
type AppList struct {
Version string `json:"version"`
Tags []Tag `json:"tags"`
Items []AppDefine `json:"items"`
Valid bool `json:"valid"`
Violations []string `json:"violations"`
LastModified int `json:"lastModified"`
Apps []AppDefine `json:"apps"`
Extra ExtraProperties `json:"additionalProperties"`
}
type AppDefine struct {
Key string `json:"key"`
Icon string `json:"icon"`
Name string `json:"name"`
ReadMe string `json:"readMe"`
LastModified int `json:"lastModified"`
AppProperty AppProperty `json:"additionalProperties"`
Versions []AppConfigVersion `json:"versions"`
}
type LocalAppAppDefine struct {
AppProperty model.App `json:"additionalProperties" yaml:"additionalProperties"`
}
type LocalAppParam struct {
AppParams LocalAppInstallDefine `json:"additionalProperties" yaml:"additionalProperties"`
}
type LocalAppInstallDefine struct {
FormFields interface{} `json:"formFields" yaml:"formFields"`
}
type ExtraProperties struct {
Tags []Tag `json:"tags"`
}
type AppProperty struct {
Name string `json:"name"`
Type string `json:"type"`
Tags []string `json:"tags"`
Versions []string `json:"versions"`
ShortDescZh string `json:"shortDescZh"`
ShortDescEn string `json:"shortDescEn"`
Type string `json:"type"`
Key string `json:"key"`
Required []string `json:"Required"`
CrossVersionUpdate bool `json:"crossVersionUpdate"`
Limit int `json:"limit"`
@@ -54,9 +82,12 @@ type AppDefine struct {
Document string `json:"document"`
}
func (define AppDefine) GetRequired() string {
by, _ := json.Marshal(define.Required)
return string(by)
type AppConfigVersion struct {
Name string `json:"name"`
LastModified int `json:"lastModified"`
DownloadUrl string `json:"downloadUrl"`
DownloadCallBackUrl string `json:"downloadCallBackUrl"`
AppForm interface{} `json:"additionalProperties"`
}
type Tag struct {
@@ -69,15 +100,23 @@ type AppForm struct {
}
type AppFormFields struct {
Type string `json:"type"`
LabelZh string `json:"labelZh"`
LabelEn string `json:"labelEn"`
Required bool `json:"required"`
Default interface{} `json:"default"`
EnvKey string `json:"envKey"`
Disabled bool `json:"disabled"`
Edit bool `json:"edit"`
Rule string `json:"rule"`
Type string `json:"type"`
LabelZh string `json:"labelZh"`
LabelEn string `json:"labelEn"`
Required bool `json:"required"`
Default interface{} `json:"default"`
EnvKey string `json:"envKey"`
Disabled bool `json:"disabled"`
Edit bool `json:"edit"`
Rule string `json:"rule"`
Multiple bool `json:"multiple"`
Child interface{} `json:"child"`
Values []AppFormValue `json:"values"`
}
type AppFormValue struct {
Label string `json:"label"`
Value string `json:"value"`
}
type AppResource struct {
+6 -12
View File
@@ -9,7 +9,6 @@ type UserLoginInfo struct {
Name string `json:"name"`
Token string `json:"token"`
MfaStatus string `json:"mfaStatus"`
MfaSecret string `json:"mfaSecret"`
}
type MfaCredential struct {
@@ -18,22 +17,17 @@ type MfaCredential struct {
}
type Login struct {
Name string `json:"name"`
Password string `json:"password"`
Captcha string `json:"captcha"`
CaptchaID string `json:"captchaID"`
AuthMethod string `json:"authMethod"`
Name string `json:"name"`
Password string `json:"password"`
IgnoreCaptcha bool `json:"ignoreCaptcha"`
Captcha string `json:"captcha"`
CaptchaID string `json:"captchaID"`
AuthMethod string `json:"authMethod"`
}
type MFALogin struct {
Name string `json:"name"`
Password string `json:"password"`
Secret string `json:"secret"`
Code string `json:"code"`
AuthMethod string `json:"authMethod"`
}
type InitUser struct {
Name string `json:"name" validate:"required"`
Password string `json:"password" validate:"required"`
}
+2 -1
View File
@@ -36,6 +36,7 @@ type CommonBackup struct {
DetailName string `json:"detailName"`
}
type CommonRecover struct {
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO"`
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
Name string `json:"name"`
DetailName string `json:"detailName"`
@@ -59,7 +60,7 @@ type BackupRecords struct {
}
type DownloadRecord struct {
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL"`
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO"`
FileDir string `json:"fileDir" validate:"required"`
FileName string `json:"fileName" validate:"required"`
}
+5 -1
View File
@@ -12,7 +12,7 @@ type PageInfo struct {
type UpdateDescription struct {
ID uint `json:"id" validate:"required"`
Description string `json:"description"`
Description string `json:"description" validate:"max=256"`
}
type OperationWithName struct {
@@ -23,6 +23,10 @@ type OperateByID struct {
ID uint `json:"id" validate:"required"`
}
type Operate struct {
Operation string `json:"operation" validate:"required"`
}
type BatchDeleteReq struct {
Ids []uint `json:"ids" validate:"required"`
}
+23 -5
View File
@@ -22,6 +22,11 @@ type ContainerInfo struct {
State string `json:"state"`
RunTime string `json:"runTime"`
CPUPercent float64 `json:"cpuPercent"`
MemoryPercent float64 `json:"memoryPercent"`
Ports []string `json:"ports"`
IsFromApp bool `json:"isFromApp"`
IsFromCompose bool `json:"isFromCompose"`
}
@@ -58,8 +63,10 @@ type VolumeHelper struct {
Mode string `json:"mode"`
}
type PortHelper struct {
ContainerPort int `json:"containerPort"`
HostPort int `json:"hostPort"`
HostIP string `json:"hostIP"`
HostPort string `json:"hostPort"`
ContainerPort string `json:"containerPort"`
Protocol string `json:"protocol"`
}
type ContainerLog struct {
@@ -73,6 +80,16 @@ type ContainerOperation struct {
NewName string `json:"newName"`
}
type ContainerPrune struct {
PruneType string `json:"pruneType" validate:"required,oneof=container image volume network"`
WithTagAll bool `josn:"withTagAll"`
}
type ContainerPruneReport struct {
DeletedNumber int `json:"deletedNumber"`
SpaceReclaimed int `json:"spaceReclaimed"`
}
type Network struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -84,7 +101,7 @@ type Network struct {
CreatedAt time.Time `json:"createdAt"`
Attachable bool `json:"attachable"`
}
type NetworkCreat struct {
type NetworkCreate struct {
Name string `json:"name"`
Driver string `json:"driver"`
Options []string `json:"options"`
@@ -101,7 +118,7 @@ type Volume struct {
Mountpoint string `json:"mountpoint"`
CreatedAt time.Time `json:"createdAt"`
}
type VolumeCreat struct {
type VolumeCreate struct {
Name string `json:"name"`
Driver string `json:"driver"`
Options []string `json:"options"`
@@ -129,7 +146,7 @@ type ComposeContainer struct {
State string `json:"state"`
}
type ComposeCreate struct {
Name string `json:"name" validate:"required"`
Name string `json:"name"`
From string `json:"from" validate:"required,oneof=edit path template"`
File string `json:"file"`
Path string `json:"path"`
@@ -139,6 +156,7 @@ type ComposeOperation struct {
Name string `json:"name" validate:"required"`
Path string `json:"path" validate:"required"`
Operation string `json:"operation" validate:"required,oneof=start stop down"`
WithFile bool `json:"withFile"`
}
type ComposeUpdate struct {
Name string `json:"name" validate:"required"`
+14 -1
View File
@@ -10,6 +10,7 @@ type CronjobCreate struct {
Day int `json:"day" validate:"number"`
Hour int `json:"hour" validate:"number"`
Minute int `json:"minute" validate:"number"`
Second int `json:"second" validate:"number"`
Script string `json:"script"`
Website string `json:"website"`
@@ -30,6 +31,7 @@ type CronjobUpdate struct {
Day int `json:"day" validate:"number"`
Hour int `json:"hour" validate:"number"`
Minute int `json:"minute" validate:"number"`
Second int `json:"second" validate:"number"`
Script string `json:"script"`
Website string `json:"website"`
@@ -52,6 +54,16 @@ type CronjobDownload struct {
BackupAccountID uint `json:"backupAccountID" validate:"required"`
}
type CronjobClean struct {
CleanData bool `json:"cleanData"`
CronjobID uint `json:"cronjobID" validate:"required"`
}
type CronjobBatchDelete struct {
CleanData bool `json:"cleanData"`
IDs []uint `json:"ids"`
}
type CronjobInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
@@ -61,6 +73,7 @@ type CronjobInfo struct {
Day int `json:"day"`
Hour int `json:"hour"`
Minute int `json:"minute"`
Second int `json:"second"`
Script string `json:"script"`
Website string `json:"website"`
@@ -73,7 +86,7 @@ type CronjobInfo struct {
TargetDirID int `json:"targetDirID"`
RetainCopies int `json:"retainCopies"`
LastRecrodTime string `json:"lastRecrodTime"`
LastRecordTime string `json:"lastRecordTime"`
Status string `json:"status"`
}
+14 -13
View File
@@ -3,13 +3,6 @@ package dto
import "time"
type DashboardBase struct {
HaloID uint `json:"haloID"`
DateeaseID uint `json:"dateeaseID"`
JumpServerID uint `json:"jumpserverID"`
MeterSphereID uint `json:"metersphereID"`
KubeoperatorID uint `json:"kubeoperatorID"`
KubepiID uint `json:"kubepiID"`
WebsiteNumber int `json:"websiteNumber"`
DatabaseNumber int `json:"databaseNumber"`
CronjobNumber int `json:"cronjobNumber"`
@@ -55,8 +48,21 @@ type DashboardCurrent struct {
IOReadBytes uint64 `json:"ioReadBytes"`
IOWriteBytes uint64 `json:"ioWriteBytes"`
IOCount uint64 `json:"ioCount"`
IOTime uint64 `json:"ioTime"`
IOReadTime uint64 `json:"ioReadTime"`
IOWriteTime uint64 `json:"ioWriteTime"`
DiskData []DiskInfo `json:"diskData"`
NetBytesSent uint64 `json:"netBytesSent"`
NetBytesRecv uint64 `json:"netBytesRecv"`
ShotTime time.Time `json:"shotTime"`
}
type DiskInfo struct {
Path string `json:"path"`
Type string `json:"type"`
Device string `json:"device"`
Total uint64 `json:"total"`
Free uint64 `json:"free"`
Used uint64 `json:"used"`
@@ -66,9 +72,4 @@ type DashboardCurrent struct {
InodesUsed uint64 `json:"inodesUsed"`
InodesFree uint64 `json:"inodesFree"`
InodesUsedPercent float64 `json:"inodesUsedPercent"`
NetBytesSent uint64 `json:"netBytesSent"`
NetBytesRecv uint64 `json:"netBytesRecv"`
ShotTime time.Time `json:"shotTime"`
}
+11 -3
View File
@@ -5,16 +5,24 @@ type DaemonJsonUpdateByFile struct {
}
type DaemonJsonConf struct {
IsSwarm bool `json:"isSwarm"`
Status string `json:"status"`
Version string `json:"version"`
Mirrors []string `json:"registryMirrors"`
Registries []string `json:"insecureRegistries"`
LiveRestore bool `json:"liveRestore"`
IPTables bool `json:"iptables"`
CgroupDriver string `json:"cgroupDriver"`
LogMaxSize string `json:"logMaxSize"`
LogMaxFile string `json:"logMaxFile"`
}
type LogOption struct {
LogMaxSize string `json:"logMaxSize"`
LogMaxFile string `json:"logMaxFile"`
}
type DockerOperation struct {
StopSocket bool `json:"stopSocket"`
StopService bool `json:"stopService"`
Operation string `json:"operation" validate:"required,oneof=start restart stop"`
Operation string `json:"operation" validate:"required,oneof=start restart stop"`
}
+47
View File
@@ -0,0 +1,47 @@
package dto
type FirewallBaseInfo struct {
Name string `json:"name"`
Status string `json:"status"`
Version string `json:"version"`
PingStatus string `json:"pingStatus"`
}
type RuleSearch struct {
PageInfo
Info string `json:"info"`
Type string `json:"type" validate:"required"`
}
type FirewallOperation struct {
Operation string `json:"operation" validate:"required,oneof=start stop disablePing enablePing"`
}
type PortRuleOperate struct {
Operation string `json:"operation" validate:"required,oneof=add remove"`
Address string `json:"address"`
Port string `json:"port" validate:"required"`
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
}
type AddrRuleOperate struct {
Operation string `json:"operation" validate:"required,oneof=add remove"`
Address string `json:"address" validate:"required"`
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
}
type PortRuleUpdate struct {
OldRule PortRuleOperate `json:"oldRule"`
NewRule PortRuleOperate `json:"newRule"`
}
type AddrRuleUpdate struct {
OldRule AddrRuleOperate `json:"oldRule"`
NewRule AddrRuleOperate `json:"newRule"`
}
type BatchRuleOperate struct {
Type string `json:"type" validate:"required"`
Rules []PortRuleOperate `json:"rules"`
}
+1
View File
@@ -13,6 +13,7 @@ type GroupSearch struct {
type GroupUpdate struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type" validate:"required"`
IsDefault bool `json:"isDefault"`
}
+27 -20
View File
@@ -5,26 +5,29 @@ import (
)
type HostOperate struct {
ID uint `json:"id"`
GroupID uint `json:"groupID"`
Name string `json:"name"`
Addr string `json:"addr" validate:"required,ip"`
Port uint `json:"port" validate:"required,number,max=65535,min=1"`
User string `json:"user" validate:"required"`
AuthMode string `json:"authMode" validate:"oneof=password key"`
PrivateKey string `json:"privateKey"`
Password string `json:"password"`
ID uint `json:"id"`
GroupID uint `json:"groupID"`
Name string `json:"name"`
Addr string `json:"addr" validate:"required"`
Port uint `json:"port" validate:"required,number,max=65535,min=1"`
User string `json:"user" validate:"required"`
AuthMode string `json:"authMode" validate:"oneof=password key"`
Password string `json:"password"`
PrivateKey string `json:"privateKey"`
PassPhrase string `json:"passPhrase"`
RememberPassword bool `json:"rememberPassword"`
Description string `json:"description"`
}
type HostConnTest struct {
Addr string `json:"addr" validate:"required,ip"`
Addr string `json:"addr" validate:"required"`
Port uint `json:"port" validate:"required,number,max=65535,min=1"`
User string `json:"user" validate:"required"`
AuthMode string `json:"authMode" validate:"oneof=password key"`
PrivateKey string `json:"privateKey"`
Password string `json:"password"`
PrivateKey string `json:"privateKey"`
PassPhrase string `json:"passPhrase"`
}
type SearchHostWithPage struct {
@@ -43,15 +46,19 @@ type ChangeHostGroup struct {
}
type HostInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
GroupID uint `json:"groupID"`
GroupBelong string `json:"groupBelong"`
Name string `json:"name"`
Addr string `json:"addr"`
Port uint `json:"port"`
User string `json:"user"`
AuthMode string `json:"authMode"`
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
GroupID uint `json:"groupID"`
GroupBelong string `json:"groupBelong"`
Name string `json:"name"`
Addr string `json:"addr"`
Port uint `json:"port"`
User string `json:"user"`
AuthMode string `json:"authMode"`
Password string `json:"password"`
PrivateKey string `json:"privateKey"`
PassPhrase string `json:"passPhrase"`
RememberPassword bool `json:"rememberPassword"`
Description string `json:"description"`
}
+14 -5
View File
@@ -28,13 +28,20 @@ type NginxParam struct {
Params []string
}
type NginxAuth struct {
Username string `json:"username"`
Remark string `json:"remark"`
}
type NginxKey string
const (
Index NginxKey = "index"
LimitConn NginxKey = "limit-conn"
SSL NginxKey = "ssl"
HttpPer NginxKey = "http-per"
Index NginxKey = "index"
LimitConn NginxKey = "limit-conn"
SSL NginxKey = "ssl"
CACHE NginxKey = "cache"
HttpPer NginxKey = "http-per"
ProxyCache NginxKey = "proxy-cache"
)
var ScopeKeyMap = map[NginxKey][]string{
@@ -46,5 +53,7 @@ var ScopeKeyMap = map[NginxKey][]string{
var StaticFileKeyMap = map[NginxKey]struct {
}{
SSL: {},
SSL: {},
CACHE: {},
ProxyCache: {},
}
+13
View File
@@ -18,6 +18,18 @@ type AppInstallCreate struct {
Params map[string]interface{} `json:"params"`
Name string `json:"name" validate:"required"`
Services map[string]string `json:"services"`
AppContainerConfig
}
type AppContainerConfig struct {
Advanced bool `json:"advanced"`
CpuQuota float64 `json:"cpuQuota"`
MemoryLimit float64 `json:"memoryLimit"`
MemoryUnit string `json:"memoryUnit"`
ContainerName string `json:"containerName"`
AllowPort bool `json:"allowPort"`
EditCompose bool `json:"editCompose"`
DockerCompose string `json:"dockerCompose"`
}
type AppInstalledSearch struct {
@@ -51,6 +63,7 @@ type AppInstalledOperate struct {
type AppInstalledUpdate struct {
InstallId uint `json:"installId" validate:"required"`
Params map[string]interface{} `json:"params" validate:"required"`
AppContainerConfig
}
type PortUpdate struct {
+13
View File
@@ -22,6 +22,7 @@ type FileCreate struct {
IsLink bool `json:"isLink"`
IsSymlink bool `json:"isSymlink"`
LinkPath string `json:"linkPath"`
Sub bool `json:"sub"`
}
type FileDelete struct {
@@ -81,6 +82,11 @@ type FileDownload struct {
Compress bool `json:"compress" validate:"required"`
}
type FileChunkDownload struct {
Path string `json:"path" validate:"required"`
Name string `json:"name" validate:"required"`
}
type DirSizeReq struct {
Path string `json:"path" validate:"required"`
}
@@ -88,3 +94,10 @@ type DirSizeReq struct {
type FileProcessReq struct {
Key string `json:"key"`
}
type FileRoleUpdate struct {
Path string `json:"path" validate:"required"`
User string `json:"user" validate:"required"`
Group string `json:"group" validate:"required"`
Sub bool `json:"sub" validate:"required"`
}
+47
View File
@@ -19,3 +19,50 @@ type NginxConfigUpdate struct {
WebsiteID uint `json:"websiteId" validate:"required"`
Params interface{} `json:"params"`
}
type NginxRewriteReq struct {
WebsiteID uint `json:"websiteId" validate:"required"`
Name string `json:"name" validate:"required"`
}
type NginxRewriteUpdate struct {
WebsiteID uint `json:"websiteId" validate:"required"`
Name string `json:"name" validate:"required"`
Content string `json:"content" validate:"required"`
}
type NginxProxyUpdate struct {
WebsiteID uint `json:"websiteID" validate:"required"`
Content string `json:"content" validate:"required"`
Name string `json:"name" validate:"required"`
}
type NginxAuthUpdate struct {
WebsiteID uint `json:"websiteID" validate:"required"`
Operate string `json:"operate" validate:"required"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Remark string `json:"remark"`
}
type NginxAuthReq struct {
WebsiteID uint `json:"websiteID" validate:"required"`
}
type NginxCommonReq struct {
WebsiteID uint `json:"websiteID" validate:"required"`
}
type NginxAntiLeechUpdate struct {
WebsiteID uint `json:"websiteID" validate:"required"`
Extends string `json:"extends" validate:"required"`
Return string `json:"return" validate:"required"`
Enable bool `json:"enable" validate:"required"`
ServerNames []string `json:"serverNames"`
Cache bool `json:"cache"`
CacheTime int `json:"cacheTime"`
CacheUint string `json:"cacheUint"`
NoneRef bool `json:"noneRef"`
LogEnable bool `json:"logEnable"`
Blocked bool `json:"blocked"`
}
+32
View File
@@ -0,0 +1,32 @@
package request
import "github.com/1Panel-dev/1Panel/backend/app/dto"
type RuntimeSearch struct {
dto.PageInfo
Type string `json:"type"`
Name string `json:"name"`
Status string `json:"status"`
}
type RuntimeCreate struct {
AppDetailID uint `json:"appDetailId"`
Name string `json:"name"`
Params map[string]interface{} `json:"params"`
Resource string `json:"resource"`
Image string `json:"image"`
Type string `json:"type"`
Version string `json:"version"`
}
type RuntimeDelete struct {
ID uint `json:"id"`
}
type RuntimeUpdate struct {
Name string `json:"name"`
ID uint `json:"id"`
Params map[string]interface{} `json:"params"`
Image string `json:"image"`
Version string `json:"version"`
}
+58
View File
@@ -18,17 +18,28 @@ type WebsiteCreate struct {
OtherDomains string `json:"otherDomains"`
Proxy string `json:"proxy"`
WebsiteGroupID uint `json:"webSiteGroupID" validate:"required"`
IPV6 bool `json:"IPV6"`
AppType string `json:"appType" validate:"oneof=new installed"`
AppInstall NewAppInstall `json:"appInstall"`
AppID uint `json:"appID"`
AppInstallID uint `json:"appInstallID"`
RuntimeID uint `json:"runtimeID"`
RuntimeConfig
}
type RuntimeConfig struct {
ProxyType string `json:"proxyType"`
Port int `json:"port"`
}
type NewAppInstall struct {
Name string `json:"name"`
AppDetailId uint `json:"appDetailID"`
Params map[string]interface{} `json:"params"`
AppContainerConfig
}
type WebsiteInstallCheckReq struct {
@@ -41,6 +52,7 @@ type WebsiteUpdate struct {
Remark string `json:"remark"`
WebsiteGroupID uint `json:"webSiteGroupID" validate:"required"`
ExpireDate string `json:"expireDate"`
IPV6 bool `json:"IPV6"`
}
type WebsiteDelete struct {
@@ -126,3 +138,49 @@ type WebsiteLogReq struct {
type WebsiteDefaultUpdate struct {
ID uint `json:"id" validate:"required"`
}
type WebsitePHPConfigUpdate struct {
ID uint `json:"id" validate:"required"`
Params map[string]string `json:"params"`
Scope string `json:"scope" validate:"required"`
DisableFunctions []string `json:"disableFunctions"`
UploadMaxSize string `json:"uploadMaxSize"`
}
type WebsitePHPFileUpdate struct {
ID uint `json:"id" validate:"required"`
Type string `json:"type" validate:"required"`
Content string `json:"content" validate:"required"`
}
type WebsiteUpdateDir struct {
ID uint `json:"id" validate:"required"`
SiteDir string `json:"siteDir" validate:"required"`
}
type WebsiteUpdateDirPermission struct {
ID uint `json:"id" validate:"required"`
User string `json:"user" validate:"required"`
Group string `json:"group" validate:"required"`
}
type WebsiteProxyConfig struct {
ID uint `json:"id" validate:"required"`
Operate string `json:"operate" validate:"required"`
Enable bool `json:"enable" validate:"required"`
Cache bool `json:"cache" validate:"required"`
CacheTime int `json:"cacheTime" validate:"required"`
CacheUnit string `json:"cacheUnit" validate:"required"`
Name string `json:"name" validate:"required"`
Modifier string `json:"modifier" validate:"required"`
Match string `json:"match" validate:"required"`
ProxyPass string `json:"proxyPass" validate:"required"`
ProxyHost string `json:"proxyHost" validate:"required"`
Content string `json:"content"`
FilePath string `json:"filePath"`
Replaces map[string]string `json:"replaces"`
}
type WebsiteProxyReq struct {
ID uint `json:"id" validate:"required"`
}
+5
View File
@@ -44,3 +44,8 @@ type WebsiteDnsAccountUpdate struct {
type WebsiteResourceReq struct {
ID uint `json:"id" validate:"required"`
}
type WebsiteSSLUpdate struct {
ID uint `json:"id" validate:"required"`
AutoRenew bool `json:"autoRenew" validate:"required"`
}
+32 -13
View File
@@ -1,8 +1,10 @@
package response
import (
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"time"
"github.com/1Panel-dev/1Panel/backend/app/model"
)
type AppRes struct {
@@ -11,15 +13,15 @@ type AppRes struct {
}
type AppUpdateRes struct {
Version string `json:"version"`
CanUpdate bool `json:"canUpdate"`
DownloadPath string `json:"downloadPath"`
CanUpdate bool `json:"canUpdate"`
AppStoreLastModified int `json:"appStoreLastModified"`
}
type AppDTO struct {
model.App
Versions []string `json:"versions"`
Tags []model.Tag `json:"tags"`
Installed bool `json:"installed"`
Versions []string `json:"versions"`
Tags []model.Tag `json:"tags"`
}
type TagDTO struct {
@@ -43,6 +45,7 @@ type AppDetailDTO struct {
model.AppDetail
Enable bool `json:"enable"`
Params interface{} `json:"params"`
Image string `json:"image"`
}
type AppInstalledDTO struct {
@@ -52,6 +55,13 @@ type AppInstalledDTO struct {
AppName string `json:"appName"`
Icon string `json:"icon"`
CanUpdate bool `json:"canUpdate"`
Path string `json:"path"`
}
type DatabaseConn struct {
Password string `json:"password"`
ServiceName string `json:"serviceName"`
Port int64 `json:"port"`
}
type AppService struct {
@@ -61,11 +71,20 @@ type AppService struct {
}
type AppParam struct {
Value interface{} `json:"value"`
Edit bool `json:"edit"`
Key string `json:"key"`
Rule string `json:"rule"`
LabelZh string `json:"labelZh"`
LabelEn string `json:"labelEn"`
Type string `json:"type"`
Value interface{} `json:"value"`
Edit bool `json:"edit"`
Key string `json:"key"`
Rule string `json:"rule"`
LabelZh string `json:"labelZh"`
LabelEn string `json:"labelEn"`
Type string `json:"type"`
Values interface{} `json:"values"`
ShowValue string `json:"showValue"`
Required bool `json:"required"`
Multiple bool `json:"multiple"`
}
type AppConfig struct {
Params []AppParam `json:"params"`
request.AppContainerConfig
}
+20
View File
@@ -1,5 +1,7 @@
package response
import "github.com/1Panel-dev/1Panel/backend/app/dto"
type NginxStatus struct {
Active string `json:"active"`
Accepts string `json:"accepts"`
@@ -14,3 +16,21 @@ type NginxParam struct {
Name string `json:"name"`
Params []string `json:"params"`
}
type NginxAuthRes struct {
Enable bool `json:"enable"`
Items []dto.NginxAuth `json:"items"`
}
type NginxAntiLeechRes struct {
Enable bool `json:"enable"`
Extends string `json:"extends"`
Return string `json:"return"`
ServerNames []string `json:"serverNames"`
Cache bool `json:"cache"`
CacheTime int `json:"cacheTime"`
CacheUint string `json:"cacheUint"`
NoneRef bool `json:"noneRef"`
LogEnable bool `json:"logEnable"`
Blocked bool `json:"blocked"`
}
+9
View File
@@ -0,0 +1,9 @@
package response
import "github.com/1Panel-dev/1Panel/backend/app/model"
type RuntimeRes struct {
model.Runtime
AppParams []AppParam `json:"appParams"`
AppID uint `json:"appId"`
}
+11
View File
@@ -10,6 +10,7 @@ type WebsiteDTO struct {
AccessLogPath string `json:"accessLogPath"`
SitePath string `json:"sitePath"`
AppName string `json:"appName"`
RuntimeName string `json:"runtimeName"`
}
type WebsitePreInstallCheck struct {
@@ -42,3 +43,13 @@ type WebsiteLog struct {
Enable bool `json:"enable"`
Content string `json:"content"`
}
type PHPConfig struct {
Params map[string]string `json:"params"`
DisableFunctions []string `json:"disableFunctions"`
UploadMaxSize string `json:"uploadMaxSize"`
}
type NginxRewriteRes struct {
Content string `json:"content"`
}
+38 -7
View File
@@ -9,6 +9,8 @@ type SettingInfo struct {
SessionTimeout string `json:"sessionTimeout"`
LocalTime string `json:"localTime"`
TimeZone string `json:"timeZone"`
NtpSite string `json:"ntpSite"`
Port string `json:"port"`
PanelName string `json:"panelName"`
@@ -16,6 +18,10 @@ type SettingInfo struct {
Language string `json:"language"`
ServerPort string `json:"serverPort"`
SSL string `json:"ssl"`
SSLType string `json:"sslType"`
BindDomain string `json:"bindDomain"`
AllowIPs string `json:"allowIPs"`
SecurityEntrance string `json:"securityEntrance"`
ExpirationDays string `json:"expirationDays"`
ExpirationTime string `json:"expirationTime"`
@@ -24,6 +30,7 @@ type SettingInfo struct {
MFASecret string `json:"mfaSecret"`
MonitorStatus string `json:"monitorStatus"`
MonitorInterval string `json:"monitorInterval"`
MonitorStoreDays string `json:"monitorStoreDays"`
MessageType string `json:"messageType"`
@@ -31,7 +38,8 @@ type SettingInfo struct {
WeChatVars string `json:"weChatVars"`
DingVars string `json:"dingVars"`
AppStoreVersion string `json:"appStoreVersion"`
AppStoreVersion string `json:"appStoreVersion"`
AppStoreLastModified string `json:"appStoreLastModified"`
}
type SettingUpdate struct {
@@ -39,6 +47,23 @@ type SettingUpdate struct {
Value string `json:"value"`
}
type SSLUpdate struct {
SSLType string `json:"sslType"`
Domain string `json:"domain"`
SSL string `json:"ssl" validate:"required,oneof=enable disable"`
Cert string `json:"cert"`
Key string `json:"key"`
SSLID uint `json:"sslID"`
}
type SSLInfo struct {
Domain string `json:"domain"`
Timeout string `json:"timeout"`
RootPath string `json:"rootPath"`
Cert string `json:"cert"`
Key string `json:"key"`
SSLID uint `json:"sslID"`
}
type PasswordUpdate struct {
OldPassword string `json:"oldPassword" validate:"required"`
NewPassword string `json:"newPassword" validate:"required"`
@@ -49,8 +74,8 @@ type PortUpdate struct {
}
type SnapshotCreate struct {
From string `json:"from" validate:"required,oneof=OSS S3 SFTP MINIO"`
Description string `json:"description"`
From string `json:"from" validate:"required,oneof=OSS S3 SFTP MINIO COS KODO"`
Description string `json:"description" validate:"max=256"`
}
type SnapshotRecover struct {
IsNew bool `json:"isNew"`
@@ -60,12 +85,12 @@ type SnapshotRecover struct {
type SnapshotImport struct {
From string `json:"from"`
Names []string `json:"names"`
Description string `json:"description"`
Description string `json:"description" validate:"max=256"`
}
type SnapshotInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Description string `json:"description" validate:"max=256"`
From string `json:"from"`
Status string `json:"status"`
Message string `json:"message"`
@@ -82,9 +107,15 @@ type SnapshotInfo struct {
}
type UpgradeInfo struct {
NewVersion string `json:"newVersion"`
ReleaseNote string `json:"releaseNote"`
NewVersion string `json:"newVersion"`
LatestVersion string `json:"latestVersion"`
ReleaseNote string `json:"releaseNote"`
}
type SyncTime struct {
NtpSite string `json:"ntpSite"`
}
type Upgrade struct {
Version string `json:"version"`
}
+49
View File
@@ -0,0 +1,49 @@
package dto
import "time"
type SSHInfo struct {
Status string `json:"status"`
Message string `json:"message"`
Port string `json:"port"`
ListenAddress string `json:"listenAddress"`
PasswordAuthentication string `json:"passwordAuthentication"`
PubkeyAuthentication string `json:"pubkeyAuthentication"`
PermitRootLogin string `json:"permitRootLogin"`
UseDNS string `json:"useDNS"`
}
type GenerateSSH struct {
EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
Password string `json:"password"`
}
type GenerateLoad struct {
EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
}
type SSHConf struct {
File string `json:"file"`
}
type SearchSSHLog struct {
PageInfo
Info string `json:"info"`
Status string `json:"Status" validate:"required,oneof=Success Failed All"`
}
type SSHLog struct {
Logs []SSHHistory `json:"logs"`
TotalCount int `json:"totalCount"`
SuccessfulCount int `json:"successfulCount"`
FailedCount int `json:"failedCount"`
}
type SSHHistory struct {
Date time.Time `json:"date"`
DateStr string `json:"dateStr"`
Area string `json:"area"`
User string `json:"user"`
AuthMode string `json:"authMode"`
Address string `json:"address"`
Port string `json:"port"`
Status string `json:"status"`
Message string `json:"message"`
}
+21 -17
View File
@@ -2,21 +2,25 @@ package model
type App struct {
BaseModel
Name string `json:"name" gorm:"type:varchar(64);not null"`
Key string `json:"key" gorm:"type:varchar(64);not null;uniqueIndex"`
ShortDescZh string `json:"shortDescZh" gorm:"type:longtext;"`
ShortDescEn string `json:"shortDescEn" gorm:"type:longtext;"`
Icon string `json:"icon" gorm:"type:longtext;"`
Type string `json:"type" gorm:"type:varchar(64);not null"`
Status string `json:"status" gorm:"type:varchar(64);not null"`
Required string `json:"required" gorm:"type:varchar(64);not null"`
CrossVersionUpdate bool `json:"crossVersionUpdate"`
Limit int `json:"limit" gorm:"type:Integer;not null"`
Website string `json:"website" gorm:"type:varchar(64);not null"`
Github string `json:"github" gorm:"type:varchar(64);not null"`
Document string `json:"document" gorm:"type:varchar(64);not null"`
Recommend int `json:"recommend" gorm:"type:Integer;not null"`
Details []AppDetail `json:"-" gorm:"-:migration"`
TagsKey []string `json:"-" gorm:"-"`
AppTags []AppTag `json:"-" gorm:"-:migration"`
Name string `json:"name" gorm:"type:varchar(64);not null"`
Key string `json:"key" gorm:"type:varchar(64);not null;"`
ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh" gorm:"type:longtext;"`
ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn" gorm:"type:longtext;"`
Icon string `json:"icon" gorm:"type:longtext;"`
Type string `json:"type" gorm:"type:varchar(64);not null"`
Status string `json:"status" gorm:"type:varchar(64);not null"`
Required string `json:"required" gorm:"type:varchar(64);"`
CrossVersionUpdate bool `json:"crossVersionUpdate"`
Limit int `json:"limit" gorm:"type:Integer;not null"`
Website string `json:"website" gorm:"type:varchar(64);not null"`
Github string `json:"github" gorm:"type:varchar(64);not null"`
Document string `json:"document" gorm:"type:varchar(64);not null"`
Recommend int `json:"recommend" gorm:"type:Integer;not null"`
Resource string `json:"resource" gorm:"type:varchar;not null;default:remote"`
ReadMe string `json:"readMe" gorm:"type:varchar;"`
LastModified int `json:"lastModified" gorm:"type:Integer;"`
Details []AppDetail `json:"-" gorm:"-:migration"`
TagsKey []string `json:"tags" yaml:"tags" gorm:"-"`
AppTags []AppTag `json:"-" gorm:"-:migration"`
}
+10 -7
View File
@@ -2,11 +2,14 @@ package model
type AppDetail struct {
BaseModel
AppId uint `json:"appId" gorm:"type:integer;not null"`
Version string `json:"version" gorm:"type:varchar(64);not null"`
Params string `json:"-" gorm:"type:longtext;"`
DockerCompose string `json:"-" gorm:"type:longtext;not null"`
Readme string `json:"readme" gorm:"type:longtext;"`
Status string `json:"status" gorm:"type:varchar(64);not null"`
LastVersion string `json:"lastVersion" gorm:"type:varchar(64);"`
AppId uint `json:"appId" gorm:"type:integer;not null"`
Version string `json:"version" gorm:"type:varchar(64);not null"`
Params string `json:"-" gorm:"type:longtext;"`
DockerCompose string `json:"dockerCompose" gorm:"type:longtext;"`
Status string `json:"status" gorm:"type:varchar(64);not null"`
LastVersion string `json:"lastVersion" gorm:"type:varchar(64);"`
LastModified int `json:"lastModified" gorm:"type:integer;"`
DownloadUrl string `json:"downloadUrl" gorm:"type:varchar;"`
DownloadCallBackUrl string `json:"downloadCallBackUrl" gorm:"type:longtext;"`
Update bool `json:"update"`
}
+15 -2
View File
@@ -2,6 +2,7 @@ package model
import (
"path"
"strings"
"github.com/1Panel-dev/1Panel/backend/constant"
)
@@ -26,9 +27,21 @@ type AppInstall struct {
}
func (i *AppInstall) GetPath() string {
return path.Join(constant.AppInstallDir, i.App.Key, i.Name)
return path.Join(i.getAppPath(), i.Name)
}
func (i *AppInstall) GetComposePath() string {
return path.Join(constant.AppInstallDir, i.App.Key, i.Name, "docker-compose.yml")
return path.Join(i.getAppPath(), i.Name, "docker-compose.yml")
}
func (i *AppInstall) GetEnvPath() string {
return path.Join(i.getAppPath(), i.Name, ".env")
}
func (i *AppInstall) getAppPath() string {
if i.App.Resource == constant.AppResourceLocal {
return path.Join(constant.LocalAppInstallDir, strings.TrimPrefix(i.App.Key, constant.AppResourceLocal))
} else {
return path.Join(constant.AppInstallDir, i.App.Key)
}
}
+1
View File
@@ -13,6 +13,7 @@ type Cronjob struct {
Day uint64 `gorm:"type:decimal" json:"day"`
Hour uint64 `gorm:"type:decimal" json:"hour"`
Minute uint64 `gorm:"type:decimal" json:"minute"`
Second uint64 `gorm:"type:decimal" json:"second"`
Script string `gorm:"longtext" json:"script"`
Website string `gorm:"type:varchar(64)" json:"website"`
+11 -8
View File
@@ -2,14 +2,17 @@ package model
type Host struct {
BaseModel
GroupID uint `gorm:"type:decimal;not null" json:"group_id"`
Name string `gorm:"type:varchar(64);not null" json:"name"`
Addr string `gorm:"type:varchar(16);not null" json:"addr"`
Port int `gorm:"type:decimal;not null" json:"port"`
User string `gorm:"type:varchar(64);not null" json:"user"`
AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"`
Password string `gorm:"type:varchar(64)" json:"password"`
PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"`
GroupID uint `gorm:"type:decimal;not null" json:"group_id"`
Name string `gorm:"type:varchar(64);not null" json:"name"`
Addr string `gorm:"type:varchar(16);not null" json:"addr"`
Port int `gorm:"type:decimal;not null" json:"port"`
User string `gorm:"type:varchar(64);not null" json:"user"`
AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"`
Password string `gorm:"type:varchar(64)" json:"password"`
PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"`
PassPhrase string `gorm:"type:varchar(256)" json:"passPhrase"`
RememberPassword bool `json:"rememberPassword"`
Description string `gorm:"type:varchar(256)" json:"description"`
}
+17
View File
@@ -0,0 +1,17 @@
package model
type Runtime struct {
BaseModel
Name string `gorm:"type:varchar;not null" json:"name"`
AppDetailID uint `gorm:"type:integer" json:"appDetailId"`
Image string `gorm:"type:varchar" json:"image"`
WorkDir string `gorm:"type:varchar" json:"workDir"`
DockerCompose string `gorm:"type:varchar" json:"dockerCompose"`
Env string `gorm:"type:varchar" json:"env"`
Params string `gorm:"type:varchar" json:"params"`
Version string `gorm:"type:varchar;not null" json:"version"`
Type string `gorm:"type:varchar;not null" json:"type"`
Status string `gorm:"type:varchar;not null" json:"status"`
Resource string `gorm:"type:varchar;not null" json:"resource"`
Message string `gorm:"type:longtext;" json:"message"`
}
+28 -17
View File
@@ -4,23 +4,34 @@ import "time"
type Website struct {
BaseModel
Protocol string `gorm:"type:varchar(64);not null" json:"protocol"`
PrimaryDomain string `gorm:"type:varchar(128);not null" json:"primaryDomain"`
Type string `gorm:"type:varchar(64);not null" json:"type"`
Alias string `gorm:"type:varchar(128);not null" json:"alias"`
Remark string `gorm:"type:longtext;" json:"remark"`
Status string `gorm:"type:varchar(64);not null" json:"status"`
HttpConfig string `gorm:"type:varchar(64);not null" json:"httpConfig"`
ExpireDate time.Time `json:"expireDate"`
AppInstallID uint `gorm:"type:integer" json:"appInstallId"`
WebsiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"`
WebsiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"`
Proxy string `gorm:"type:varchar(128);not null" json:"proxy"`
ErrorLog bool `json:"errorLog"`
AccessLog bool `json:"accessLog"`
DefaultServer bool `json:"defaultServer"`
Domains []WebsiteDomain `json:"domains" gorm:"-:migration"`
WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"`
Protocol string `gorm:"type:varchar;not null" json:"protocol"`
PrimaryDomain string `gorm:"type:varchar;not null" json:"primaryDomain"`
Type string `gorm:"type:varchar;not null" json:"type"`
Alias string `gorm:"type:varchar;not null" json:"alias"`
Remark string `gorm:"type:longtext;" json:"remark"`
Status string `gorm:"type:varchar;not null" json:"status"`
HttpConfig string `gorm:"type:varchar;not null" json:"httpConfig"`
ExpireDate time.Time `json:"expireDate"`
Proxy string `gorm:"type:varchar;" json:"proxy"`
ProxyType string `gorm:"type:varchar;" json:"proxyType"`
SiteDir string `gorm:"type:varchar;" json:"siteDir"`
ErrorLog bool `json:"errorLog"`
AccessLog bool `json:"accessLog"`
DefaultServer bool `json:"defaultServer"`
IPV6 bool `json:"IPV6"`
Rewrite string `gorm:"type:varchar" json:"rewrite"`
WebsiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"`
WebsiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"`
RuntimeID uint `gorm:"type:integer" json:"runtimeID"`
AppInstallID uint `gorm:"type:integer" json:"appInstallId"`
User string `gorm:"type:varchar;" json:"user"`
Group string `gorm:"type:varchar;" json:"group"`
Domains []WebsiteDomain `json:"domains" gorm:"-:migration"`
WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"`
}
func (w Website) TableName() string {
-11
View File
@@ -1,11 +0,0 @@
package model
type WebsiteGroup struct {
BaseModel
Name string `gorm:"type:varchar(64);not null" json:"name"`
Default bool `json:"default"`
}
func (w WebsiteGroup) TableName() string {
return "website_groups"
}
+31 -1
View File
@@ -11,6 +11,26 @@ import (
type AppRepo struct {
}
type IAppRepo interface {
WithKey(key string) DBOption
WithType(typeStr string) DBOption
OrderByRecommend() DBOption
GetRecommend() DBOption
WithResource(resource string) DBOption
Page(page, size int, opts ...DBOption) (int64, []model.App, error)
GetFirst(opts ...DBOption) (model.App, error)
GetBy(opts ...DBOption) ([]model.App, error)
BatchCreate(ctx context.Context, apps []model.App) error
GetByKey(ctx context.Context, key string) (model.App, error)
Create(ctx context.Context, app *model.App) error
Save(ctx context.Context, app *model.App) error
BatchDelete(ctx context.Context, apps []model.App) error
}
func NewIAppRepo() IAppRepo {
return &AppRepo{}
}
func (a AppRepo) WithKey(key string) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("key = ?", key)
@@ -35,12 +55,18 @@ func (a AppRepo) GetRecommend() DBOption {
}
}
func (a AppRepo) WithResource(resource string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("resource = ?", resource)
}
}
func (a AppRepo) Page(page, size int, opts ...DBOption) (int64, []model.App, error) {
var apps []model.App
db := getDb(opts...).Model(&model.App{})
count := int64(0)
db = db.Count(&count)
err := db.Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
err := db.Debug().Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
return count, apps, err
}
@@ -81,3 +107,7 @@ func (a AppRepo) Create(ctx context.Context, app *model.App) error {
func (a AppRepo) Save(ctx context.Context, app *model.App) error {
return getTx(ctx).Omit(clause.Associations).Save(app).Error
}
func (a AppRepo) BatchDelete(ctx context.Context, apps []model.App) error {
return getTx(ctx).Omit(clause.Associations).Delete(&apps).Error
}
+21
View File
@@ -4,11 +4,28 @@ import (
"context"
"github.com/1Panel-dev/1Panel/backend/app/model"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type AppDetailRepo struct {
}
type IAppDetailRepo interface {
WithVersion(version string) DBOption
WithAppId(id uint) DBOption
GetFirst(opts ...DBOption) (model.AppDetail, error)
Update(ctx context.Context, detail model.AppDetail) error
BatchCreate(ctx context.Context, details []model.AppDetail) error
DeleteByAppIds(ctx context.Context, appIds []uint) error
GetBy(opts ...DBOption) ([]model.AppDetail, error)
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
BatchDelete(ctx context.Context, appDetails []model.AppDetail) error
}
func NewIAppDetailRepo() IAppDetailRepo {
return &AppDetailRepo{}
}
func (a AppDetailRepo) WithVersion(version string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("version = ?", version)
@@ -51,3 +68,7 @@ func (a AppDetailRepo) BatchUpdateBy(maps map[string]interface{}, opts ...DBOpti
}
return db.Updates(&maps).Error
}
func (a AppDetailRepo) BatchDelete(ctx context.Context, appDetails []model.AppDetail) error {
return getTx(ctx).Omit(clause.Associations).Delete(&appDetails).Error
}
+61 -5
View File
@@ -3,6 +3,7 @@ package repo
import (
"context"
"encoding/json"
"gorm.io/gorm/clause"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/global"
@@ -11,6 +12,33 @@ import (
type AppInstallRepo struct{}
type IAppInstallRepo interface {
WithDetailIdsIn(detailIds []uint) DBOption
WithDetailIdNotIn(detailIds []uint) DBOption
WithAppId(appId uint) DBOption
WithAppIdsIn(appIds []uint) DBOption
WithStatus(status string) DBOption
WithServiceName(serviceName string) DBOption
WithContainerName(containerName string) DBOption
WithPort(port int) DBOption
WithIdNotInWebsite() DBOption
WithIDNotIs(id uint) DBOption
ListBy(opts ...DBOption) ([]model.AppInstall, error)
GetFirst(opts ...DBOption) (model.AppInstall, error)
Create(ctx context.Context, install *model.AppInstall) error
Save(ctx context.Context, install *model.AppInstall) error
DeleteBy(opts ...DBOption) error
Delete(ctx context.Context, install model.AppInstall) error
Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error)
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
LoadBaseInfo(key string, name string) (*RootInfo, error)
GetFirstByCtx(ctx context.Context, opts ...DBOption) (model.AppInstall, error)
}
func NewIAppInstallRepo() IAppInstallRepo {
return &AppInstallRepo{}
}
func (a *AppInstallRepo) WithDetailIdsIn(detailIds []uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("app_detail_id in (?)", detailIds)
@@ -29,6 +57,12 @@ func (a *AppInstallRepo) WithAppId(appId uint) DBOption {
}
}
func (a *AppInstallRepo) WithIDNotIs(id uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("id != ?", id)
}
}
func (a *AppInstallRepo) WithAppIdsIn(appIds []uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("app_id in (?)", appIds)
@@ -47,6 +81,12 @@ func (a *AppInstallRepo) WithServiceName(serviceName string) DBOption {
}
}
func (a *AppInstallRepo) WithContainerName(containerName string) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("container_name = ?", containerName)
}
}
func (a *AppInstallRepo) WithPort(port int) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("https_port = ? or http_port = ?", port, port)
@@ -73,13 +113,20 @@ func (a *AppInstallRepo) GetFirst(opts ...DBOption) (model.AppInstall, error) {
return install, err
}
func (a *AppInstallRepo) Create(ctx context.Context, install *model.AppInstall) error {
db := getTx(ctx).Model(&model.AppInstall{})
return db.Create(&install).Error
func (a *AppInstallRepo) GetFirstByCtx(ctx context.Context, opts ...DBOption) (model.AppInstall, error) {
var install model.AppInstall
db := getTx(ctx, opts...).Model(&model.AppInstall{})
err := db.Preload("App").First(&install).Error
return install, err
}
func (a *AppInstallRepo) Save(install *model.AppInstall) error {
return getDb().Save(&install).Error
func (a *AppInstallRepo) Create(ctx context.Context, install *model.AppInstall) error {
db := getTx(ctx).Model(&model.AppInstall{})
return db.Omit(clause.Associations).Create(&install).Error
}
func (a *AppInstallRepo) Save(ctx context.Context, install *model.AppInstall) error {
return getTx(ctx).Omit(clause.Associations).Save(&install).Error
}
func (a *AppInstallRepo) DeleteBy(opts ...DBOption) error {
@@ -112,8 +159,11 @@ type RootInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
Port int64 `json:"port"`
HttpsPort int64 `json:"httpsPort"`
Password string `json:"password"`
UserPassword string `json:"userPassword"`
ContainerName string `json:"containerName"`
ServiceName string `json:"serviceName"`
Param string `json:"param"`
Env string `json:"env"`
Key string `json:"key"`
@@ -146,8 +196,14 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
if ok {
info.Password = password
}
userPassword, ok := envMap["PANEL_DB_USER_PASSWORD"].(string)
if ok {
info.UserPassword = userPassword
}
info.Port = int64(appInstall.HttpPort)
info.HttpsPort = int64(appInstall.HttpsPort)
info.ID = appInstall.ID
info.ServiceName = appInstall.ServiceName
info.ContainerName = appInstall.ContainerName
info.Name = appInstall.Name
info.Env = appInstall.Env
+14
View File
@@ -11,6 +11,20 @@ import (
type AppInstallResourceRpo struct {
}
type IAppInstallResourceRpo interface {
WithAppInstallId(appInstallId uint) DBOption
WithLinkId(linkId uint) DBOption
WithResourceId(resourceId uint) DBOption
GetBy(opts ...DBOption) ([]model.AppInstallResource, error)
GetFirst(opts ...DBOption) (model.AppInstallResource, error)
Create(ctx context.Context, resource *model.AppInstallResource) error
DeleteBy(ctx context.Context, opts ...DBOption) error
}
func NewIAppInstallResourceRpo() IAppInstallResourceRpo {
return &AppInstallResourceRpo{}
}
func (a AppInstallResourceRpo) WithAppInstallId(appInstallId uint) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("app_install_id = ?", appInstallId)
+12
View File
@@ -8,6 +8,18 @@ import (
type AppTagRepo struct {
}
type IAppTagRepo interface {
BatchCreate(ctx context.Context, tags []*model.AppTag) error
DeleteByAppIds(ctx context.Context, appIds []uint) error
DeleteAll(ctx context.Context) error
GetByAppId(appId uint) ([]model.AppTag, error)
GetByTagIds(tagIds []uint) ([]model.AppTag, error)
}
func NewIAppTagRepo() IAppTagRepo {
return &AppTagRepo{}
}
func (a AppTagRepo) BatchCreate(ctx context.Context, tags []*model.AppTag) error {
return getTx(ctx).Create(&tags).Error
}
+2
View File
@@ -20,6 +20,8 @@ type IBackupRepo interface {
Delete(opts ...DBOption) error
DeleteRecord(ctx context.Context, opts ...DBOption) error
WithByDetailName(detailName string) DBOption
WithByFileName(fileName string) DBOption
WithByType(backupType string) DBOption
}
func NewIBackupRepo() IBackupRepo {
+1
View File
@@ -15,6 +15,7 @@ type ICommandRepo interface {
Create(command *model.Command) error
Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error
Get(opts ...DBOption) (model.Command, error)
}
func NewICommandRepo() ICommandRepo {
+5
View File
@@ -21,10 +21,15 @@ type ICommonRepo interface {
WithIdsIn(ids []uint) DBOption
WithByDate(startTime, endTime time.Time) DBOption
WithByStartDate(startTime time.Time) DBOption
WithByStatus(status string) DBOption
}
type CommonRepo struct{}
func NewCommonRepo() ICommonRepo {
return &CommonRepo{}
}
func (c *CommonRepo) WithByID(id uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("id = ?", id)
+1
View File
@@ -17,6 +17,7 @@ type IComposeTemplateRepo interface {
CreateRecord(compose *model.Compose) error
DeleteRecord(opts ...DBOption) error
ListRecord() ([]model.Compose, error)
}
func NewIComposeTemplateRepo() IComposeTemplateRepo {
+18 -2
View File
@@ -20,12 +20,15 @@ type ICronjobRepo interface {
Page(limit, offset int, opts ...DBOption) (int64, []model.Cronjob, error)
Create(cronjob *model.Cronjob) error
WithByJobID(id int) DBOption
WithByBackupID(id uint) DBOption
WithByRecordDropID(id int) DBOption
Save(id uint, cronjob model.Cronjob) error
Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error
DeleteRecord(opts ...DBOption) error
StartRecords(cronjobID uint, targetPath string) model.JobRecords
StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords
EndRecords(record model.JobRecords, status, message, records string)
PageRecords(page, size int, opts ...DBOption) (int64, []model.JobRecords, error)
}
func NewICronjobRepo() ICronjobRepo {
@@ -112,10 +115,23 @@ func (c *CronjobRepo) WithByJobID(id int) DBOption {
}
}
func (u *CronjobRepo) StartRecords(cronjobID uint, targetPath string) model.JobRecords {
func (c *CronjobRepo) WithByBackupID(id uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("target_dir_id = ?", id)
}
}
func (c *CronjobRepo) WithByRecordDropID(id int) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("id < ?", id)
}
}
func (u *CronjobRepo) StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords {
var record model.JobRecords
record.StartTime = time.Now()
record.CronjobID = cronjobID
record.FromLocal = fromLocal
record.Status = constant.StatusWaiting
if err := global.DB.Create(&record).Error; err != nil {
global.LOG.Errorf("create record status failed, err: %v", err)
+5
View File
@@ -19,6 +19,7 @@ type IMysqlRepo interface {
Delete(ctx context.Context, opts ...DBOption) error
Update(id uint, vars map[string]interface{}) error
UpdateDatabaseInfo(id uint, vars map[string]interface{}) error
DeleteAll(ctx context.Context) error
}
func NewIMysqlRepo() IMysqlRepo {
@@ -65,6 +66,10 @@ func (u *MysqlRepo) Delete(ctx context.Context, opts ...DBOption) error {
return getTx(ctx, opts...).Delete(&model.DatabaseMysql{}).Error
}
func (u *MysqlRepo) DeleteAll(ctx context.Context) error {
return getTx(ctx).Where("1 = 1").Delete(&model.DatabaseMysql{}).Error
}
func (u *MysqlRepo) Update(id uint, vars map[string]interface{}) error {
return global.DB.Model(&model.DatabaseMysql{}).Where("id = ?", id).Updates(vars).Error
}
-30
View File
@@ -1,30 +0,0 @@
package repo
type RepoGroup struct {
CommonRepo
AppRepo
AppTagRepo
TagRepo
AppDetailRepo
AppInstallRepo
AppInstallResourceRpo
ImageRepoRepo
ComposeTemplateRepo
MysqlRepo
CronjobRepo
HostRepo
CommandRepo
GroupRepo
SettingRepo
BackupRepo
WebsiteRepo
WebsiteDomainRepo
WebsiteGroupRepo
WebsiteDnsAccountRepo
WebsiteSSLRepo
WebsiteAcmeAccountRepo
LogRepo
SnapshotRepo
}
var RepoGroupApp = new(RepoGroup)
+3 -3
View File
@@ -14,7 +14,7 @@ type IGroupRepo interface {
Create(group *model.Group) error
Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error
CancelDefault() error
CancelDefault(groupType string) error
WithByIsDefault(isDefault bool) DBOption
}
@@ -64,6 +64,6 @@ func (u *GroupRepo) Delete(opts ...DBOption) error {
return db.Delete(&model.Group{}).Error
}
func (w GroupRepo) CancelDefault() error {
return global.DB.Model(&model.Group{}).Where("`is_default` = 1").Updates(map[string]interface{}{"is_default": 0}).Error
func (u *GroupRepo) CancelDefault(groupType string) error {
return global.DB.Model(&model.Group{}).Where("is_default = ? AND type = ?", 1, groupType).Updates(map[string]interface{}{"is_default": 0}).Error
}
+11 -11
View File
@@ -25,7 +25,7 @@ func NewIHostRepo() IHostRepo {
return &HostRepo{}
}
func (u *HostRepo) Get(opts ...DBOption) (model.Host, error) {
func (h *HostRepo) Get(opts ...DBOption) (model.Host, error) {
var host model.Host
db := global.DB
for _, opt := range opts {
@@ -35,7 +35,7 @@ func (u *HostRepo) Get(opts ...DBOption) (model.Host, error) {
return host, err
}
func (u *HostRepo) GetList(opts ...DBOption) ([]model.Host, error) {
func (h *HostRepo) GetList(opts ...DBOption) ([]model.Host, error) {
var hosts []model.Host
db := global.DB.Model(&model.Host{})
for _, opt := range opts {
@@ -45,7 +45,7 @@ func (u *HostRepo) GetList(opts ...DBOption) ([]model.Host, error) {
return hosts, err
}
func (u *HostRepo) Page(page, size int, opts ...DBOption) (int64, []model.Host, error) {
func (h *HostRepo) Page(page, size int, opts ...DBOption) (int64, []model.Host, error) {
var users []model.Host
db := global.DB.Model(&model.Host{})
for _, opt := range opts {
@@ -57,7 +57,7 @@ func (u *HostRepo) Page(page, size int, opts ...DBOption) (int64, []model.Host,
return count, users, err
}
func (c *HostRepo) WithByInfo(info string) DBOption {
func (h *HostRepo) WithByInfo(info string) DBOption {
return func(g *gorm.DB) *gorm.DB {
if len(info) == 0 {
return g
@@ -67,22 +67,22 @@ func (c *HostRepo) WithByInfo(info string) DBOption {
}
}
func (u *HostRepo) WithByPort(port uint) DBOption {
func (h *HostRepo) WithByPort(port uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("port = ?", port)
}
}
func (u *HostRepo) WithByUser(user string) DBOption {
func (h *HostRepo) WithByUser(user string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("user = ?", user)
}
}
func (u *HostRepo) WithByAddr(addr string) DBOption {
func (h *HostRepo) WithByAddr(addr string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("addr = ?", addr)
}
}
func (u *HostRepo) WithByGroup(group string) DBOption {
func (h *HostRepo) WithByGroup(group string) DBOption {
return func(g *gorm.DB) *gorm.DB {
if len(group) == 0 {
return g
@@ -91,15 +91,15 @@ func (u *HostRepo) WithByGroup(group string) DBOption {
}
}
func (u *HostRepo) Create(host *model.Host) error {
func (h *HostRepo) Create(host *model.Host) error {
return global.DB.Create(host).Error
}
func (u *HostRepo) Update(id uint, vars map[string]interface{}) error {
func (h *HostRepo) Update(id uint, vars map[string]interface{}) error {
return global.DB.Model(&model.Host{}).Where("id = ?", id).Updates(vars).Error
}
func (u *HostRepo) Delete(opts ...DBOption) error {
func (h *HostRepo) Delete(opts ...DBOption) error {
db := global.DB
for _, opt := range opts {
db = opt(db)
+87
View File
@@ -0,0 +1,87 @@
package repo
import (
"context"
"github.com/1Panel-dev/1Panel/backend/app/model"
"gorm.io/gorm"
)
type RuntimeRepo struct {
}
type IRuntimeRepo interface {
WithName(name string) DBOption
WithImage(image string) DBOption
WithNotId(id uint) DBOption
WithStatus(status string) DBOption
WithDetailId(id uint) DBOption
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
Create(ctx context.Context, runtime *model.Runtime) error
Save(runtime *model.Runtime) error
DeleteBy(opts ...DBOption) error
GetFirst(opts ...DBOption) (*model.Runtime, error)
}
func NewIRunTimeRepo() IRuntimeRepo {
return &RuntimeRepo{}
}
func (r *RuntimeRepo) WithName(name string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("name = ?", name)
}
}
func (r *RuntimeRepo) WithStatus(status string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("status = ?", status)
}
}
func (r *RuntimeRepo) WithImage(image string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("image = ?", image)
}
}
func (r *RuntimeRepo) WithDetailId(id uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("app_detail_id = ?", id)
}
}
func (r *RuntimeRepo) WithNotId(id uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("id != ?", id)
}
}
func (r *RuntimeRepo) Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error) {
var runtimes []model.Runtime
db := getDb(opts...).Model(&model.Runtime{})
count := int64(0)
db = db.Count(&count)
err := db.Limit(size).Offset(size * (page - 1)).Find(&runtimes).Error
return count, runtimes, err
}
func (r *RuntimeRepo) Create(ctx context.Context, runtime *model.Runtime) error {
db := getTx(ctx).Model(&model.Runtime{})
return db.Create(&runtime).Error
}
func (r *RuntimeRepo) Save(runtime *model.Runtime) error {
return getDb().Save(&runtime).Error
}
func (r *RuntimeRepo) DeleteBy(opts ...DBOption) error {
return getDb(opts...).Delete(&model.Runtime{}).Error
}
func (r *RuntimeRepo) GetFirst(opts ...DBOption) (*model.Runtime, error) {
var runtime model.Runtime
if err := getDb(opts...).First(&runtime).Error; err != nil {
return nil, err
}
return &runtime, nil
}
+28
View File
@@ -1,6 +1,8 @@
package repo
import (
"time"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/global"
"gorm.io/gorm"
@@ -14,6 +16,13 @@ type ISettingRepo interface {
Create(key, value string) error
Update(key, value string) error
WithByKey(key string) DBOption
CreateMonitorBase(model model.MonitorBase) error
BatchCreateMonitorIO(ioList []model.MonitorIO) error
BatchCreateMonitorNet(ioList []model.MonitorNetwork) error
DelMonitorBase(timeForDelete time.Time) error
DelMonitorIO(timeForDelete time.Time) error
DelMonitorNet(timeForDelete time.Time) error
}
func NewISettingRepo() ISettingRepo {
@@ -57,3 +66,22 @@ func (c *SettingRepo) WithByKey(key string) DBOption {
func (u *SettingRepo) Update(key, value string) error {
return global.DB.Model(&model.Setting{}).Where("key = ?", key).Updates(map[string]interface{}{"value": value}).Error
}
func (u *SettingRepo) CreateMonitorBase(model model.MonitorBase) error {
return global.DB.Create(&model).Error
}
func (u *SettingRepo) BatchCreateMonitorIO(ioList []model.MonitorIO) error {
return global.DB.CreateInBatches(ioList, len(ioList)).Error
}
func (u *SettingRepo) BatchCreateMonitorNet(ioList []model.MonitorNetwork) error {
return global.DB.CreateInBatches(ioList, len(ioList)).Error
}
func (u *SettingRepo) DelMonitorBase(timeForDelete time.Time) error {
return global.DB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorBase{}).Error
}
func (u *SettingRepo) DelMonitorIO(timeForDelete time.Time) error {
return global.DB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorIO{}).Error
}
func (u *SettingRepo) DelMonitorNet(timeForDelete time.Time) error {
return global.DB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorNetwork{}).Error
}
+13
View File
@@ -8,6 +8,19 @@ import (
type TagRepo struct {
}
type ITagRepo interface {
BatchCreate(ctx context.Context, tags []*model.Tag) error
DeleteAll(ctx context.Context) error
All() ([]model.Tag, error)
GetByIds(ids []uint) ([]model.Tag, error)
GetByKeys(keys []string) ([]model.Tag, error)
GetByAppId(appId uint) ([]model.Tag, error)
}
func NewITagRepo() ITagRepo {
return &TagRepo{}
}
func (t TagRepo) BatchCreate(ctx context.Context, tags []*model.Tag) error {
return getTx(ctx).Create(&tags).Error
}
+7
View File
@@ -17,6 +17,7 @@ type IWebsiteRepo interface {
WithGroupID(groupId uint) DBOption
WithDefaultServer() DBOption
WithDomainLike(domain string) DBOption
WithRuntimeID(runtimeID uint) DBOption
Page(page, size int, opts ...DBOption) (int64, []model.Website, error)
List(opts ...DBOption) ([]model.Website, error)
GetFirst(opts ...DBOption) (model.Website, error)
@@ -40,6 +41,12 @@ func (w *WebsiteRepo) WithAppInstallId(appInstallId uint) DBOption {
}
}
func (w *WebsiteRepo) WithRuntimeID(runtimeID uint) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("runtime_id = ?", runtimeID)
}
}
func (w *WebsiteRepo) WithDomain(domain string) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("primary_domain = ?", domain)

Some files were not shown because too many files have changed in this diff Show More