init:初始化仓库

main
鱼星 1 week ago
parent 6274c094d0
commit 3bda1ef628

5
.gitattributes vendored

@ -0,0 +1,5 @@
*.ts linguist-language=Go
*.js linguist-language=Go
*.css linguist-language=Go
*.scss linguist-language=Go
*.html linguist-language=Go

@ -0,0 +1,50 @@
name: 'Bug Report'
description: 'Report an Bug'
title: '[Bug] '
assignees: wanghe-fit2cloud
body:
- type: markdown
attributes:
value: "## Contact Information"
- type: input
validations:
required: false
attributes:
label: "Contact Information"
description: "The ways to quickly contact you: WeChat group number and nickname, email, etc."
- type: markdown
attributes:
value: "## Environment Information"
- type: input
validations:
required: true
attributes:
label: "1Panel Version"
description: "Log in to the 1Panel Web console and check the current version at the bottom right of the page."
- type: markdown
attributes:
value: "## Detailed information"
- type: textarea
attributes:
label: "Problem Description"
description: "Briefly describe the issue youve encountered."
validations:
required: true
- type: textarea
attributes:
label: "Steps to Reproduce"
description: "How can this issue be reproduced."
validations:
required: true
- type: textarea
attributes:
label: "The expected correct result"
- type: textarea
attributes:
label: "Related log output"
description: "Please paste any relevant log output here. It will automatically be formatted as code, so no backticks are necessary."
render: shell
- type: textarea
attributes:
label: "Additional Information"
description: "If you have any additional information to provide, you can include it here (screenshots, videos, etc., are welcome)."

@ -0,0 +1,29 @@
name: 'Feature Request'
description: 'Suggest an idea'
title: '[Feature] '
assignees: wanghe-fit2cloud
body:
- type: markdown
attributes:
value: "## Environment Information"
- type: input
validations:
required: true
attributes:
label: "1Panel Version"
description: "Log in to the 1Panel Web console and check the current version at the bottom right of the page."
- type: markdown
attributes:
value: "## Detailed information"
- type: textarea
attributes:
label: "Please describe your needs or suggestions for improvements"
validations:
required: true
- type: textarea
attributes:
label: "Please describe the solution you suggest"
- type: textarea
attributes:
label: "Additional Information"
description: "If you have any additional information to provide, you can include it here (screenshots, videos, etc., are welcome)."

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Questions & Discussions
url: https://github.com/1Panel-dev/1Panel/discussions
about: Raise questions about the installation, deployment, use and other aspects of the project.

@ -0,0 +1,9 @@
#### 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.

@ -0,0 +1,16 @@
name: General PR Handling for 1Panel
on: pull_request
permissions:
pull-requests: write
jobs:
generic_handler:
name: Add Labels to PR
if: github.repository == '1Panel-dev/1Panel'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-ecosystem/action-add-labels@v1
with:
github_token: ${{ secrets.GITHUBTOKEN }}
labels: ${{ github.base_ref }}

@ -0,0 +1,47 @@
name: Create Release And Upload assets
on:
push:
tags:
- 'v*'
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22.19.0'
- name: Build Web
run: |
cd frontend && npm install && npm run build:pro
env:
NODE_OPTIONS: --max-old-space-size=8192
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Build Release
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: '~> v2'
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
- name: Setup OSSUTIL
uses: yizhoumo/setup-ossutil@v2
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.18'
- name: Upload Assets to OSS
run: ossutil cp -r dist/ oss://resource-fit2cloud-com/1panel/package/v2/stable/${{ github.ref_name }}/release/ --include "*.tar.gz" --include "checksums.txt" --only-current-dir --force

@ -0,0 +1,45 @@
name: Create Release And Upload Cloudflare R2
on:
push:
tags:
- 'v*'
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22.19.0'
- name: Build Web
run: |
cd frontend && npm install && npm run build:pro
env:
NODE_OPTIONS: --max-old-space-size=8192
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Build Release
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: '~> v2'
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
- name: Setup Rclone
uses: AnimMouse/setup-rclone@v1
with:
rclone_config: ${{ secrets.RCLONE_CONFIG }}
- name: Upload to Cloudflare R2
run: |
rclone copy dist/ cloudflare_r2:package/v2/stable/${{ github.ref_name }}/release/ --include "*.tar.gz" --include "checksums.txt" --progress

@ -0,0 +1,14 @@
name: Issue Translator
on:
issue_comment:
types: [created]
issues:
types: [opened]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: usthe/issues-translate-action@v2.7
with:
IS_MODIFY_TITLE: true
BOT_GITHUB_TOKEN: ${{ secrets.ISSUE_TRANSLATOR_TOKEN }}

@ -0,0 +1,25 @@
name: LLM Code Review
permissions:
contents: read
pull-requests: write
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
llm-code-review:
runs-on: ubuntu-latest
steps:
- uses: fit2cloud/LLM-CodeReview-Action@main
env:
GITHUB_TOKEN: ${{ secrets.FIT2CLOUDRD_LLM_CODE_REVIEW_TOKEN }}
OPENAI_API_KEY: ${{ secrets.ALIYUN_LLM_API_KEY }}
LANGUAGE: English
OPENAI_API_ENDPOINT: https://dashscope.aliyuncs.com/compatible-mode/v1
MODEL: qwen2.5-coder-3b-instruct
PROMPT: "Please check the following code differences for any irregularities, potential issues, or optimization suggestions, and provide your answers in English."
top_p: 1
temperature: 1
# max_tokens: 10000
MAX_PATCH_LENGTH: 10000
IGNORE_PATTERNS: "/node_modules,*.md,/dist,/.github"
FILE_PATTERNS: "*.java,*.go,*.py,*.vue,*.ts,*.js,*.css,*.scss,*.html"

@ -0,0 +1,21 @@
name: SonarCloud Scan
on:
push:
branches:
- dev
pull_request:
types: [opened, synchronize, reopened]
jobs:
sonarcloud:
name: SonarCloud
if: github.repository == '1Panel-dev/1Panel'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUBTOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

@ -0,0 +1,16 @@
name: Synchronize to Gitee
on: [push]
jobs:
repo-sync:
if: github.repository == '1Panel-dev/1Panel'
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-feizhiyun'
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
static_list: "1Panel"
force_update: true

@ -0,0 +1,11 @@
name: Typos Check
on: pull_request
jobs:
run:
name: Spell Check with Typos
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
uses: actions/checkout@v2
- name: Check spelling
uses: crate-ci/typos@master

71
.gitignore vendored

@ -0,0 +1,71 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
build/1panel-agent
build/1panel-core
# Mac
.DS_Store
*/.DS_Store
# VS Code
.vscode
*.project
*.factorypath
__debug*
# IntelliJ IDEA
.idea/*
!.idea/icon.png
*.iws
*.iml
*.ipr
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories
/pkg/
backend/__debug_bin
core/cmd/server/__debug_bin
core/cmd/server/web/assets
core/cmd/server/web/monacoeditorwork
core/cmd/server/web/index.html
frontend/auto-imports.d.ts
frontend/components.d.ts
frontend/src/xpack
agent/xpack
agent/router/entry_xpack.go
agent/server/init_xpack.go
agent/utils/xpack/xpack_xpack.go
core/xpack
core/router/entry_xpack.go
core/server/init_xpack.go
core/utils/xpack/xpack_xpack.go
xpack
.history/
dist/
1pctl
1panel.service
install.sh
quick_start.sh
cmd/server/fileList.txt
.fileList.txt
1Panel.code-workspace
core/.golangci.yml
agent/.golangci.yml
.opencode
openspec
CLAUDE.md
AGENTS.md
opencode.json

@ -0,0 +1,82 @@
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=jcroql
version: 2
before:
hooks:
# - export NODE_OPTIONS="--max-old-space-size=8192"
# - make build_web
- chmod +x ./ci/script.sh
- ./ci/script.sh
- sed -i 's@ORIGINAL_VERSION=.*@ORIGINAL_VERSION=v{{ .Version }}@g' 1pctl
builds:
- id: agent
dir: agent
main: cmd/server/main.go
binary: 1panel-agent
flags:
- -tags=xpack
- -trimpath
ldflags:
- -w -s
env:
- CGO_ENABLED=0
goos:
- linux
goarm:
- 7
goarch:
- amd64
- arm64
- arm
- ppc64le
- s390x
- riscv64
- id: core
dir: core
main: cmd/server/main.go
binary: 1panel-core
flags:
- -tags=xpack
- -trimpath
ldflags:
- -w -s
env:
- CGO_ENABLED=0
goos:
- linux
goarm:
- 7
goarch:
- amd64
- arm64
- arm
- ppc64le
- s390x
- riscv64
archives:
- formats: [ 'tar.gz' ]
ids: [core, agent]
name_template: "1panel-v{{ .Version }}-{{ .Os }}-{{ .Arch }}{{- if .Arm }}v{{ .Arm }}{{ end }}"
wrap_in_directory: true
files:
- 1pctl
- install.sh
- 1panel-core.service
- 1panel-agent.service
- initscript/*
- lang/*
- GeoIP.mmdb
checksum:
name_template: 'checksums.txt'
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

@ -0,0 +1,30 @@
# Contributing
As a contributor, you should agree that:
- The producer can adjust the open-source agreement to be more strict or relaxed as deemed necessary.
- Your contributed code may be used for commercial purposes, including but not limited to its cloud business operations.
## Create pull request
PR are always welcome, even if they only contain small fixes like typos or a few lines of code. If there will be a significant effort, please document it as an issue and get a discussion going before starting to work on it.
Please submit a PR broken down into small changes bit by bit. A PR consisting of a lot of features and code changes may be hard to review. It is recommended to submit PRs in an incremental fashion.
This [development guideline](https://docs.1panel.pro/dev_manual/dev_manual/) contains information about repository structure, how to set up development environment, how to run it, and more.
Note: If you split your pull request to small changes, please make sure any of the changes goes to master will not break anything. Otherwise, it can not be merged until this feature complete.
## Report issues
It is a great way to contribute by reporting an issue. Well-written and complete bug reports are always welcome! Please open an issue and follow the template to fill in required information.
Before opening any issue, please look up the existing issues to avoid submitting a duplication.
If you find a match, you can "subscribe" to it to get notified on updates. If you have additional helpful information about the issue, please leave a comment.
When reporting issues, always include:
* Which version you are using.
* Steps to reproduce the issue.
* Snapshots or log files if needed
Because the issues are open to the public, when submitting files, be sure to remove any sensitive information, e.g. user name, password, IP address, and company name. You can
replace those parts with "REDACTED" or other strings like "****".

@ -0,0 +1,39 @@
# syntax=docker/dockerfile:1
ARG NODE_VERSION=20
ARG GO_VERSION=1.22
FROM node:${NODE_VERSION}-bookworm AS web-builder
WORKDIR /src
COPY frontend/package*.json ./frontend/
RUN cd frontend && npm install
COPY frontend ./frontend
COPY core ./core
RUN cd frontend && npm run build:pro
FROM golang:${GO_VERSION}-bookworm AS go-builder
WORKDIR /src
ARG GOTOOLCHAIN=auto
ENV GOTOOLCHAIN=${GOTOOLCHAIN}
ENV CGO_ENABLED=0
COPY core/go.mod core/go.sum ./core/
COPY agent/go.mod agent/go.sum ./agent/
RUN cd core && go mod download
RUN cd agent && go mod download
COPY . .
COPY --from=web-builder /src/core/cmd/server/web /src/core/cmd/server/web
RUN cd core && go build -trimpath -ldflags "-s -w" -o /out/1panel-core ./cmd/server/main.go
RUN cd agent && go build -trimpath -ldflags "-s -w" -o /out/1panel-agent ./cmd/server/main.go
FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends bash ca-certificates tzdata tar gzip grep sed \
&& rm -rf /var/lib/apt/lists/*
COPY --from=go-builder /out/1panel-core /usr/local/bin/1panel-core
COPY --from=go-builder /out/1panel-agent /usr/local/bin/1panel-agent
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
COPY docker/1pctl /usr/local/bin/1pctl
COPY core/cmd/server/conf/app.yaml /usr/local/share/1panel/app.yaml
RUN chmod 755 /usr/local/bin/entrypoint.sh /usr/local/bin/1pctl \
&& mkdir -p /opt/1panel/conf
EXPOSE 9999
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

@ -0,0 +1,49 @@
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOARCH=$(shell go env GOARCH)
GOOS=$(shell go env GOOS )
BASE_PATH := $(shell pwd)
BUILD_PATH = $(BASE_PATH)/build
WEB_PATH=$(BASE_PATH)/frontend
ASSERT_PATH= $(BASE_PATH)/core/cmd/server/web/assets
CORE_PATH=$(BASE_PATH)/core
CORE_MAIN=$(CORE_PATH)/cmd/server/main.go
CORE_NAME=1panel-core
AGENT_PATH=$(BASE_PATH)/agent
AGENT_MAIN=$(AGENT_PATH)/cmd/server/main.go
AGENT_NAME=1panel-agent
clean_assets:
rm -rf $(ASSERT_PATH)
upx_bin:
upx $(BUILD_PATH)/$(CORE_NAME)
upx $(BUILD_PATH)/$(AGENT_NAME)
build_frontend:
cd $(WEB_PATH) && npm install && npm run build:pro
build_core_on_linux:
cd $(CORE_PATH) \
&& CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(CORE_NAME) $(CORE_MAIN)
build_agent_on_linux:
cd $(AGENT_PATH) \
&& CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(AGENT_NAME) $(AGENT_MAIN)
build_core_on_darwin:
cd $(CORE_PATH) \
&& CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(CORE_NAME) $(CORE_MAIN)
build_agent_on_darwin:
cd $(AGENT_PATH) \
&& CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(AGENT_NAME) $(AGENT_MAIN)
build_all: build_frontend build_core_on_linux build_agent_on_linux
build_on_local: clean_assets build_frontend build_core_on_darwin build_agent_on_darwin

@ -0,0 +1,9 @@
reviewers:
- wanghe-fit2cloud
- zhengkunwang223
- ssongliu
approvers:
- wanghe-fit2cloud
- zhengkunwang223
- ssongliu

@ -0,0 +1,13 @@
# Security policy
## Supported versions
| Version | Supported |
| ------- | ------------------ |
| v1.x | :white_check_mark: |
## Reporting a vulnerability
We first appreciate and are very thankful that you've found a vulnerability issue in 1Panel! By disclosing such issue to 1Panel development team you are helping 1Panel to become a much more safer project than before! ;)
To protect the existing users of 1Panel, we kindly ask you to not disclose the vulnerability to anyone except the 1Panel development team before a fix has been rolled out. Send an email to `wanghe@fit2cloud.com` instead.

@ -0,0 +1,256 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/gpu"
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/gpu/common"
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/xpu"
"github.com/gin-gonic/gin"
)
// @Tags AI
// @Summary Create Ollama model
// @Accept json
// @Param request body dto.OllamaModelName true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/ollama/model [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加 Ollama 模型 [name]","formatEN":"add Ollama model [name]"}
func (b *BaseApi) CreateOllamaModel(c *gin.Context) {
var req dto.OllamaModelName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := aiToolService.Create(req); err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags AI
// @Summary Rereate Ollama model
// @Accept json
// @Param request body dto.OllamaModelName true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/ollama/model/recreate [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加 Ollama 模型重试 [name]","formatEN":"re-add Ollama model [name]"}
func (b *BaseApi) RecreateOllamaModel(c *gin.Context) {
var req dto.OllamaModelName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := aiToolService.Recreate(req); err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags AI
// @Summary Close Ollama model conn
// @Accept json
// @Param request body dto.OllamaModelName true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/ollama/close [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"关闭 Ollama 模型连接 [name]","formatEN":"close conn for Ollama model [name]"}
func (b *BaseApi) CloseOllamaModel(c *gin.Context) {
var req dto.OllamaModelName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := aiToolService.Close(req.Name); err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags AI
// @Summary Sync Ollama model list
// @Success 200 {array} dto.OllamaModelDropList
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/ollama/model/sync [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"同步 Ollama 模型列表","formatEN":"sync Ollama model list"}
func (b *BaseApi) SyncOllamaModel(c *gin.Context) {
list, err := aiToolService.Sync()
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags AI
// @Summary Page Ollama models
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/ollama/model/search [post]
func (b *BaseApi) SearchOllamaModel(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := aiToolService.Search(req)
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags AI
// @Summary Page Ollama models
// @Accept json
// @Param request body dto.OllamaModelName true "request"
// @Success 200 {string} details
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/ollama/model/load [post]
func (b *BaseApi) LoadOllamaModelDetail(c *gin.Context) {
var req dto.OllamaModelName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
detail, err := aiToolService.LoadDetail(req.Name)
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, detail)
}
// @Tags AI
// @Summary Delete Ollama model
// @Accept json
// @Param request body dto.ForceDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/ollama/model/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"ollama_models","output_column":"name","output_value":"names"}],"formatZH":"删除 Ollama 模型 [names]","formatEN":"remove Ollama model [names]"}
func (b *BaseApi) DeleteOllamaModel(c *gin.Context) {
var req dto.ForceDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := aiToolService.Delete(req); err != nil {
helper.BadRequest(c, err)
return
}
helper.Success(c)
}
// @Tags AI
// @Summary Load gpu / xpu info
// @Accept json
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/gpu/load [get]
func (b *BaseApi) LoadGpuInfo(c *gin.Context) {
ok, client := gpu.New()
if ok {
info, err := client.LoadGpuInfo()
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, info)
return
}
xpuOK, xpuClient := xpu.New()
if xpuOK {
info, err := xpuClient.LoadGpuInfo()
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, info)
return
}
helper.SuccessWithData(c, &common.GpuInfo{})
}
// @Tags AI
// @Summary Bind domain
// @Accept json
// @Param request body dto.OllamaBindDomain true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/domain/bind [post]
func (b *BaseApi) BindDomain(c *gin.Context) {
var req dto.OllamaBindDomain
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := aiToolService.BindDomain(req); err != nil {
helper.BadRequest(c, err)
return
}
helper.Success(c)
}
// @Tags AI
// @Summary Get bind domain
// @Accept json
// @Param request body dto.OllamaBindDomainReq true "request"
// @Success 200 {object} dto.OllamaBindDomainRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/domain/get [post]
func (b *BaseApi) GetBindDomain(c *gin.Context) {
var req dto.OllamaBindDomainReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := aiToolService.GetBindDomain(req)
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, res)
}
// Tags AI
// Summary Update bind domain
// Accept json
// Param request body dto.OllamaBindDomain true "request"
// Success 200
// Security ApiKeyAuth
// Security Timestamp
// Router /ai/domain/update [post]
func (b *BaseApi) UpdateBindDomain(c *gin.Context) {
var req dto.OllamaBindDomain
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := aiToolService.UpdateBindDomain(req); err != nil {
helper.BadRequest(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,200 @@
package v2
import (
"errors"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
func (b *BaseApi) PageAlert(c *gin.Context) {
var req dto.AlertSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, alerts, err := alertService.PageAlert(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: alerts,
})
}
func (b *BaseApi) GetAlerts(c *gin.Context) {
alerts, err := alertService.GetAlerts()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, alerts)
}
func (b *BaseApi) CreateAlert(c *gin.Context) {
var req dto.AlertCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := alertService.CreateAlert(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) DeleteAlert(c *gin.Context) {
var req dto.DeleteRequest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := alertService.DeleteAlert(req.ID)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) UpdateAlert(c *gin.Context) {
var req dto.AlertUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := alertService.UpdateAlert(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) GetAlert(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.BadRequest(c, errors.New("no such id in request param"))
return
}
alert, err := alertService.GetAlert(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, alert)
}
func (b *BaseApi) UpdateAlertStatus(c *gin.Context) {
var req dto.AlertUpdateStatus
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := alertService.UpdateStatus(req.ID, req.Status); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) GetDisks(c *gin.Context) {
alerts, err := alertService.GetDisks()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, alerts)
}
func (b *BaseApi) PageAlertLogs(c *gin.Context) {
var req dto.AlertLogSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, alertLogs, err := alertService.PageAlertLogs(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: alertLogs,
})
}
func (b *BaseApi) CleanAlertLogs(c *gin.Context) {
if err := alertService.CleanAlertLogs(); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) GetClams(c *gin.Context) {
clams, err := alertService.GetClams()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, clams)
}
func (b *BaseApi) GetCronJobs(c *gin.Context) {
var req dto.CronJobReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
cronJobs, err := alertService.GetCronJobs(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, cronJobs)
}
func (b *BaseApi) GetAlertConfig(c *gin.Context) {
config, err := alertService.GetAlertConfig()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, config)
}
func (b *BaseApi) UpdateAlertConfig(c *gin.Context) {
var req dto.AlertConfigUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := alertService.UpdateAlertConfig(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) DeleteAlertConfig(c *gin.Context) {
var req dto.DeleteRequest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := alertService.DeleteAlertConfig(req.ID)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) TestAlertConfig(c *gin.Context) {
var req dto.AlertConfigTest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
flag, err := alertService.TestAlertConfig(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, flag)
}

@ -0,0 +1,242 @@
package v2
import (
"net/http"
"time"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/gin-gonic/gin"
)
// @Tags App
// @Summary List apps
// @Accept json
// @Param request body request.AppSearch true "request"
// @Success 200 {object} response.AppRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/search [post]
func (b *BaseApi) SearchApp(c *gin.Context) {
var req request.AppSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list, err := appService.PageApp(c, req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithDataGzipped(c, list)
}
// @Tags App
// @Summary Sync remote app list
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/sync/remote [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用商店同步","formatEN":"App store synchronization"}
func (b *BaseApi) SyncApp(c *gin.Context) {
var req dto.OperateWithTask
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := appService.GetAppUpdate()
if err != nil {
helper.InternalServer(c, err)
return
}
if !res.CanUpdate {
if res.IsSyncing {
helper.SuccessWithMsg(c, i18n.GetMsgByKey("AppStoreIsSyncing"))
} else {
helper.SuccessWithMsg(c, i18n.GetMsgByKey("AppStoreIsUpToDate"))
}
return
}
if err = appService.SyncAppListFromRemote(req.TaskID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags App
// @Summary Sync local app list
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/sync/local [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用商店同步","formatEN":"App store synchronization"}
func (b *BaseApi) SyncLocalApp(c *gin.Context) {
var req dto.OperateWithTask
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
go appService.SyncAppListFromLocal(req.TaskID)
helper.Success(c)
}
// @Tags App
// @Summary Search app by key
// @Accept json
// @Param key path string true "app key"
// @Success 200 {object} response.AppDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/:key [get]
func (b *BaseApi) GetApp(c *gin.Context) {
appKey, err := helper.GetStrParamByKey(c, "key")
if err != nil {
helper.BadRequest(c, err)
return
}
appDTO, err := appService.GetApp(c, appKey)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, appDTO)
}
// @Tags App
// @Summary Search app detail by 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
// @Security Timestamp
// @Router /apps/detail/:appId/:version/:type [get]
func (b *BaseApi) GetAppDetail(c *gin.Context) {
appID, err := helper.GetIntParamByKey(c, "appId")
if err != nil {
helper.BadRequest(c, err)
return
}
version := c.Param("version")
appType := c.Param("type")
appDetailDTO, err := appService.GetAppDetail(appID, version, appType)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, appDetailDTO)
}
// @Tags App
// @Summary Get app detail by id
// @Accept json
// @Param appId path integer true "id"
// @Success 200 {object} response.AppDetailDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/details/:id [get]
func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
appDetailID, err := helper.GetIntParamByKey(c, "id")
if err != nil {
helper.BadRequest(c, err)
return
}
appDetailDTO, err := appService.GetAppDetailByID(appDetailID)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, appDetailDTO)
}
// @Tags App
// @Summary Install app
// @Accept json
// @Param request body request.AppInstallCreate true "request"
// @Success 200 {object} model.AppInstall
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/install [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"安装应用 [name]","formatEN":"Install app [name]"}
func (b *BaseApi) InstallApp(c *gin.Context) {
var req request.AppInstallCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
install, err := appService.Install(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, install)
}
func (b *BaseApi) GetAppTags(c *gin.Context) {
tags, err := appService.GetAppTags(c)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, tags)
}
// @Tags App
// @Summary Get app list update
// @Success 200 {object} response.AppUpdateRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/checkupdate [get]
func (b *BaseApi) GetAppListUpdate(c *gin.Context) {
res, err := appService.GetAppUpdate()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags App
// @Summary Get app icon by app_id
// @Accept json
// @Param appId path integer true "app id"
// @Success 200 {file} file "app icon"
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/icon/:key [get]
func (b *BaseApi) GetAppIcon(c *gin.Context) {
appKey, err := helper.GetStrParamByKey(c, "key")
if err != nil {
helper.BadRequest(c, err)
return
}
iconBytes, err := appService.GetAppIcon(appKey)
if err != nil {
helper.InternalServer(c, err)
return
}
c.Header("Content-Type", "image/png")
c.Header("Cache-Control", "public, max-age=31536000, immutable")
c.Header("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
c.Data(http.StatusOK, "image/png", iconBytes)
}
// @Tags App
// @Summary Search app detail by appkey and version
// @Accept json
// @Param appId path integer true "app key"
// @Param version path string true "app version"
// @Success 200 {object} response.AppDetailSimpleDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/detail/node/:appKey/:version [get]
func (b *BaseApi) GetAppDetailForNode(c *gin.Context) {
appKey := c.Param("appKey")
version := c.Param("version")
appDetailDTO, err := appService.GetAppDetailByKey(appKey, version)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, appDetailDTO)
}

@ -0,0 +1,66 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags App
// @Summary List Upgrade Ignored App
// @Accept json
// @Success 200 {array} model.AppIgnoreUpgrade
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/ignored/detail [get]
func (b *BaseApi) ListAppIgnored(c *gin.Context) {
res, err := appIgnoreUpgradeService.List()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags App
// @Summary Ignore Upgrade App
// @Accept json
// @Param request body request.AppIgnoreUpgradeReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/ignore [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"忽略应用升级","formatEN":"Ignore application upgrade"}
func (b *BaseApi) IgnoreAppUpgrade(c *gin.Context) {
var req request.AppIgnoreUpgradeReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := appIgnoreUpgradeService.CreateAppIgnore(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// 写一个去掉忽略的接口
// @Tags App
// @Summary Cancel Ignore Upgrade App
// @Accept json
// @Param request body request.ReqWithID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/ignored/cancel [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"取消忽略应用升级","formatEN":"Cancel ignore application upgrade"}
func (b *BaseApi) CancelIgnoreAppUpgrade(c *gin.Context) {
var req request.ReqWithID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := appIgnoreUpgradeService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,351 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags App
// @Summary Page app installed
// @Accept json
// @Param request body request.AppInstalledSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/search [post]
func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
var req request.AppInstalledSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if req.All {
list, err := appInstallService.SearchForWebsite(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: int64(len(list)),
})
} else {
total, list, err := appInstallService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
}
// @Tags App
// @Summary List app installed
// @Accept json
// @Success 200 {array} dto.AppInstallInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/list [get]
func (b *BaseApi) ListAppInstalled(c *gin.Context) {
list, err := appInstallService.GetInstallList()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags App
// @Summary Check app installed
// @Accept json
// @Param request body request.AppInstalledInfo true "request"
// @Success 200 {object} response.AppInstalledCheck
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/check [post]
func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
var req request.AppInstalledInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
checkData, err := appInstallService.CheckExist(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, checkData)
}
// @Tags App
// @Summary Search app port by key
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {integer} port
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/loadport [post]
func (b *BaseApi) LoadPort(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
port, err := appInstallService.LoadPort(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, port)
}
// @Tags App
// @Summary Search app password by key
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {object} response.DatabaseConn
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/conninfo [POST]
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
conn, err := appInstallService.LoadConnInfo(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, conn)
}
// @Tags App
// @Summary Check before delete
// @Accept json
// @Param appInstallId path integer true "App install id"
// @Success 200 {array} dto.AppResource
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/delete/check/:appInstallId [get]
func (b *BaseApi) DeleteCheck(c *gin.Context) {
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
if err != nil {
helper.BadRequest(c, err)
return
}
checkData, err := appInstallService.DeleteCheck(appInstallId)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, checkData)
}
// Sync app installed
// @Tags App
// @Summary Sync app installed
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/sync [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"同步已安装应用列表","formatEN":"Sync the list of installed apps"}
func (b *BaseApi) SyncInstalled(c *gin.Context) {
if err := appInstallService.SyncAll(false); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags App
// @Summary Operate installed app
// @Accept json
// @Param request body request.AppInstalledOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/op [post]
// @x-panel-log {"bodyKeys":["installId","operate"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := appInstallService.Operate(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags App
// @Summary Search app service by key
// @Accept json
// @Param key path string true "request"
// @Success 200 {array} response.AppService
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/services/:key [get]
func (b *BaseApi) GetServices(c *gin.Context) {
key := c.Param("key")
services, err := appInstallService.GetServices(key)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, services)
}
// @Tags App
// @Summary Search app update version by install id
// @Accept json
// @Param appInstallId path integer true "request"
// @Success 200 {array} dto.AppVersion
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/update/versions [post]
func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
var req request.AppUpdateVersion
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
versions, err := appInstallService.GetUpdateVersions(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, versions)
}
// @Tags App
// @Summary Change app port
// @Accept json
// @Param request body request.PortUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/port/change [post]
// @x-panel-log {"bodyKeys":["key","name","port"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用端口修改 [key]-[name] => [port]","formatEN":"Application port update [key]-[name] => [port]"}
func (b *BaseApi) ChangeAppPort(c *gin.Context) {
var req request.PortUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := appInstallService.ChangeAppPort(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags App
// @Summary Search default config by key
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/conf [post]
func (b *BaseApi) GetDefaultConfig(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
content, err := appInstallService.GetDefaultConfigByKey(req.Type, req.Name)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, content)
}
// @Tags App
// @Summary Search params by appInstallId
// @Accept json
// @Param appInstallId path string true "request"
// @Success 200 {object} response.AppConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/params/:appInstallId [get]
func (b *BaseApi) GetParams(c *gin.Context) {
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
if err != nil {
helper.BadRequest(c, err)
return
}
content, err := appInstallService.GetParams(appInstallId)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, content)
}
// @Tags App
// @Summary Change app params
// @Accept json
// @Param request body request.AppInstalledUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/params/update [post]
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用参数修改 [installId]","formatEN":"Application param update [installId]"}
func (b *BaseApi) UpdateInstalled(c *gin.Context) {
var req request.AppInstalledUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := appInstallService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags App
// @Summary Update app config
// @Accept json
// @Param request body request.AppConfigUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/config/update [post]
// @x-panel-log {"bodyKeys":["installID","webUI"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用配置更新 [installID]","formatEN":"Application config update [installID]"}
func (b *BaseApi) UpdateAppConfig(c *gin.Context) {
var req request.AppConfigUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := appInstallService.UpdateAppConfig(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags App
// @Summary Get app install info
// @Accept json
// @Param appInstallId path integer true "App install id"
// @Success 200 {object} dto.AppInstallInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /apps/installed/info/:appInstallId [get]
func (b *BaseApi) GetAppInstallInfo(c *gin.Context) {
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
if err != nil {
helper.BadRequest(c, err)
return
}
info, err := appInstallService.GetAppInstallInfo(appInstallId)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, info)
}

@ -0,0 +1,530 @@
package v2
import (
"fmt"
"path"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/gin-gonic/gin"
)
func (b *BaseApi) CheckBackupUsed(c *gin.Context) {
name, err := helper.GetStrParamByKey(c, "name")
if err != nil {
helper.BadRequest(c, err)
return
}
if err := backupService.CheckUsed(name, true); err != nil {
helper.BadRequest(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Check backup account
// @Accept json
// @Param request body dto.BackupOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/check [post]
func (b *BaseApi) CheckBackup(c *gin.Context) {
var req dto.BackupOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
helper.SuccessWithData(c, backupService.CheckConn(req))
}
// @Tags Backup Account
// @Summary Create backup account
// @Accept json
// @Param request body dto.BackupOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups [post]
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建备份账号 [type]","formatEN":"create backup account [type]"}
func (b *BaseApi) CreateBackup(c *gin.Context) {
var req dto.BackupOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := backupService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Refresh token
// @Accept json
// @Param request body dto.BackupOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/refresh/token [post]
func (b *BaseApi) RefreshToken(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := backupService.RefreshToken(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary List buckets
// @Accept json
// @Param request body dto.ForBuckets true "request"
// @Success 200 {array} object
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/buckets [post]
func (b *BaseApi) ListBuckets(c *gin.Context) {
var req dto.ForBuckets
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
buckets, err := backupService.GetBuckets(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, buckets)
}
// @Tags Backup Account
// @Summary Delete backup account
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"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.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := backupService.Delete(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Update backup account
// @Accept json
// @Param request body dto.BackupOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/update [post]
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新备份账号 [types]","formatEN":"update backup account [types]"}
func (b *BaseApi) UpdateBackup(c *gin.Context) {
var req dto.BackupOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := backupService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Upload file for recover
// @Accept json
// @Param request body dto.UploadForRecover true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/upload [post]
// @x-panel-log {"bodyKeys":["filePath"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传备份文件 [filePath]","formatEN":"upload backup file [filePath]"}
func (b *BaseApi) UploadForRecover(c *gin.Context) {
var req dto.UploadForRecover
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := backupService.UploadForRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Load backup account options
// @Accept json
// @Success 200 {array} dto.BackupOption
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/options [get]
func (b *BaseApi) LoadBackupOptions(c *gin.Context) {
list, err := backupService.LoadBackupOptions()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Backup Account
// @Summary Search backup accounts with page
// @Accept json
// @Param request body dto.SearchPageWithType true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/search [post]
func (b *BaseApi) SearchBackup(c *gin.Context) {
var req dto.SearchPageWithType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := backupService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Backup Account
// @Summary get local backup dir
// @Success 200 {string} dir
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/local [get]
func (b *BaseApi) GetLocalDir(c *gin.Context) {
dir, err := backupService.GetLocalDir()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dir)
}
// @Tags Backup Account
// @Summary Load backup record size
// @Accept json
// @Param request body dto.SearchForSize true "request"
// @Success 200 {array} dto.RecordFileSize
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/record/size [post]
func (b *BaseApi) LoadBackupRecordSize(c *gin.Context) {
var req dto.SearchForSize
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list, err := backupRecordService.LoadRecordSize(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Backup Account
// @Summary Page backup records
// @Accept json
// @Param request body dto.RecordSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/record/search [post]
func (b *BaseApi) SearchBackupRecords(c *gin.Context) {
var req dto.RecordSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := backupRecordService.SearchRecordsWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Backup Account
// @Summary Page backup records by cronjob
// @Accept json
// @Param request body dto.RecordSearchByCronjob true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/record/search/bycronjob [post]
func (b *BaseApi) SearchBackupRecordsByCronjob(c *gin.Context) {
var req dto.RecordSearchByCronjob
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := backupRecordService.SearchRecordsByCronjobWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Backup Account
// @Summary Download backup record
// @Accept json
// @Param request body dto.DownloadRecord true "request"
// @Success 200 {string} filePath
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/record/download [post]
// @x-panel-log {"bodyKeys":["source","fileName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载备份记录 [source][fileName]","formatEN":"download backup records [source][fileName]"}
func (b *BaseApi) DownloadRecord(c *gin.Context) {
var req dto.DownloadRecord
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
filePath, err := backupRecordService.DownloadRecord(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, filePath)
}
// @Tags Backup Account
// @Summary Update backup record description
// @Accept json
// @Param request body dto.UpdateDescription true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/record/description/update [post]
func (b *BaseApi) UpdateRecordDescription(c *gin.Context) {
var req dto.UpdateDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := backupRecordService.UpdateDescription(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Delete backup record
// @Accept json
// @Param request body dto.BatchDeleteReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/record/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := backupRecordService.BatchDeleteRecord(req.Ids); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary List files from backup accounts
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/search/files [post]
func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data := backupRecordService.ListFiles(req)
helper.SuccessWithData(c, data)
}
// @Tags Backup Account
// @Summary Backup system data
// @Accept json
// @Param request body dto.CommonBackup true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/backup [post]
// @x-panel-log {"bodyKeys":["type","name","detailName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"备份 [type] 数据 [name][detailName]","formatEN":"backup [type] data [name][detailName]"}
func (b *BaseApi) Backup(c *gin.Context) {
var req dto.CommonBackup
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
switch req.Type {
case "app":
if _, err := backupService.AppBackup(req); err != nil {
helper.InternalServer(c, err)
return
}
case "mysql", "mariadb", constant.AppMysqlCluster:
if err := backupService.MysqlBackup(req); err != nil {
helper.InternalServer(c, err)
return
}
case constant.AppPostgresql, constant.AppPostgresqlCluster:
if err := backupService.PostgresqlBackup(req); err != nil {
helper.InternalServer(c, err)
return
}
case "website":
if err := backupService.WebsiteBackup(req); err != nil {
helper.InternalServer(c, err)
return
}
case "redis", constant.AppRedisCluster:
if err := backupService.RedisBackup(req); err != nil {
helper.InternalServer(c, err)
return
}
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Recover system data
// @Accept json
// @Param request body dto.CommonRecover true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/recover [post]
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
func (b *BaseApi) Recover(c *gin.Context) {
var req dto.CommonRecover
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
downloadPath, err := backupRecordService.DownloadRecord(dto.DownloadRecord{
DownloadAccountID: req.DownloadAccountID,
FileDir: path.Dir(req.File),
FileName: path.Base(req.File),
})
if err != nil {
helper.BadRequest(c, fmt.Errorf("download file failed, err: %v", err))
return
}
req.File = downloadPath
switch req.Type {
case "mysql", "mariadb", constant.AppMysqlCluster:
if err := backupService.MysqlRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
case constant.AppPostgresql, constant.AppPostgresqlCluster:
if err := backupService.PostgresqlRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
case "website":
if err := backupService.WebsiteRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
case "redis", constant.AppRedisCluster:
if err := backupService.RedisRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
case "app":
if err := backupService.AppRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
}
helper.Success(c)
}
// @Tags Backup Account
// @Summary Recover system data by upload
// @Accept json
// @Param request body dto.CommonRecover true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /backups/recover/byupload [post]
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
func (b *BaseApi) RecoverByUpload(c *gin.Context) {
var req dto.CommonRecover
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
switch req.Type {
case "mysql", "mariadb", constant.AppMysqlCluster:
if err := backupService.MysqlRecoverByUpload(req); err != nil {
helper.InternalServer(c, err)
return
}
case constant.AppPostgresql, constant.AppPostgresqlCluster:
if err := backupService.PostgresqlRecoverByUpload(req); err != nil {
helper.InternalServer(c, err)
return
}
case "app":
if err := backupService.AppRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
case "website":
if err := backupService.WebsiteRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
}
helper.Success(c)
}

@ -0,0 +1,274 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Clam
// @Summary Create clam
// @Accept json
// @Param request body dto.ClamCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam [post]
// @x-panel-log {"bodyKeys":["name","path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建扫描规则 [name][path]","formatEN":"create clam [name][path]"}
func (b *BaseApi) CreateClam(c *gin.Context) {
var req dto.ClamCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Clam
// @Summary Update clam
// @Accept json
// @Param request body dto.ClamUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/update [post]
// @x-panel-log {"bodyKeys":["name","path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改扫描规则 [name][path]","formatEN":"update clam [name][path]"}
func (b *BaseApi) UpdateClam(c *gin.Context) {
var req dto.ClamUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Clam
// @Summary Update clam status
// @Accept json
// @Param request body dto.ClamUpdateStatus true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/status/update [post]
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"clams","output_column":"name","output_value":"name"}],"formatZH":"修改扫描规则 [name] 状态为 [status]","formatEN":"change the status of clam [name] to [status]."}
func (b *BaseApi) UpdateClamStatus(c *gin.Context) {
var req dto.ClamUpdateStatus
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.UpdateStatus(req.ID, req.Status); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Clam
// @Summary Page clam
// @Accept json
// @Param request body dto.SearchClamWithPage true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/search [post]
func (b *BaseApi) SearchClam(c *gin.Context) {
var req dto.SearchClamWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := clamService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Clam
// @Summary Load clam base info
// @Accept json
// @Success 200 {object} dto.ClamBaseInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/base [post]
func (b *BaseApi) LoadClamBaseInfo(c *gin.Context) {
info, err := clamService.LoadBaseInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, info)
}
// @Tags Clam
// @Summary Operate Clam
// @Accept json
// @Success 200
// @Param request body dto.Operate true "request"
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] Clam","formatEN":"[operation] FTP"}
func (b *BaseApi) OperateClam(c *gin.Context) {
var req dto.Operate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.Operate(req.Operation); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Clam
// @Summary Clean clam record
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/record/clean [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":true,"db":"clams","output_column":"name","output_value":"name"}],"formatZH":"清空扫描报告 [name]","formatEN":"clean clam record [name]"}
func (b *BaseApi) CleanClamRecord(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.CleanRecord(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Clam
// @Summary Page clam record
// @Accept json
// @Param request body dto.ClamLogSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/record/search [post]
func (b *BaseApi) SearchClamRecord(c *gin.Context) {
var req dto.ClamLogSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := clamService.SearchRecords(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Clam
// @Summary Load clam file
// @Accept json
// @Param request body dto.ClamFileReq true "request"
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/file/search [post]
func (b *BaseApi) SearchClamFile(c *gin.Context) {
var req dto.ClamFileReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
content, err := clamService.LoadFile(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, content)
}
// @Tags Clam
// @Summary Update clam file
// @Accept json
// @Param request body dto.UpdateByNameAndFile true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/file/update [post]
func (b *BaseApi) UpdateFile(c *gin.Context) {
var req dto.UpdateByNameAndFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.UpdateFile(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Clam
// @Summary Delete clam
// @Accept json
// @Param request body dto.ClamDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"clams","output_column":"name","output_value":"names"}],"formatZH":"删除扫描规则 [names]","formatEN":"delete clam [names]"}
func (b *BaseApi) DeleteClam(c *gin.Context) {
var req dto.ClamDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Clam
// @Summary Handle clam scan
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clam/handle [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":true,"db":"clams","output_column":"name","output_value":"name"}],"formatZH":"执行病毒扫描 [name]","formatEN":"handle clam scan [name]"}
func (b *BaseApi) HandleClamScan(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := clamService.HandleOnce(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,142 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Container Compose-template
// @Summary Create compose template
// @Accept json
// @Param request body dto.ComposeTemplateCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/template [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 compose 模版 [name]","formatEN":"create compose template [name]"}
func (b *BaseApi) CreateComposeTemplate(c *gin.Context) {
var req dto.ComposeTemplateCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := composeTemplateService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Compose-template
// @Summary Bacth compose template
// @Accept json
// @Param request body dto.ComposeTemplateBatch true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/template/batch [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"批量导入编排模版","formatEN":"batch import compose templates"}
func (b *BaseApi) BatchComposeTemplate(c *gin.Context) {
var req dto.ComposeTemplateBatch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := composeTemplateService.Batch(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Compose-template
// @Summary Page compose templates
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Produce json
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/template/search [post]
func (b *BaseApi) SearchComposeTemplate(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := composeTemplateService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Container Compose-template
// @Summary List compose templates
// @Produce json
// @Success 200 {array} dto.ComposeTemplateInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/template [get]
func (b *BaseApi) ListComposeTemplate(c *gin.Context) {
list, err := composeTemplateService.List()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Container Compose-template
// @Summary Delete compose template
// @Accept json
// @Param request body dto.BatchDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/template/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := composeTemplateService.Delete(req.Ids); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Compose-template
// @Summary Update compose template
// @Accept json
// @Param request body dto.ComposeTemplateUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/template/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
upMap := make(map[string]interface{})
upMap["content"] = req.Content
upMap["description"] = req.Description
if err := composeTemplateService.Update(req.ID, upMap); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,769 @@
package v2
import (
"strconv"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
)
// @Tags Container
// @Summary Page containers
// @Accept json
// @Param request body dto.PageContainer true "request"
// @Produce json
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/search [post]
func (b *BaseApi) SearchContainer(c *gin.Context) {
var req dto.PageContainer
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := containerService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Container
// @Summary Load container users
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Produce json
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/users [post]
func (b *BaseApi) LoadContainerUsers(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
helper.SuccessWithData(c, containerService.LoadUsers(req))
}
// @Tags Container
// @Summary List containers
// @Accept json
// @Produce json
// @Success 200 {array} dto.ContainerOptions
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/list [post]
func (b *BaseApi) ListContainer(c *gin.Context) {
helper.SuccessWithData(c, containerService.List())
}
// @Tags Container
// @Summary List containers by image
// @Accept json
// @Produce json
// @Success 200 {array} dto.ContainerOptions
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/list/byimage [post]
func (b *BaseApi) ListContainerByImage(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
helper.SuccessWithData(c, containerService.ListByImage(req.Name))
}
// @Tags Container
// @Summary Load containers status
// @Accept json
// @Produce json
// @Success 200 {object} dto.ContainerStatus
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/status [get]
func (b *BaseApi) LoadContainerStatus(c *gin.Context) {
data, err := containerService.LoadStatus()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Container Compose
// @Summary Page composes
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/compose/search [post]
func (b *BaseApi) SearchCompose(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := containerService.PageCompose(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Container Compose
// @Summary Test compose
// @Accept json
// @Param request body dto.ComposeCreate true "request"
// @Success 200 {boolean} isOK
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/compose/test [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"检测 compose [name] 格式","formatEN":"check compose [name]"}
func (b *BaseApi) TestCompose(c *gin.Context) {
var req dto.ComposeCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
isOK, err := containerService.TestCompose(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, isOK)
}
// @Tags Container Compose
// @Summary Create compose
// @Accept json
// @Param request body dto.ComposeCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/compose [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 compose [name]","formatEN":"create compose [name]"}
func (b *BaseApi) CreateCompose(c *gin.Context) {
var req dto.ComposeCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.CreateCompose(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Compose
// @Summary Operate compose
// @Accept json
// @Param request body dto.ComposeOperation true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/compose/operate [post]
// @x-panel-log {"bodyKeys":["name","operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"compose [operation] [name]","formatEN":"compose [operation] [name]"}
func (b *BaseApi) OperatorCompose(c *gin.Context) {
var req dto.ComposeOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ComposeOperation(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Update container
// @Accept json
// @Param request body dto.ContainerOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/update [post]
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新容器 [name][image]","formatEN":"update container [name][image]"}
func (b *BaseApi) ContainerUpdate(c *gin.Context) {
var req dto.ContainerOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerUpdate(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Load container info
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200 {object} dto.ContainerOperate
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/info [post]
func (b *BaseApi) ContainerInfo(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := containerService.ContainerInfo(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Summary Load container limits
// @Success 200 {object} dto.ResourceLimit
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/limit [get]
func (b *BaseApi) LoadResourceLimit(c *gin.Context) {
data, err := containerService.LoadResourceLimit()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Summary Load container stats
// @Success 200 {array} dto.ContainerListStats
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/list/stats [get]
func (b *BaseApi) ContainerListStats(c *gin.Context) {
data, err := containerService.ContainerListStats()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Summary Load container stats size
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200 {object} dto.ContainerItemStats
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/item/stats [post]
func (b *BaseApi) ContainerItemStats(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := containerService.ContainerItemStats(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Container
// @Summary Create container
// @Accept json
// @Param request body dto.ContainerOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers [post]
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器 [name][image]","formatEN":"create container [name][image]"}
func (b *BaseApi) ContainerCreate(c *gin.Context) {
var req dto.ContainerOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerCreate(req, true); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Create container by command
// @Accept json
// @Param request body dto.ContainerCreateByCommand true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/command [post]
func (b *BaseApi) ContainerCreateByCommand(c *gin.Context) {
var req dto.ContainerCreateByCommand
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerCreateByCommand(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Upgrade container
// @Accept json
// @Param request body dto.ContainerUpgrade true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/upgrade [post]
// @x-panel-log {"bodyKeys":["names","image"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新容器镜像 [names][image]","formatEN":"upgrade container image [names][image]"}
func (b *BaseApi) ContainerUpgrade(c *gin.Context) {
var req dto.ContainerUpgrade
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerUpgrade(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Clean container
// @Accept json
// @Param request body dto.ContainerPrune true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/prune [post]
// @x-panel-log {"bodyKeys":["pruneType"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理容器 [pruneType]","formatEN":"clean container [pruneType]"}
func (b *BaseApi) ContainerPrune(c *gin.Context) {
var req dto.ContainerPrune
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.Prune(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Clean container log
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/clean/log [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理容器 [name] 日志","formatEN":"clean container [name] logs"}
func (b *BaseApi) CleanContainerLog(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerLogClean(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Clean compose log
// @Accept json
// @Param request body dto.ComposeLogClean true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/compose/clean/log [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理容器编排 [name] 日志","formatEN":"clean compose [name] logs"}
func (b *BaseApi) CleanComposeLog(c *gin.Context) {
var req dto.ComposeLogClean
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ComposeLogClean(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Rename Container
// @Accept json
// @Param request body dto.ContainerRename true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/rename [post]
// @x-panel-log {"bodyKeys":["name","newName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"容器重命名 [name] => [newName]","formatEN":"rename container [name] => [newName]"}
func (b *BaseApi) ContainerRename(c *gin.Context) {
var req dto.ContainerRename
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerRename(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Commit Container
// @Accept json
// @Param request body dto.ContainerCommit true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/commit [post]
func (b *BaseApi) ContainerCommit(c *gin.Context) {
var req dto.ContainerCommit
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerCommit(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Operate Container
// @Accept json
// @Param request body dto.ContainerOperation true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/operate [post]
// @x-panel-log {"bodyKeys":["names","operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"容器 [names] 执行 [operation]","formatEN":"container [operation] [names]"}
func (b *BaseApi) ContainerOperation(c *gin.Context) {
var req dto.ContainerOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ContainerOperation(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Container stats
// @Param id path string true "容器id"
// @Success 200 {object} dto.ContainerStats
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/stats/:id [get]
func (b *BaseApi) ContainerStats(c *gin.Context) {
containerID, ok := c.Params.Get("id")
if !ok {
helper.BadRequest(c, errors.New("error container id in path"))
return
}
result, err := containerService.ContainerStats(containerID)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, result)
}
// @Tags Container
// @Summary Container inspect
// @Accept json
// @Param request body dto.InspectReq true "request"
// @Success 200 {string} result
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/inspect [post]
func (b *BaseApi) Inspect(c *gin.Context) {
var req dto.InspectReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
result, err := containerService.Inspect(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, result)
}
func (b *BaseApi) DownloadContainerLogs(c *gin.Context) {
var req dto.ContainerLog
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := containerService.DownloadContainerLogs(req.ContainerType, req.Container, req.Since, strconv.Itoa(int(req.Tail)), c)
if err != nil {
helper.InternalServer(c, err)
}
}
// @Tags Container Network
// @Summary Page networks
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Produce json
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/network/search [post]
func (b *BaseApi) SearchNetwork(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := containerService.PageNetwork(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Container Network
// @Summary List networks
// @Accept json
// @Produce json
// @Success 200 {array} dto.Options
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/network [get]
func (b *BaseApi) ListNetwork(c *gin.Context) {
list, err := containerService.ListNetwork()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Container Network
// @Summary Delete network
// @Accept json
// @Param request body dto.BatchDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/network/del [post]
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除容器网络 [names]","formatEN":"delete container network [names]"}
func (b *BaseApi) DeleteNetwork(c *gin.Context) {
var req dto.BatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.DeleteNetwork(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Network
// @Summary Create network
// @Accept json
// @Param request body dto.NetworkCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/network [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器网络 name","formatEN":"create container network [name]"}
func (b *BaseApi) CreateNetwork(c *gin.Context) {
var req dto.NetworkCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.CreateNetwork(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Volume
// @Summary Page volumes
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Produce json
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/volume/search [post]
func (b *BaseApi) SearchVolume(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := containerService.PageVolume(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Container Volume
// @Summary List volumes
// @Accept json
// @Produce json
// @Success 200 {array} dto.Options
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/volume [get]
func (b *BaseApi) ListVolume(c *gin.Context) {
list, err := containerService.ListVolume()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Container Volume
// @Summary Delete volume
// @Accept json
// @Param request body dto.BatchDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/volume/del [post]
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除容器存储卷 [names]","formatEN":"delete container volume [names]"}
func (b *BaseApi) DeleteVolume(c *gin.Context) {
var req dto.BatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.DeleteVolume(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Volume
// @Summary Create volume
// @Accept json
// @Param request body dto.VolumeCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/volume [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建容器存储卷 [name]","formatEN":"create container volume [name]"}
func (b *BaseApi) CreateVolume(c *gin.Context) {
var req dto.VolumeCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.CreateVolume(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Compose
// @Summary Update compose
// @Accept json
// @Param request body dto.ComposeUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/compose/update [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 compose [name]","formatEN":"update compose information [name]"}
func (b *BaseApi) ComposeUpdate(c *gin.Context) {
var req dto.ComposeUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := containerService.ComposeUpdate(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container
// @Summary Container logs
// @Param container query string false "容器名称"
// @Param since query string false "时间筛选"
// @Param follow query string false "是否追踪"
// @Param tail query string false "显示行号"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/search/log [get]
func (b *BaseApi) ContainerStreamLogs(c *gin.Context) {
c.Header("Content-Type", "text/event-stream")
c.Header("Cache-Control", "no-cache")
c.Header("Connection", "keep-alive")
c.Header("Transfer-Encoding", "chunked")
since := c.Query("since")
follow := c.Query("follow") == "true"
tail := c.Query("tail")
container := c.Query("container")
compose := c.Query("compose")
streamLog := dto.StreamLog{
Compose: compose,
Container: container,
Since: since,
Follow: follow,
Tail: tail,
Type: "container",
}
if compose != "" {
streamLog.Type = "compose"
}
containerService.StreamLogs(c, streamLog)
}

@ -0,0 +1,359 @@
package v2
import (
"net/http"
"strings"
"time"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/gin-gonic/gin"
)
// @Tags Cronjob
// @Summary Create cronjob
// @Accept json
// @Param request body dto.CronjobOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs [post]
// @x-panel-log {"bodyKeys":["type","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建计划任务 [type][name]","formatEN":"create cronjob [type][name]"}
func (b *BaseApi) CreateCronjob(c *gin.Context) {
var req dto.CronjobOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Load cronjob info
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/load/info [post]
func (b *BaseApi) LoadCronjobInfo(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := cronjobService.LoadInfo(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Cronjob
// @Summary Export cronjob list
// @Accept json
// @Param request body dto.OperateByIDs true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/export [post]
func (b *BaseApi) ExportCronjob(c *gin.Context) {
var req dto.OperateByIDs
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
content, err := cronjobService.Export(req)
if err != nil {
helper.InternalServer(c, err)
return
}
http.ServeContent(c.Writer, c.Request, "", time.Now(), strings.NewReader(content))
}
// @Tags Cronjob
// @Summary Import cronjob list
// @Accept json
// @Param request body dto.CronjobImport true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/import [post]
func (b *BaseApi) ImportCronjob(c *gin.Context) {
var req dto.CronjobImport
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.Import(req.Cronjobs); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Load script options
// @Success 200 {array} dto.ScriptOptions
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/script/options [get]
func (b *BaseApi) LoadScriptOptions(c *gin.Context) {
helper.SuccessWithData(c, cronjobService.LoadScriptOptions())
}
// @Tags Cronjob
// @Summary Load cronjob spec time
// @Accept json
// @Param request body dto.CronjobSpec true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/next [post]
func (b *BaseApi) LoadNextHandle(c *gin.Context) {
var req dto.CronjobSpec
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list, err := cronjobService.LoadNextHandle(req.Spec)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Cronjob
// @Summary Page cronjobs
// @Accept json
// @Param request body dto.PageCronjob true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/search [post]
func (b *BaseApi) SearchCronjob(c *gin.Context) {
var req dto.PageCronjob
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := cronjobService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Cronjob
// @Summary Page job records
// @Accept json
// @Param request body dto.SearchRecord true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/search/records [post]
func (b *BaseApi) SearchJobRecords(c *gin.Context) {
var req dto.SearchRecord
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
loc, _ := time.LoadLocation(common.LoadTimeZoneByCmd())
req.StartTime = req.StartTime.In(loc)
req.EndTime = req.EndTime.In(loc)
total, list, err := cronjobService.SearchRecords(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Cronjob
// @Summary Load Cronjob record log
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/records/log [post]
func (b *BaseApi) LoadRecordLog(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
content := cronjobService.LoadRecordLog(req)
helper.SuccessWithData(c, content)
}
// @Tags Cronjob
// @Summary Clean job records
// @Accept json
// @Param request body dto.CronjobClean true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/records/clean [post]
// @x-panel-log {"bodyKeys":["cronjobID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"cronjobID","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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.CleanRecord(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Handle stop job
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/stop [post]
func (b *BaseApi) StopCronJob(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.HandleStop(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Delete cronjob
// @Accept json
// @Param request body dto.CronjobBatchDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"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.CronjobBatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Update cronjob
// @Accept json
// @Param request body dto.CronjobOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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.CronjobOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.Update(req.ID, req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Update cronjob group
// @Accept json
// @Param request body dto.ChangeGroup true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/group/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"更新计划任务分组 [name]","formatEN":"update cronjob group [name]"}
func (b *BaseApi) UpdateCronjobGroup(c *gin.Context) {
var req dto.ChangeGroup
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.UpdateGroup(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Update cronjob status
// @Accept json
// @Param request body dto.CronjobUpdateStatus true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/status [post]
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.UpdateStatus(req.ID, req.Status); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Cronjob
// @Summary Handle cronjob once
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /cronjobs/handle [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := cronjobService.HandleOnce(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,223 @@
package v2
import (
"errors"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Dashboard
// @Summary Load os info
// @Accept json
// @Success 200 {object} dto.OsInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/base/os [get]
func (b *BaseApi) LoadDashboardOsInfo(c *gin.Context) {
data, err := dashboardService.LoadOsInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary Load app launcher
// @Accept json
// @Success 200 {array} dto.AppLauncher
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/app/launcher [get]
func (b *BaseApi) LoadAppLauncher(c *gin.Context) {
data, err := dashboardService.LoadAppLauncher(c)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithDataGzipped(c, data)
}
// @Tags Dashboard
// @Summary Load app launcher options
// @Accept json
// @Param request body dto.SearchByFilter true "request"
// @Success 200 {array} dto.LauncherOption
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/app/launcher/option [post]
func (b *BaseApi) LoadAppLauncherOption(c *gin.Context) {
var req dto.SearchByFilter
if err := helper.CheckBind(&req, c); err != nil {
return
}
data, err := dashboardService.ListLauncherOption(req.Filter)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary Update app Launcher
// @Accept json
// @Param request body dto.SettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/app/launcher/show [post]
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"首页应用 [key] => 显示:[value]","formatEN":"app launcher [key] => show: [value]"}
func (b *BaseApi) UpdateAppLauncher(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := dashboardService.ChangeShow(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Dashboard
// @Summary Load quick jump options
// @Success 200 {array} dto.QuickJump
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/quick/option [get]
func (b *BaseApi) LoadQuickOption(c *gin.Context) {
helper.SuccessWithData(c, dashboardService.LoadQuickOptions())
}
// @Tags Dashboard
// @Summary Update quick jump
// @Accept json
// @Param request body dto.ChangeQuicks true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/quick/change [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"切换快速跳转","formatEN":"change quick jump"}
func (b *BaseApi) UpdateQuickJump(c *gin.Context) {
var req dto.ChangeQuicks
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := dashboardService.ChangeQuick(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Dashboard
// @Summary Load dashboard base info
// @Accept json
// @Param ioOption path string true "request"
// @Param netOption path string true "request"
// @Success 200 {object} dto.DashboardBase
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/base/:ioOption/:netOption [get]
func (b *BaseApi) LoadDashboardBaseInfo(c *gin.Context) {
ioOption, ok := c.Params.Get("ioOption")
if !ok {
helper.BadRequest(c, errors.New("error ioOption in path"))
return
}
netOption, ok := c.Params.Get("netOption")
if !ok {
helper.BadRequest(c, errors.New("error ioOption in path"))
return
}
data, err := dashboardService.LoadBaseInfo(ioOption, netOption)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary Load dashboard current info for node
// @Success 200 {object} dto.NodeCurrent
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/current/node [get]
func (b *BaseApi) LoadCurrentInfoForNode(c *gin.Context) {
data := dashboardService.LoadCurrentInfoForNode()
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary Load dashboard current info
// @Accept json
// @Param ioOption path string true "request"
// @Param netOption path string true "request"
// @Success 200 {object} dto.DashboardCurrent
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/current/:ioOption/:netOption [get]
func (b *BaseApi) LoadDashboardCurrentInfo(c *gin.Context) {
ioOption, ok := c.Params.Get("ioOption")
if !ok {
helper.BadRequest(c, errors.New("error ioOption in path"))
return
}
netOption, ok := c.Params.Get("netOption")
if !ok {
helper.BadRequest(c, errors.New("error netOption in path"))
return
}
data := dashboardService.LoadCurrentInfo(ioOption, netOption)
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary Load top cpu processes
// @Success 200 {array} dto.Process
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/current/top/cpu [get]
func (b *BaseApi) LoadDashboardTopCPU(c *gin.Context) {
data := dashboardService.LoadTopCPU()
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary Load top memory processes
// @Success 200 {array} dto.Process
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/current/top/mem [get]
func (b *BaseApi) LoadDashboardTopMem(c *gin.Context) {
data := dashboardService.LoadTopMem()
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary System restart
// @Accept json
// @Param operation path string true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /dashboard/system/restart/:operation [post]
func (b *BaseApi) SystemRestart(c *gin.Context) {
operation, ok := c.Params.Get("operation")
if !ok {
helper.BadRequest(c, errors.New("error operation in path"))
return
}
if err := dashboardService.Restart(operation); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,228 @@
package v2
import (
"encoding/base64"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Database
// @Summary Create database
// @Accept json
// @Param request body dto.DatabaseCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db [post]
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建远程数据库 [name][type]","formatEN":"create database [name][type]"}
func (b *BaseApi) CreateDatabase(c *gin.Context) {
var req dto.DatabaseCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if req.SSL {
key, _ := base64.StdEncoding.DecodeString(req.ClientKey)
req.ClientKey = string(key)
cert, _ := base64.StdEncoding.DecodeString(req.ClientCert)
req.ClientCert = string(cert)
ca, _ := base64.StdEncoding.DecodeString(req.RootCert)
req.RootCert = string(ca)
}
if err := databaseService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database
// @Summary Check database
// @Accept json
// @Param request body dto.DatabaseCreate true "request"
// @Success 200 {boolean} isOk
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/check [post]
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"检测远程数据库 [name][type] 连接性","formatEN":"check if database [name][type] is connectable"}
func (b *BaseApi) CheckDatabase(c *gin.Context) {
var req dto.DatabaseCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if req.SSL {
clientKey, _ := base64.StdEncoding.DecodeString(req.ClientKey)
req.ClientKey = string(clientKey)
clientCert, _ := base64.StdEncoding.DecodeString(req.ClientCert)
req.ClientCert = string(clientCert)
rootCert, _ := base64.StdEncoding.DecodeString(req.RootCert)
req.RootCert = string(rootCert)
}
helper.SuccessWithData(c, databaseService.CheckDatabase(req))
}
// @Tags Database
// @Summary Page databases
// @Accept json
// @Param request body dto.DatabaseSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/search [post]
func (b *BaseApi) SearchDatabase(c *gin.Context) {
var req dto.DatabaseSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := databaseService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Database
// @Summary List databases
// @Success 200 {array} dto.DatabaseOption
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/list/:type [get]
func (b *BaseApi) ListDatabase(c *gin.Context) {
dbType, err := helper.GetStrParamByKey(c, "type")
if err != nil {
helper.BadRequest(c, err)
return
}
list, err := databaseService.List(dbType)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Database
// @Summary List databases
// @Success 200 {array} dto.DatabaseItem
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/item/:type [get]
func (b *BaseApi) LoadDatabaseItems(c *gin.Context) {
dbType, err := helper.GetStrParamByKey(c, "type")
if err != nil {
helper.BadRequest(c, err)
return
}
list, err := databaseService.LoadItems(dbType)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Database
// @Summary Get databases
// @Success 200 {object} dto.DatabaseInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/:name [get]
func (b *BaseApi) GetDatabase(c *gin.Context) {
name, err := helper.GetStrParamByKey(c, "name")
if err != nil {
helper.BadRequest(c, err)
return
}
data, err := databaseService.Get(name)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Database
// @Summary Check before delete remote database
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/del/check [post]
func (b *BaseApi) DeleteCheckDatabase(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
apps, err := databaseService.DeleteCheck(req.ID)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, apps)
}
// @Tags Database
// @Summary Delete database
// @Accept json
// @Param request body dto.DatabaseDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"databases","output_column":"name","output_value":"names"}],"formatZH":"删除远程数据库 [names]","formatEN":"delete database [names]"}
func (b *BaseApi) DeleteDatabase(c *gin.Context) {
var req dto.DatabaseDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := databaseService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database
// @Summary Update database
// @Accept json
// @Param request body dto.DatabaseUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/db/update [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新远程数据库 [name]","formatEN":"update database [name]"}
func (b *BaseApi) UpdateDatabase(c *gin.Context) {
var req dto.DatabaseUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if req.SSL {
cKey, _ := base64.StdEncoding.DecodeString(req.ClientKey)
req.ClientKey = string(cKey)
cCert, _ := base64.StdEncoding.DecodeString(req.ClientCert)
req.ClientCert = string(cCert)
ca, _ := base64.StdEncoding.DecodeString(req.RootCert)
req.RootCert = string(ca)
}
if err := databaseService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,74 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Database Common
// @Summary Load base info
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {object} dto.DBBaseInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/common/info [post]
func (b *BaseApi) LoadDBBaseInfo(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := dbCommonService.LoadBaseInfo(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Database Common
// @Summary Load Database conf
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/common/load/file [post]
func (b *BaseApi) LoadDBFile(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
content, err := dbCommonService.LoadDatabaseFile(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, content)
}
// @Tags Database Common
// @Summary Update conf by upload file
// @Accept json
// @Param request body dto.DBConfUpdateByFile true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/common/update/conf [post]
// @x-panel-log {"bodyKeys":["type","database"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 [type] 数据库 [database] 配置信息","formatEN":"update the [type] [database] database configuration information"}
func (b *BaseApi) UpdateDBConfByFile(c *gin.Context) {
var req dto.DBConfUpdateByFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := dbCommonService.UpdateConfByFile(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,348 @@
package v2
import (
"context"
"encoding/base64"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Database Mysql
// @Summary Create mysql database
// @Accept json
// @Param request body dto.MysqlDBCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 mysql 数据库 [name]","formatEN":"create mysql database [name]"}
func (b *BaseApi) CreateMysql(c *gin.Context) {
var req dto.MysqlDBCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Password) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Password = string(password)
}
if _, err := mysqlService.Create(context.Background(), req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Bind user of mysql database
// @Accept json
// @Param request body dto.BindUser true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/bind [post]
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"绑定 mysql 数据库名 [database] [username]","formatEN":"bind mysql database [database] [username]"}
func (b *BaseApi) BindUser(c *gin.Context) {
var req dto.BindUser
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Password) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Password = string(password)
}
if err := mysqlService.BindUser(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Update mysql database description
// @Accept json
// @Param request body dto.UpdateDescription true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/description/update [post]
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := mysqlService.UpdateDescription(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Change mysql password
// @Accept json
// @Param request body dto.ChangeDBInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/change/password [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Value) != 0 {
value, err := base64.StdEncoding.DecodeString(req.Value)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Value = string(value)
}
if err := mysqlService.ChangePassword(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Change mysql access
// @Accept json
// @Param request body dto.ChangeDBInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/change/access [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := mysqlService.ChangeAccess(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Update mysql variables
// @Accept json
// @Param request body dto.MysqlVariablesUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/variables/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"调整 mysql 数据库性能参数","formatEN":"adjust mysql database performance parameters"}
func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
var req dto.MysqlVariablesUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := mysqlService.UpdateVariables(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Page mysql databases
// @Accept json
// @Param request body dto.MysqlDBSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/search [post]
func (b *BaseApi) SearchMysql(c *gin.Context) {
var req dto.MysqlDBSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := mysqlService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Database Mysql
// @Summary List mysql database format collation options
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200 {array} dto.MysqlFormatCollationOption
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/format/options [post]
func (b *BaseApi) ListDBFormatCollationOptions(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
helper.SuccessWithData(c, mysqlService.LoadFormatOption(req))
}
// @Tags Database Mysql
// @Summary Load mysql database from remote
// @Accept json
// @Param request body dto.MysqlLoadDB true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/load [post]
func (b *BaseApi) LoadDBFromRemote(c *gin.Context) {
var req dto.MysqlLoadDB
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := mysqlService.LoadFromRemote(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Check before delete mysql database
// @Accept json
// @Param request body dto.MysqlDBDeleteCheck true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/del/check [post]
func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
var req dto.MysqlDBDeleteCheck
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
apps, err := mysqlService.DeleteCheck(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, apps)
}
// @Tags Database Mysql
// @Summary Delete mysql database
// @Accept json
// @Param request body dto.MysqlDBDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
tx, ctx := helper.GetTxAndContext()
if err := mysqlService.Delete(ctx, req); err != nil {
helper.InternalServer(c, err)
tx.Rollback()
return
}
tx.Commit()
helper.Success(c)
}
// @Tags Database Mysql
// @Summary Load mysql remote access
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {boolean} isRemote
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/remote [post]
func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
isRemote, err := mysqlService.LoadRemoteAccess(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, isRemote)
}
// @Tags Database Mysql
// @Summary Load mysql status info
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {object} dto.MysqlStatus
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/status [post]
func (b *BaseApi) LoadStatus(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := mysqlService.LoadStatus(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Database Mysql
// @Summary Load mysql variables info
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {object} dto.MysqlVariables
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/variables [post]
func (b *BaseApi) LoadVariables(c *gin.Context) {
var req dto.OperationWithNameAndType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := mysqlService.LoadVariables(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}

@ -0,0 +1,233 @@
package v2
import (
"context"
"encoding/base64"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Database PostgreSQL
// @Summary Create postgresql database
// @Accept json
// @Param request body dto.PostgresqlDBCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 postgresql 数据库 [name]","formatEN":"create postgresql database [name]"}
func (b *BaseApi) CreatePostgresql(c *gin.Context) {
var req dto.PostgresqlDBCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Password) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Password = string(password)
}
if _, err := postgresqlService.Create(context.Background(), req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database PostgreSQL
// @Summary Bind postgresql user
// @Accept json
// @Param request body dto.PostgresqlBindUser true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/bind [post]
// @x-panel-log {"bodyKeys":["name", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"绑定 postgresql 数据库 [name] 用户 [username]","formatEN":"bind postgresql database [name] user [username]"}
func (b *BaseApi) BindPostgresqlUser(c *gin.Context) {
var req dto.PostgresqlBindUser
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := postgresqlService.BindUser(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database PostgreSQL
// @Summary Update postgresql database description
// @Accept json
// @Param request body dto.UpdateDescription true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/description [post]
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_postgresqls","output_column":"name","output_value":"name"}],"formatZH":"postgresql 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the postgresql database [name] is modified => [description]"}
func (b *BaseApi) UpdatePostgresqlDescription(c *gin.Context) {
var req dto.UpdateDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := postgresqlService.UpdateDescription(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database PostgreSQL
// @Summary Change postgresql privileges
// @Accept json
// @Param request body dto.ChangeDBInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/privileges [post]
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新数据库 [database] 用户 [username] 权限","formatEN":"Update [user] privileges of database [database]"}
func (b *BaseApi) ChangePostgresqlPrivileges(c *gin.Context) {
var req dto.PostgresqlPrivileges
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := postgresqlService.ChangePrivileges(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database PostgreSQL
// @Summary Change postgresql password
// @Accept json
// @Param request body dto.ChangeDBInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/password [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_postgresqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 密码","formatEN":"Update database [name] password"}
func (b *BaseApi) ChangePostgresqlPassword(c *gin.Context) {
var req dto.ChangeDBInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Value) != 0 {
value, err := base64.StdEncoding.DecodeString(req.Value)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Value = string(value)
}
if err := postgresqlService.ChangePassword(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database PostgreSQL
// @Summary Page postgresql databases
// @Accept json
// @Param request body dto.PostgresqlDBSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/search [post]
func (b *BaseApi) SearchPostgresql(c *gin.Context) {
var req dto.PostgresqlDBSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := postgresqlService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Database PostgreSQL
// @Summary Load postgresql database from remote
// @Accept json
// @Param request body dto.PostgresqlLoadDB true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/:database/load [post]
func (b *BaseApi) LoadPostgresqlDBFromRemote(c *gin.Context) {
database, err := helper.GetStrParamByKey(c, "database")
if err != nil {
helper.BadRequest(c, err)
return
}
if err := postgresqlService.LoadFromRemote(database); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database PostgreSQL
// @Summary Check before delete postgresql database
// @Accept json
// @Param request body dto.PostgresqlDBDeleteCheck true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/del/check [post]
func (b *BaseApi) DeleteCheckPostgresql(c *gin.Context) {
var req dto.PostgresqlDBDeleteCheck
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
apps, err := postgresqlService.DeleteCheck(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, apps)
}
// @Tags Database PostgreSQL
// @Summary Delete postgresql database
// @Accept json
// @Param request body dto.PostgresqlDBDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/pg/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_postgresqls","output_column":"name","output_value":"name"}],"formatZH":"删除 postgresql 数据库 [name]","formatEN":"delete postgresql database [name]"}
func (b *BaseApi) DeletePostgresql(c *gin.Context) {
var req dto.PostgresqlDBDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
tx, ctx := helper.GetTxAndContext()
if err := postgresqlService.Delete(ctx, req); err != nil {
helper.InternalServer(c, err)
tx.Rollback()
return
}
tx.Commit()
helper.Success(c)
}

@ -0,0 +1,169 @@
package v2
import (
"encoding/base64"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Database Redis
// @Summary Load redis status info
// @Accept json
// @Param request body dto.LoadRedisStatus true "request"
// @Success 200 {object} dto.RedisStatus
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/redis/status [post]
func (b *BaseApi) LoadRedisStatus(c *gin.Context) {
var req dto.LoadRedisStatus
if err := helper.CheckBind(&req, c); err != nil {
return
}
data, err := redisService.LoadStatus(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Database Redis
// @Summary Load redis conf
// @Accept json
// @Param request body dto.LoadRedisStatus true "request"
// @Success 200 {object} dto.RedisConf
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/redis/conf [post]
func (b *BaseApi) LoadRedisConf(c *gin.Context) {
var req dto.LoadRedisStatus
if err := helper.CheckBind(&req, c); err != nil {
return
}
data, err := redisService.LoadConf(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Database Redis
// @Summary Load redis persistence conf
// @Accept json
// @Param request body dto.LoadRedisStatus true "request"
// @Success 200 {object} dto.RedisPersistence
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/redis/persistence/conf [post]
func (b *BaseApi) LoadPersistenceConf(c *gin.Context) {
var req dto.LoadRedisStatus
if err := helper.CheckBind(&req, c); err != nil {
return
}
data, err := redisService.LoadPersistenceConf(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
func (b *BaseApi) CheckHasCli(c *gin.Context) {
helper.SuccessWithData(c, redisService.CheckHasCli())
}
// @Tags Database Redis
// @Summary Install redis-cli
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/redis/install/cli [post]
func (b *BaseApi) InstallCli(c *gin.Context) {
if err := redisService.InstallCli(); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Redis
// @Summary Update redis conf
// @Accept json
// @Param request body dto.RedisConfUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/redis/conf/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"}
func (b *BaseApi) UpdateRedisConf(c *gin.Context) {
var req dto.RedisConfUpdate
if err := helper.CheckBind(&req, c); err != nil {
return
}
if err := redisService.UpdateConf(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Redis
// @Summary Change redis password
// @Accept json
// @Param request body dto.ChangeRedisPass true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/redis/password [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 redis 数据库密码","formatEN":"change the password of the redis database"}
func (b *BaseApi) ChangeRedisPassword(c *gin.Context) {
var req dto.ChangeRedisPass
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Value) != 0 {
value, err := base64.StdEncoding.DecodeString(req.Value)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Value = string(value)
}
if err := redisService.ChangePassword(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Database Redis
// @Summary Update redis persistence conf
// @Accept json
// @Param request body dto.RedisConfPersistenceUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /databases/redis/persistence/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"redis 数据库持久化配置更新","formatEN":"redis database persistence configuration update"}
func (b *BaseApi) UpdateRedisPersistenceConf(c *gin.Context) {
var req dto.RedisConfPersistenceUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := redisService.UpdatePersistenceConf(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,250 @@
package v2
import (
"encoding/base64"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Device
// @Summary Load device base info
// @Success 200 {object} dto.DeviceBaseInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/base [post]
func (b *BaseApi) LoadDeviceBaseInfo(c *gin.Context) {
data, err := deviceService.LoadBaseInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Device
// @Summary list time zone options
// @Accept json
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/zone/options [get]
func (b *BaseApi) LoadTimeOption(c *gin.Context) {
list, err := deviceService.LoadTimeZone()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Device
// @Summary load conf
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/conf [post]
func (b *BaseApi) LoadDeviceConf(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list, err := deviceService.LoadConf(req.Name)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Device
// @Summary Update device conf by file
// @Accept json
// @Param request body dto.UpdateByNameAndFile true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/update/byconf [post]
func (b *BaseApi) UpdateDeviceByFile(c *gin.Context) {
var req dto.UpdateByNameAndFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := deviceService.UpdateByConf(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Device
// @Summary Load user list
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/users [get]
func (b *BaseApi) LoadUsers(c *gin.Context) {
users, err := deviceService.LoadUsers()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, users)
}
// @Tags Device
// @Summary Update device
// @Accept json
// @Param request body dto.SettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/update/conf [post]
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改主机参数 [key] => [value]","formatEN":"update device conf [key] => [value]"}
func (b *BaseApi) UpdateDeviceConf(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := deviceService.Update(req.Key, req.Value); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Device
// @Summary Update device hosts
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/update/host [post]
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改主机 Host [key] => [value]","formatEN":"update device host [key] => [value]"}
func (b *BaseApi) UpdateDeviceHost(c *gin.Context) {
var req []dto.HostHelper
if err := helper.CheckBind(&req, c); err != nil {
return
}
if err := deviceService.UpdateHosts(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Device
// @Summary Update device passwd
// @Accept json
// @Param request body dto.ChangePasswd true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/update/passwd [post]
func (b *BaseApi) UpdateDevicePasswd(c *gin.Context) {
var req dto.ChangePasswd
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Passwd) != 0 {
password, err := base64.StdEncoding.DecodeString(req.Passwd)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Passwd = string(password)
}
if err := deviceService.UpdatePasswd(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Device
// @Summary Update device swap
// @Accept json
// @Param request body dto.SwapHelper true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/update/swap [post]
// @x-panel-log {"bodyKeys":["operate","path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 主机 swap [path]","formatEN":"[operate] device swap [path]"}
func (b *BaseApi) UpdateDeviceSwap(c *gin.Context) {
var req dto.SwapHelper
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := deviceService.UpdateSwap(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Device
// @Summary Check device DNS conf
// @Accept json
// @Param request body dto.SettingUpdate true "request"
// @Success 200 {boolean} data
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/device/check/dns [post]
func (b *BaseApi) CheckDNS(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := deviceService.CheckDNS(req.Key, req.Value)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Device
// @Summary Scan system
// @Success 200 {object} dto.CleanData
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/scan [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"扫描系统垃圾文件","formatEN":"scan System Junk Files"}
func (b *BaseApi) ScanSystem(c *gin.Context) {
helper.SuccessWithData(c, deviceService.Scan())
}
// @Tags Device
// @Summary Clean system
// @Accept json
// @Param request body []dto.Clean true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/clean [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理系统垃圾文件","formatEN":"Clean system junk files"}
func (b *BaseApi) SystemClean(c *gin.Context) {
var req []dto.Clean
if err := helper.CheckBind(&req, c); err != nil {
return
}
deviceService.Clean(req)
helper.Success(c)
}

@ -0,0 +1,99 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Disk Management
// @Summary Get complete disk information
// @Description Get information about all disks including partitioned and unpartitioned disks
// @Produce json
// @Success 200 {object} response.CompleteDiskInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/disks [get]
func (b *BaseApi) GetCompleteDiskInfo(c *gin.Context) {
diskInfo, err := diskService.GetCompleteDiskInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, diskInfo)
}
// @Tags Disk Management
// @Summary Partition disk
// @Description Create partition and format disk with specified filesystem
// @Accept json
// @Param request body request.DiskPartitionRequest true "partition request"
// @Success 200 {string} string "Partition created successfully"
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/disks/partition [post]
// @x-panel-log {"bodyKeys":["device", "filesystem", "mountPoint"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"对磁盘 [device] 进行分区,文件系统 [filesystem],挂载点 [mountPoint]","formatEN":"Partition disk [device] with filesystem [filesystem], mount point [mountPoint]"}
func (b *BaseApi) PartitionDisk(c *gin.Context) {
var req request.DiskPartitionRequest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
result, err := diskService.PartitionDisk(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, result)
}
// @Tags Disk Management
// @Summary Mount disk
// @Description Mount partition to specified mount point
// @Accept json
// @Param request body request.DiskMountRequest true "mount request"
// @Success 200 {string} string "Disk mounted successfully"
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/disks/mount [post]
// @x-panel-log {"bodyKeys":["device", "mountPoint"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"挂载磁盘 [device] 到 [mountPoint]","formatEN":"Mount disk [device] to [mountPoint]"}
func (b *BaseApi) MountDisk(c *gin.Context) {
var req request.DiskMountRequest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := diskService.MountDisk(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Disk Management
// @Summary Unmount disk
// @Description Unmount partition from mount point
// @Accept json
// @Param request body request.DiskUnmountRequest true "unmount request"
// @Success 200 {string} string "Disk unmounted successfully"
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/disks/unmount [post]
// @x-panel-log {"bodyKeys":["device", "mountPoint"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"卸载磁盘 [device] 从 [mountPoint]","formatEN":"Unmount disk [device] from [mountPoint]"}
func (b *BaseApi) UnmountDisk(c *gin.Context) {
var req request.DiskUnmountRequest
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := diskService.UnmountDisk(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,173 @@
package v2
import (
"os"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/gin-gonic/gin"
)
// @Tags Container Docker
// @Summary Load docker status
// @Produce json
// @Success 200 {string} dto.DockerStatus
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/docker/status [get]
func (b *BaseApi) LoadDockerStatus(c *gin.Context) {
status := dockerService.LoadDockerStatus()
helper.SuccessWithData(c, status)
}
// @Tags Container Docker
// @Summary Load docker daemon.json
// @Produce json
// @Success 200 {object} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/daemonjson/file [get]
func (b *BaseApi) LoadDaemonJsonFile(c *gin.Context) {
if _, err := os.Stat(constant.DaemonJsonPath); err != nil {
helper.SuccessWithData(c, "daemon.json is not find in path")
return
}
content, err := os.ReadFile(constant.DaemonJsonPath)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, string(content))
}
// @Tags Container Docker
// @Summary Load docker daemon.json
// @Produce json
// @Success 200 {object} dto.DaemonJsonConf
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/daemonjson [get]
func (b *BaseApi) LoadDaemonJson(c *gin.Context) {
conf, err := dockerService.LoadDockerConf()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, conf)
}
// @Tags Container Docker
// @Summary Update docker daemon.json
// @Accept json
// @Param request body dto.SettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/daemonjson/update [post]
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新配置 [key]","formatEN":"Updated configuration [key]"}
func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := dockerService.UpdateConf(req, true); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Docker
// @Summary Update docker daemon.json log option
// @Accept json
// @Param request body dto.LogOption true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/logoption/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新日志配置","formatEN":"Updated the log option"}
func (b *BaseApi) UpdateLogOption(c *gin.Context) {
var req dto.LogOption
if err := helper.CheckBind(&req, c); err != nil {
return
}
if err := dockerService.UpdateLogOption(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Docker
// @Summary Update docker daemon.json ipv6 option
// @Accept json
// @Param request body dto.LogOption true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/ipv6option/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 ipv6 配置","formatEN":"Updated the ipv6 option"}
func (b *BaseApi) UpdateIpv6Option(c *gin.Context) {
var req dto.Ipv6Option
if err := helper.CheckBind(&req, c); err != nil {
return
}
if err := dockerService.UpdateIpv6Option(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Docker
// @Summary Update docker daemon.json by upload file
// @Accept json
// @Param request body dto.DaemonJsonUpdateByFile true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/daemonjson/update/byfile [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新配置文件","formatEN":"Updated configuration file"}
func (b *BaseApi) UpdateDaemonJsonByFile(c *gin.Context) {
var req dto.DaemonJsonUpdateByFile
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := dockerService.UpdateConfByFile(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Docker
// @Summary Operate docker
// @Accept json
// @Param request body dto.DockerOperation true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/docker/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"docker 服务 [operation]","formatEN":"[operation] docker service"}
func (b *BaseApi) OperateDocker(c *gin.Context) {
var req dto.DockerOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := dockerService.OperateDocker(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,79 @@
package v2
import "github.com/1Panel-dev/1Panel/agent/app/service"
type ApiGroup struct {
BaseApi
}
var ApiGroupApp = new(ApiGroup)
type BaseApi struct{}
var (
dashboardService = service.NewIDashboardService()
appService = service.NewIAppService()
appInstallService = service.NewIAppInstalledService()
appIgnoreUpgradeService = service.NewIAppIgnoreUpgradeService()
aiToolService = service.NewIAIToolService()
mcpServerService = service.NewIMcpServerService()
tensorrtLLMService = service.NewITensorRTLLMService()
containerService = service.NewIContainerService()
composeTemplateService = service.NewIComposeTemplateService()
imageRepoService = service.NewIImageRepoService()
imageService = service.NewIImageService()
dockerService = service.NewIDockerService()
dbCommonService = service.NewIDBCommonService()
mysqlService = service.NewIMysqlService()
postgresqlService = service.NewIPostgresqlService()
databaseService = service.NewIDatabaseService()
redisService = service.NewIRedisService()
cronjobService = service.NewICronjobService()
fileService = service.NewIFileService()
sshService = service.NewISSHService()
firewallService = service.NewIFirewallService()
iptablesService = service.NewIIptablesService()
monitorService = service.NewIMonitorService()
systemService = service.NewISystemService()
deviceService = service.NewIDeviceService()
fail2banService = service.NewIFail2BanService()
ftpService = service.NewIFtpService()
clamService = service.NewIClamService()
settingService = service.NewISettingService()
backupService = service.NewIBackupService()
backupRecordService = service.NewIBackupRecordService()
websiteService = service.NewIWebsiteService()
websiteDnsAccountService = service.NewIWebsiteDnsAccountService()
websiteSSLService = service.NewIWebsiteSSLService()
websiteAcmeAccountService = service.NewIWebsiteAcmeAccountService()
nginxService = service.NewINginxService()
logService = service.NewILogService()
snapshotService = service.NewISnapshotService()
runtimeService = service.NewRuntimeService()
processService = service.NewIProcessService()
phpExtensionsService = service.NewIPHPExtensionsService()
hostToolService = service.NewIHostToolService()
recycleBinService = service.NewIRecycleBinService()
favoriteService = service.NewIFavoriteService()
websiteCAService = service.NewIWebsiteCAService()
taskService = service.NewITaskService()
groupService = service.NewIGroupService()
alertService = service.NewIAlertService()
diskService = service.NewIDiskService()
)

@ -0,0 +1,154 @@
package v2
import (
"os"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Fail2ban
// @Summary Load fail2ban base info
// @Success 200 {object} dto.Fail2BanBaseInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/fail2ban/base [get]
func (b *BaseApi) LoadFail2BanBaseInfo(c *gin.Context) {
data, err := fail2banService.LoadBaseInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Fail2ban
// @Summary Page fail2ban ip list
// @Accept json
// @Param request body dto.Fail2BanSearch true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/fail2ban/search [post]
func (b *BaseApi) SearchFail2Ban(c *gin.Context) {
var req dto.Fail2BanSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list, err := fail2banService.Search(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Fail2ban
// @Summary Operate fail2ban
// @Accept json
// @Param request body dto.Operate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/fail2ban/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] Fail2ban","formatEN":"[operation] Fail2ban"}
func (b *BaseApi) OperateFail2Ban(c *gin.Context) {
var req dto.Operate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := fail2banService.Operate(req.Operation); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Fail2ban
// @Summary Operate sshd of fail2ban
// @Accept json
// @Param request body dto.Fail2BanSet true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/fail2ban/operate/sshd [post]
func (b *BaseApi) OperateSSHD(c *gin.Context) {
var req dto.Fail2BanSet
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := fail2banService.OperateSSHD(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Fail2ban
// @Summary Update fail2ban conf
// @Accept json
// @Param request body dto.Fail2BanUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/fail2ban/update [post]
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 Fail2ban 配置 [key] => [value]","formatEN":"update fail2ban conf [key] => [value]"}
func (b *BaseApi) UpdateFail2BanConf(c *gin.Context) {
var req dto.Fail2BanUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := fail2banService.UpdateConf(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Fail2ban
// @Summary Load fail2ban conf
// @Accept json
// @Success 200 {string} file
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/fail2ban/load/conf [get]
func (b *BaseApi) LoadFail2BanConf(c *gin.Context) {
path := "/etc/fail2ban/jail.local"
file, err := os.ReadFile(path)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, string(file))
}
// @Tags Fail2ban
// @Summary Update fail2ban conf by file
// @Accept json
// @Param request body dto.UpdateByFile true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/fail2ban/update/byconf [post]
func (b *BaseApi) UpdateFail2BanConfByFile(c *gin.Context) {
var req dto.UpdateByFile
if err := helper.CheckBind(&req, c); err != nil {
return
}
if err := fail2banService.UpdateConfByFile(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,75 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags File
// @Summary List favorites
// @Accept json
// @Param request body dto.PageInfo true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /files/favorite/search [post]
func (b *BaseApi) SearchFavorite(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := favoriteService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: list,
})
}
// @Tags File
// @Summary Create favorite
// @Accept json
// @Param request body request.FavoriteCreate true "request"
// @Success 200 {object} model.Favorite
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /files/favorite [post]
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"收藏文件/文件夹 [path]","formatEN":"收藏文件/文件夹 [path]"}
func (b *BaseApi) CreateFavorite(c *gin.Context) {
var req request.FavoriteCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
favorite, err := favoriteService.Create(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, favorite)
}
// @Tags File
// @Summary Delete favorite
// @Accept json
// @Param request body request.FavoriteDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /files/favorite/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"favorites","output_column":"path","output_value":"path"}],"formatZH":"删除收藏 [path]","formatEN":"delete avorite [path]"}
func (b *BaseApi) DeleteFavorite(c *gin.Context) {
var req request.FavoriteDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := favoriteService.Delete(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,339 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Firewall
// @Summary Load firewall base info
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200 {object} dto.FirewallBaseInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/base [post]
func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := firewallService.LoadBaseInfo(req.Name)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Firewall
// @Summary Page firewall rules
// @Accept json
// @Param request body dto.RuleSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/search [post]
func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
var req dto.RuleSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := firewallService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Firewall
// @Summary Operate firewall
// @Accept json
// @Param request body dto.FirewallOperation true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
func (b *BaseApi) OperateFirewall(c *gin.Context) {
var req dto.FirewallOperation
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.OperateFirewall(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Create group
// @Accept json
// @Param request body dto.PortRuleOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/port [post]
// @x-panel-log {"bodyKeys":["port","strategy"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加端口规则 [strategy] [port]","formatEN":"create port rules [strategy][port]"}
func (b *BaseApi) OperatePortRule(c *gin.Context) {
var req dto.PortRuleOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.OperatePortRule(req, true); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// OperateForwardRule
// @Tags Firewall
// @Summary Operate forward rule
// @Accept json
// @Param request body dto.ForwardRuleOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/forward [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新端口转发规则","formatEN":"update port forward rules"}
func (b *BaseApi) OperateForwardRule(c *gin.Context) {
var req dto.ForwardRuleOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.OperateForwardRule(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Operate Ip rule
// @Accept json
// @Param request body dto.AddrRuleOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/ip [post]
// @x-panel-log {"bodyKeys":["strategy","address"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加 ip 规则 [strategy] [address]","formatEN":"create address rules [strategy][address]"}
func (b *BaseApi) OperateIPRule(c *gin.Context) {
var req dto.AddrRuleOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.OperateAddressRule(req, true); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Batch operate rule
// @Accept json
// @Param request body dto.BatchRuleOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/batch [post]
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
var req dto.BatchRuleOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.BatchOperateRule(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Update rule description
// @Accept json
// @Param request body dto.UpdateFirewallDescription true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/update/description [post]
func (b *BaseApi) UpdateFirewallDescription(c *gin.Context) {
var req dto.UpdateFirewallDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.UpdateDescription(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Update port rule
// @Accept json
// @Param request body dto.PortRuleUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/update/port [post]
func (b *BaseApi) UpdatePortRule(c *gin.Context) {
var req dto.PortRuleUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.UpdatePortRule(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Update Ip rule
// @Accept json
// @Param request body dto.AddrRuleUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/update/addr [post]
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
var req dto.AddrRuleUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := firewallService.UpdateAddrRule(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary search iptables filter rules
// @Accept json
// @Param request body dto.SearchPageWithType true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/filter/search [post]
func (b *BaseApi) SearchFilterRules(c *gin.Context) {
var req dto.SearchPageWithType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := iptablesService.Search(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Firewall
// @Summary Operate iptables filter rule
// @Accept json
// @Param request body dto.IptablesRuleOp true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/filter/rule/operate [post]
// @x-panel-log {"bodyKeys":["operation","chain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] filter规则到 [chain]","formatEN":"[operation] filter rule to [chain]"}
func (b *BaseApi) OperateFilterRule(c *gin.Context) {
var req dto.IptablesRuleOp
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := iptablesService.OperateRule(req, true); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Batch operate iptables filter rules
// @Accept json
// @Param request body dto.IptablesBatchOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/filter/rule/batch [post]
func (b *BaseApi) BatchOperateFilterRule(c *gin.Context) {
var req dto.IptablesBatchOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := iptablesService.BatchOperate(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary Apply/Unload/Init iptables filter
// @Accept json
// @Param request body dto.IptablesOp true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/filter/operate [post]
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] iptables filter 防火墙","formatEN":"[operate] iptables filter firewall"}
func (b *BaseApi) OperateFilterChain(c *gin.Context) {
var req dto.IptablesOp
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := iptablesService.Operate(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Firewall
// @Summary load chain status with name
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/firewall/filter/chain/status [post]
func (b *BaseApi) LoadChainStatus(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
helper.SuccessWithData(c, iptablesService.LoadChainStatus(req))
}

@ -0,0 +1,199 @@
package v2
import (
"encoding/base64"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags FTP
// @Summary Load FTP base info
// @Success 200 {object} dto.FtpBaseInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp/base [get]
func (b *BaseApi) LoadFtpBaseInfo(c *gin.Context) {
data, err := ftpService.LoadBaseInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags FTP
// @Summary Load FTP operation log
// @Accept json
// @Param request body dto.FtpLogSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp/log/search [post]
func (b *BaseApi) LoadFtpLogInfo(c *gin.Context) {
var req dto.FtpLogSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := ftpService.LoadLog(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags FTP
// @Summary Operate FTP
// @Accept json
// @Param request body dto.Operate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] FTP","formatEN":"[operation] FTP"}
func (b *BaseApi) OperateFtp(c *gin.Context) {
var req dto.Operate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := ftpService.Operate(req.Operation); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags FTP
// @Summary Page FTP user
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp/search [post]
func (b *BaseApi) SearchFtp(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := ftpService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags FTP
// @Summary Create FTP user
// @Accept json
// @Param request body dto.FtpCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp [post]
// @x-panel-log {"bodyKeys":["user", "path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 FTP 账户 [user][path]","formatEN":"create FTP [user][path]"}
func (b *BaseApi) CreateFtp(c *gin.Context) {
var req dto.FtpCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Password) != 0 {
pass, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Password = string(pass)
}
if _, err := ftpService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags FTP
// @Summary Delete FTP user
// @Accept json
// @Param request body dto.BatchDeleteReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"ftps","output_column":"user","output_value":"users"}],"formatZH":"删除 FTP 账户 [users]","formatEN":"delete FTP users [users]"}
func (b *BaseApi) DeleteFtp(c *gin.Context) {
var req dto.BatchDeleteReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := ftpService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags FTP
// @Summary Sync FTP user
// @Accept json
// @Param request body dto.BatchDeleteReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp/sync [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"同步 FTP 账户","formatEN":"sync FTP users"}
func (b *BaseApi) SyncFtp(c *gin.Context) {
if err := ftpService.Sync(); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags FTP
// @Summary Update FTP user
// @Accept json
// @Param request body dto.FtpUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /toolbox/ftp/update [post]
// @x-panel-log {"bodyKeys":["user", "path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 FTP 账户 [user][path]","formatEN":"update FTP [user][path]"}
func (b *BaseApi) UpdateFtp(c *gin.Context) {
var req dto.FtpUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if len(req.Password) != 0 {
pass, err := base64.StdEncoding.DecodeString(req.Password)
if err != nil {
helper.BadRequest(c, err)
return
}
req.Password = string(pass)
}
if err := ftpService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,96 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags System Group
// @Summary Create group
// @Accept json
// @Param request body dto.GroupCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /groups [post]
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"}
func (b *BaseApi) CreateGroup(c *gin.Context) {
var req dto.GroupCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := groupService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Group
// @Summary Delete group
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /groups/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := groupService.Delete(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Group
// @Summary Update group
// @Accept json
// @Param request body dto.GroupUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /groups/update [post]
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"}
func (b *BaseApi) UpdateGroup(c *gin.Context) {
var req dto.GroupUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := groupService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Group
// @Summary List groups
// @Accept json
// @Param request body dto.GroupSearch true "request"
// @Success 200 {array} dto.OperateByType
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /groups/search [post]
func (b *BaseApi) ListGroup(c *gin.Context) {
var req dto.OperateByType
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list, err := groupService.List(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}

@ -0,0 +1,10 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/gin-gonic/gin"
)
func (b *BaseApi) CheckHealth(c *gin.Context) {
helper.Success(c)
}

@ -0,0 +1,166 @@
package helper
import (
"compress/gzip"
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"sync"
"github.com/1Panel-dev/1Panel/agent/global"
"gorm.io/gorm"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
)
func ErrorWithDetail(ctx *gin.Context, code int, msgKey string, err error) {
res := dto.Response{
Code: code,
Message: "",
}
res.Message = i18n.GetMsgWithDetail(msgKey, err.Error())
ctx.JSON(http.StatusOK, res)
ctx.Abort()
}
func InternalServer(ctx *gin.Context, err error) {
ErrorWithDetail(ctx, http.StatusInternalServerError, "ErrInternalServer", err)
}
func BadRequest(ctx *gin.Context, err error) {
ErrorWithDetail(ctx, http.StatusBadRequest, "ErrInvalidParams", err)
}
func SuccessWithData(ctx *gin.Context, data interface{}) {
if data == nil {
data = gin.H{}
}
res := dto.Response{
Code: http.StatusOK,
Data: data,
}
ctx.JSON(http.StatusOK, res)
ctx.Abort()
}
var gzipWriterPool = sync.Pool{
New: func() interface{} {
return gzip.NewWriter(nil)
},
}
func SuccessWithDataGzipped(ctx *gin.Context, data interface{}) {
if !strings.Contains(ctx.GetHeader("Accept-Encoding"), "gzip") {
SuccessWithData(ctx, data)
return
}
if data == nil {
data = gin.H{}
}
res := dto.Response{
Code: http.StatusOK,
Data: data,
}
jsonBytes, err := json.Marshal(res)
if err != nil {
ErrorWithDetail(ctx, http.StatusInternalServerError, "ErrInternalServer", err)
return
}
ctx.Header("Content-Encoding", "gzip")
ctx.Header("Content-Type", "application/json; charset=utf-8")
ctx.Status(http.StatusOK)
gz := gzipWriterPool.Get().(*gzip.Writer)
gz.Reset(ctx.Writer)
_, _ = gz.Write(jsonBytes)
_ = gz.Close()
gzipWriterPool.Put(gz)
ctx.Abort()
}
func Success(ctx *gin.Context) {
res := dto.Response{
Code: http.StatusOK,
Message: "success",
}
ctx.JSON(http.StatusOK, res)
ctx.Abort()
}
func SuccessWithMsg(ctx *gin.Context, msg string) {
res := dto.Response{
Code: http.StatusOK,
Message: msg,
}
ctx.JSON(http.StatusOK, res)
ctx.Abort()
}
func GetParamID(c *gin.Context) (uint, error) {
idParam, ok := c.Params.Get("id")
if !ok {
return 0, errors.New("error id in path")
}
intNum, _ := strconv.Atoi(idParam)
return uint(intNum), nil
}
func GetIntParamByKey(c *gin.Context, key string) (uint, error) {
idParam, ok := c.Params.Get(key)
if !ok {
return 0, fmt.Errorf("error %s in path", key)
}
intNum, _ := strconv.Atoi(idParam)
return uint(intNum), nil
}
func GetStrParamByKey(c *gin.Context, key string) (string, error) {
idParam, ok := c.Params.Get(key)
if !ok {
return "", fmt.Errorf("error %s in path", key)
}
return idParam, nil
}
func GetTxAndContext() (tx *gorm.DB, ctx context.Context) {
tx = global.DB.Begin()
ctx = context.WithValue(context.Background(), constant.DB, tx)
return
}
func CheckBindAndValidate(req interface{}, c *gin.Context) error {
if err := c.ShouldBindJSON(req); err != nil {
ErrorWithDetail(c, http.StatusBadRequest, "ErrInvalidParams", err)
return err
}
if err := global.VALID.Struct(req); err != nil {
ErrorWithDetail(c, http.StatusBadRequest, "ErrInvalidParams", err)
return err
}
return nil
}
func CheckBind(req interface{}, c *gin.Context) error {
if err := c.ShouldBindJSON(&req); err != nil {
ErrorWithDetail(c, http.StatusBadRequest, "ErrInvalidParams", err)
return err
}
return nil
}
func GetParamInt32(paramName string, c *gin.Context) (int32, error) {
idParam, ok := c.Params.Get(paramName)
if !ok {
return 0, errors.New("error id in path")
}
intNum, _ := strconv.Atoi(idParam)
return int32(intNum), nil
}

@ -0,0 +1,157 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Host tool
// @Summary Get tool status
// @Accept json
// @Param request body request.HostToolReq true "request"
// @Success 200 {object} response.HostToolRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/tool [post]
func (b *BaseApi) GetToolStatus(c *gin.Context) {
var req request.HostToolReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
config, err := hostToolService.GetToolStatus(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, config)
}
// @Tags Host tool
// @Summary Create Host tool Config
// @Accept json
// @Param request body request.HostToolCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/tool/init [post]
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 [type] 配置","formatEN":"create [type] config"}
func (b *BaseApi) InitToolConfig(c *gin.Context) {
var req request.HostToolCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := hostToolService.CreateToolConfig(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Host tool
// @Summary Operate tool
// @Accept json
// @Param request body request.HostToolReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/tool/operate [post]
// @x-panel-log {"bodyKeys":["operate","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] [type] ","formatEN":"[operate] [type]"}
func (b *BaseApi) OperateTool(c *gin.Context) {
var req request.HostToolReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := hostToolService.OperateTool(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Host tool
// @Summary Get tool config
// @Accept json
// @Param request body request.HostToolConfig true "request"
// @Success 200 {object} response.HostToolConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/tool/config [post]
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 主机工具配置文件 ","formatEN":"[operate] tool config"}
func (b *BaseApi) OperateToolConfig(c *gin.Context) {
var req request.HostToolConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
config, err := hostToolService.OperateToolConfig(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, config)
}
// @Tags Host tool
// @Summary Create Supervisor process
// @Accept json
// @Param request body request.SupervisorProcessConfig true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/tool/supervisor/process [post]
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 守护进程 ","formatEN":"[operate] process"}
func (b *BaseApi) OperateProcess(c *gin.Context) {
var req request.SupervisorProcessConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := hostToolService.OperateSupervisorProcess(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Host tool
// @Summary Get Supervisor process config
// @Accept json
// @Success 200 {object} response.SupervisorProcessConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/tool/supervisor/process [get]
func (b *BaseApi) GetProcess(c *gin.Context) {
configs, err := hostToolService.GetSupervisorProcessConfig()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, configs)
}
// @Tags Host tool
// @Summary Get Supervisor process config file
// @Accept json
// @Param request body request.SupervisorProcessFileReq true "request"
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/tool/supervisor/process/file [post]
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] Supervisor 进程文件 ","formatEN":"[operate] Supervisor Process Config file"}
func (b *BaseApi) GetProcessFile(c *gin.Context) {
var req request.SupervisorProcessFileReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
content, err := hostToolService.OperateSupervisorProcessFile(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, content)
}

@ -0,0 +1,227 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Container Image
// @Summary Page images
// @Accept json
// @Param request body dto.PageImage true "request"
// @Produce json
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/search [post]
func (b *BaseApi) SearchImage(c *gin.Context) {
var req dto.PageImage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := imageService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Container Image
// @Summary List all images
// @Produce json
// @Success 200 {array} dto.ImageInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/all [get]
func (b *BaseApi) ListAllImage(c *gin.Context) {
list, err := imageService.ListAll()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Container Image
// @Summary load images options
// @Produce json
// @Success 200 {array} dto.Options
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image [get]
func (b *BaseApi) ListImage(c *gin.Context) {
list, err := imageService.List()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Container Image
// @Summary Build image
// @Accept json
// @Param request body dto.ImageBuild true "request"
// @Success 200 {string} log
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/build [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"构建镜像 [name]","formatEN":"build image [name]"}
func (b *BaseApi) ImageBuild(c *gin.Context) {
var req dto.ImageBuild
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageService.ImageBuild(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image
// @Summary Pull image
// @Accept json
// @Param request body dto.ImagePull true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/pull [post]
// @x-panel-log {"bodyKeys":["repoID","imageName"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageService.ImagePull(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image
// @Summary Push image
// @Accept json
// @Param request body dto.ImagePush true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/push [post]
// @x-panel-log {"bodyKeys":["repoID","tagName","name"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageService.ImagePush(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image
// @Summary Delete image
// @Accept json
// @Param request body dto.BatchDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/remove [post]
// @x-panel-log {"bodyKeys":["names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"移除镜像 [names]","formatEN":"remove image [names]"}
func (b *BaseApi) ImageRemove(c *gin.Context) {
var req dto.BatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageService.ImageRemove(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image
// @Summary Save image
// @Accept json
// @Param request body dto.ImageSave true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/save [post]
// @x-panel-log {"bodyKeys":["tagName","path","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"保留 [tagName] 为 [path]/[name]","formatEN":"save [tagName] as [path]/[name]"}
func (b *BaseApi) ImageSave(c *gin.Context) {
var req dto.ImageSave
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageService.ImageSave(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image
// @Summary Tag image
// @Accept json
// @Param request body dto.ImageTag true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/tag [post]
// @x-panel-log {"bodyKeys":["repoID","targetName"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageService.ImageTag(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image
// @Summary Load image
// @Accept json
// @Param request body dto.ImageLoad true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/image/load [post]
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [path] 加载镜像","formatEN":"load image from [path]"}
func (b *BaseApi) ImageLoad(c *gin.Context) {
var req dto.ImageLoad
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageService.ImageLoad(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,142 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags Container Image-repo
// @Summary Page image repos
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Produce json
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/repo/search [post]
func (b *BaseApi) SearchRepo(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := imageRepoService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags Container Image-repo
// @Summary List image repos
// @Produce json
// @Success 200 {array} dto.ImageRepoOption
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/repo [get]
func (b *BaseApi) ListRepo(c *gin.Context) {
list, err := imageRepoService.List()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Container Image-repo
// @Summary Load repo status
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Produce json
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/repo/status [post]
func (b *BaseApi) CheckRepoStatus(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageRepoService.Login(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image-repo
// @Summary Create image repo
// @Accept json
// @Param request body dto.ImageRepoDelete true "request"
// @Produce json
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/repo [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建镜像仓库 [name]","formatEN":"create image repo [name]"}
func (b *BaseApi) CreateRepo(c *gin.Context) {
var req dto.ImageRepoCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageRepoService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image-repo
// @Summary Delete image repo
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Produce json
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/repo/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_column":"name","output_value":"name"}],"formatZH":"删除镜像仓库 [name]","formatEN":"delete image repo [name]"}
func (b *BaseApi) DeleteRepo(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageRepoService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Container Image-repo
// @Summary Update image repo
// @Accept json
// @Param request body dto.ImageRepoUpdate true "request"
// @Produce json
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /containers/repo/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := imageRepoService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,22 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/gin-gonic/gin"
)
// @Tags Logs
// @Summary Load system log files
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /logs/system/files [get]
func (b *BaseApi) GetSystemFiles(c *gin.Context) {
data, err := logService.ListSystemLogFile()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}

@ -0,0 +1,166 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags McpServer
// @Summary List mcp servers
// @Accept json
// @Param request body request.McpServerSearch true "request"
// @Success 200 {object} response.McpServersRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/search [post]
func (b *BaseApi) PageMcpServers(c *gin.Context) {
var req request.McpServerSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list := mcpServerService.Page(req)
helper.SuccessWithData(c, list)
}
// @Tags McpServer
// @Summary Create mcp server
// @Accept json
// @Param request body request.McpServerCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/server [post]
func (b *BaseApi) CreateMcpServer(c *gin.Context) {
var req request.McpServerCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := mcpServerService.Create(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags McpServer
// @Summary Update mcp server
// @Accept json
// @Param request body request.McpServerUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/server/update [post]
func (b *BaseApi) UpdateMcpServer(c *gin.Context) {
var req request.McpServerUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := mcpServerService.Update(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags McpServer
// @Summary Delete mcp server
// @Accept json
// @Param request body request.McpServerDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/server/del [post]
func (b *BaseApi) DeleteMcpServer(c *gin.Context) {
var req request.McpServerDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := mcpServerService.Delete(req.ID)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags McpServer
// @Summary Operate mcp server
// @Accept json
// @Param request body request.McpServerOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/server/op [post]
func (b *BaseApi) OperateMcpServer(c *gin.Context) {
var req request.McpServerOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := mcpServerService.Operate(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags McpServer
// @Summary Bind Domain for mcp server
// @Accept json
// @Param request body request.McpBindDomain true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/domain/bind [post]
func (b *BaseApi) BindMcpDomain(c *gin.Context) {
var req request.McpBindDomain
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := mcpServerService.BindDomain(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags McpServer
// @Summary Update bind Domain for mcp server
// @Accept json
// @Param request body request.McpBindDomainUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/domain/update [post]
func (b *BaseApi) UpdateMcpBindDomain(c *gin.Context) {
var req request.McpBindDomainUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := mcpServerService.UpdateBindDomain(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags McpServer
// @Summary Get bin Domain for mcp server
// @Accept json
// @Success 200 {object} response.McpBindDomainRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/mcp/domain/get [get]
func (b *BaseApi) GetMcpBindDomain(c *gin.Context) {
res, err := mcpServerService.GetBindDomain()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}

@ -0,0 +1,132 @@
package v2
import (
"sort"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
"github.com/shirou/gopsutil/v4/disk"
"github.com/shirou/gopsutil/v4/net"
)
// @Tags Monitor
// @Summary Load monitor data
// @Param request body dto.MonitorSearch true "request"
// @Success 200 {array} dto.MonitorData
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/monitor/search [post]
func (b *BaseApi) LoadMonitor(c *gin.Context) {
var req dto.MonitorSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := monitorService.LoadMonitorData(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithDataGzipped(c, data)
}
// @Tags Monitor
// @Summary Load monitor data
// @Param request body dto.MonitorGPUSearch true "request"
// @Success 200 {object} dto.MonitorGPUData
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/monitor/gpu/search [post]
func (b *BaseApi) LoadGPUMonitor(c *gin.Context) {
var req dto.MonitorGPUSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := monitorService.LoadGPUMonitorData(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Monitor
// @Summary Clean monitor data
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/monitor/clean [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空监控数据","formatEN":"clean monitor datas"}
func (b *BaseApi) CleanMonitor(c *gin.Context) {
if err := monitorService.CleanData(); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Monitor
// @Summary Load monitor setting
// @Success 200 {object} dto.MonitorSetting
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/monitor/setting [get]
func (b *BaseApi) LoadMonitorSetting(c *gin.Context) {
setting, err := monitorService.LoadSetting()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, setting)
}
// @Tags Monitor
// @Summary Update monitor setting
// @Param request body dto.MonitorSettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/monitor/setting/update [post]
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改默认监控网卡 [name]-[value]","formatEN":"update default monitor [name]-[value]"}
func (b *BaseApi) UpdateMonitorSetting(c *gin.Context) {
var req dto.MonitorSettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := monitorService.UpdateSetting(req.Key, req.Value); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) GetNetworkOptions(c *gin.Context) {
netStat, _ := net.IOCounters(true)
var options []string
options = append(options, "all")
for _, net := range netStat {
options = append(options, net.Name)
}
sort.Strings(options)
helper.SuccessWithData(c, options)
}
func (b *BaseApi) GetIOOptions(c *gin.Context) {
diskStat, _ := disk.IOCounters()
var options []string
options = append(options, "all")
for _, net := range diskStat {
options = append(options, net.Name)
}
sort.Strings(options)
helper.SuccessWithData(c, options)
}
func (b *BaseApi) GetCPUOptions(c *gin.Context) {
helper.SuccessWithData(c, monitorService.LoadGPUOptions())
}

@ -0,0 +1,195 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags OpenResty
// @Summary Load OpenResty conf
// @Success 200 {object} response.NginxFile
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty [get]
func (b *BaseApi) GetNginx(c *gin.Context) {
fileInfo, err := nginxService.GetNginxConfig()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, fileInfo)
}
// @Tags OpenResty
// @Summary Load partial OpenResty conf
// @Accept json
// @Param request body request.NginxScopeReq true "request"
// @Success 200 {array} response.NginxParam
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/scope [post]
func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
var req request.NginxScopeReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
params, err := nginxService.GetConfigByScope(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, params)
}
// @Tags OpenResty
// @Summary Update OpenResty conf
// @Accept json
// @Param request body request.NginxConfigUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/update [post]
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := nginxService.UpdateConfigByScope(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags OpenResty
// @Summary Load OpenResty status info
// @Success 200 {object} response.NginxStatus
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/status [get]
func (b *BaseApi) GetNginxStatus(c *gin.Context) {
res, err := nginxService.GetStatus()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags OpenResty
// @Summary Update OpenResty conf by upload file
// @Accept json
// @Param request body request.NginxConfigFileUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/file [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 nginx 配置","formatEN":"Update nginx conf"}
func (b *BaseApi) UpdateNginxFile(c *gin.Context) {
var req request.NginxConfigFileUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := nginxService.UpdateConfigFile(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags OpenResty
// @Summary Build OpenResty
// @Accept json
// @Param request body request.NginxBuildReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/build [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"构建 OpenResty","formatEN":"Build OpenResty"}
func (b *BaseApi) BuildNginx(c *gin.Context) {
var req request.NginxBuildReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := nginxService.Build(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags OpenResty
// @Summary Update OpenResty module
// @Accept json
// @Param request body request.NginxModuleUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/modules/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 OpenResty 模块","formatEN":"Update OpenResty module"}
func (b *BaseApi) UpdateNginxModule(c *gin.Context) {
var req request.NginxModuleUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := nginxService.UpdateModule(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags OpenResty
// @Summary Get OpenResty modules
// @Success 200 {object} response.NginxBuildConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/modules [get]
func (b *BaseApi) GetNginxModules(c *gin.Context) {
modules, err := nginxService.GetModules()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, modules)
}
// @Tags OpenResty
// @Summary Operate default HTTPs
// @Accept json
// @Param request body request.NginxDefaultHTTPSUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/https [post]
func (b *BaseApi) OperateDefaultHTTPs(c *gin.Context) {
var req request.NginxDefaultHTTPSUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := nginxService.OperateDefaultHTTPs(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags OpenResty
// @Summary Get default HTTPs status
// @Success 200 {object} response.NginxConfigRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /openresty/https [get]
func (b *BaseApi) GetDefaultHTTPsStatus(c *gin.Context) {
res, err := nginxService.GetDefaultHttpsStatus()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}

@ -0,0 +1,105 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags PHP Extensions
// @Summary Page Extensions
// @Accept json
// @Param request body request.PHPExtensionsSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/extensions/search [post]
func (b *BaseApi) PagePHPExtensions(c *gin.Context) {
var req request.PHPExtensionsSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if req.All {
list, err := phpExtensionsService.List()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: int64(len(list)),
Items: list,
})
} else {
total, list, err := phpExtensionsService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: list,
})
}
}
// @Tags PHP Extensions
// @Summary Create Extensions
// @Accept json
// @Param request body request.PHPExtensionsCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/extensions [post]
func (b *BaseApi) CreatePHPExtensions(c *gin.Context) {
var req request.PHPExtensionsCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := phpExtensionsService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags PHP Extensions
// @Summary Update Extensions
// @Accept json
// @Param request body request.PHPExtensionsUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/extensions/update [post]
func (b *BaseApi) UpdatePHPExtensions(c *gin.Context) {
var req request.PHPExtensionsUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := phpExtensionsService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags PHP Extensions
// @Summary Delete Extensions
// @Accept json
// @Param request body request.PHPExtensionsDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/extensions/del [post]
func (b *BaseApi) DeletePHPExtensions(c *gin.Context) {
var req request.PHPExtensionsDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := phpExtensionsService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,74 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
websocket2 "github.com/1Panel-dev/1Panel/agent/utils/websocket"
"github.com/gin-gonic/gin"
)
func (b *BaseApi) ProcessWs(c *gin.Context) {
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
if err != nil {
return
}
wsClient := websocket2.NewWsClient("processClient", ws)
go wsClient.Read()
go wsClient.Write()
}
// @Tags Process
// @Summary Stop Process
// @Param request body request.ProcessReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /process/stop [post]
// @x-panel-log {"bodyKeys":["PID"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"结束进程 [PID]","formatEN":"结束进程 [PID]"}
func (b *BaseApi) StopProcess(c *gin.Context) {
var req request.ProcessReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := processService.StopProcess(req); err != nil {
helper.BadRequest(c, err)
return
}
helper.Success(c)
}
// @Tags Process
// @Summary Get Process Info By PID
// @Param pid path int true "PID"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /process/{pid} [get]
func (b *BaseApi) GetProcessInfoByPID(c *gin.Context) {
pid, err := helper.GetParamInt32("pid", c)
if err != nil {
helper.BadRequest(c, err)
return
}
data, err := processService.GetProcessInfoByPID(pid)
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Process
// @Summary Get Listening Process
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /process/listening [post]
func (b *BaseApi) GetListeningProcess(c *gin.Context) {
procs, err := processService.GetListeningProcess(c)
if err != nil {
helper.BadRequest(c, err)
return
}
helper.SuccessWithData(c, procs)
}

@ -0,0 +1,85 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags File
// @Summary List RecycleBin files
// @Accept json
// @Param request body dto.PageInfo true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /files/recycle/search [post]
func (b *BaseApi) SearchRecycleBinFile(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := recycleBinService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags File
// @Summary Reduce RecycleBin files
// @Accept json
// @Param request body request.RecycleBinReduce true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /files/recycle/reduce [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"还原回收站文件 [name]","formatEN":"Reduce RecycleBin file [name]"}
func (b *BaseApi) ReduceRecycleBinFile(c *gin.Context) {
var req request.RecycleBinReduce
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := recycleBinService.Reduce(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags File
// @Summary Clear RecycleBin files
// @Accept json
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /files/recycle/clear [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空回收站","formatEN":"清空回收站"}
func (b *BaseApi) ClearRecycleBinFile(c *gin.Context) {
if err := recycleBinService.Clear(); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags File
// @Summary Get RecycleBin status
// @Accept json
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /files/recycle/status [get]
func (b *BaseApi) GetRecycleStatus(c *gin.Context) {
settingInfo, err := settingService.GetSettingInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, settingInfo.FileRecycleBin)
}

@ -0,0 +1,579 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Runtime
// @Summary List runtimes
// @Accept json
// @Param request body request.RuntimeSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/search [post]
func (b *BaseApi) SearchRuntimes(c *gin.Context) {
var req request.RuntimeSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, items, err := runtimeService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: items,
})
}
// @Tags Runtime
// @Summary Create runtime
// @Accept json
// @Param request body request.RuntimeCreate true "request"
// @Success 200 {object} model.Runtime
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建运行环境 [name]","formatEN":"Create runtime [name]"}
func (b *BaseApi) CreateRuntime(c *gin.Context) {
var req request.RuntimeCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
ssl, err := runtimeService.Create(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, ssl)
}
// @Tags Website
// @Summary Delete runtime
// @Accept json
// @Param request body request.RuntimeDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除运行环境 [name]","formatEN":"Delete runtime [name]"}
func (b *BaseApi) DeleteRuntime(c *gin.Context) {
var req request.RuntimeDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := runtimeService.Delete(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website
// @Summary Delete runtime
// @Accept json
// @Success 200 {array} dto.AppResource
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/installed/delete/check/:id [get]
func (b *BaseApi) DeleteRuntimeCheck(c *gin.Context) {
runTimeId, err := helper.GetIntParamByKey(c, "id")
if err != nil {
helper.BadRequest(c, err)
return
}
checkData, err := runtimeService.DeleteCheck(runTimeId)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, checkData)
}
// @Tags Runtime
// @Summary Update runtime
// @Accept json
// @Param request body request.RuntimeUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/update [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新运行环境 [name]","formatEN":"Update runtime [name]"}
func (b *BaseApi) UpdateRuntime(c *gin.Context) {
var req request.RuntimeUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := runtimeService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Get runtime
// @Accept json
// @Param id path string true "request"
// @Success 200 {object} response.RuntimeDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/:id [get]
func (b *BaseApi) GetRuntime(c *gin.Context) {
id, err := helper.GetIntParamByKey(c, "id")
if err != nil {
helper.BadRequest(c, err)
return
}
res, err := runtimeService.Get(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Runtime
// @Summary Get Node package scripts
// @Accept json
// @Param request body request.NodePackageReq true "request"
// @Success 200 {array} response.PackageScripts
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/node/package [post]
func (b *BaseApi) GetNodePackageRunScript(c *gin.Context) {
var req request.NodePackageReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := runtimeService.GetNodePackageRunScript(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Runtime
// @Summary Operate runtime
// @Accept json
// @Param request body request.RuntimeOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/operate [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"操作运行环境 [name]","formatEN":"Operate runtime [name]"}
func (b *BaseApi) OperateRuntime(c *gin.Context) {
var req request.RuntimeOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := runtimeService.OperateRuntime(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Get Node modules
// @Accept json
// @Param request body request.NodeModuleReq true "request"
// @Success 200 {array} response.NodeModule
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/node/modules [post]
func (b *BaseApi) GetNodeModules(c *gin.Context) {
var req request.NodeModuleReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := runtimeService.GetNodeModules(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Runtime
// @Summary Operate Node modules
// @Accept json
// @Param request body request.NodeModuleReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/node/modules/operate [post]
func (b *BaseApi) OperateNodeModules(c *gin.Context) {
var req request.NodeModuleOperateReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := runtimeService.OperateNodeModules(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Sync runtime status
// @Accept json
// @Success 200
// @Security ApiKeyAuth
// @Router /runtimes/sync [post]
func (b *BaseApi) SyncStatus(c *gin.Context) {
err := runtimeService.SyncRuntimeStatus()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Get php runtime extension
// @Accept json
// @Param id path string true "request"
// @Success 200 {object} response.PHPExtensionRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/:id/extensions [get]
func (b *BaseApi) GetRuntimeExtension(c *gin.Context) {
id, err := helper.GetIntParamByKey(c, "id")
if err != nil {
helper.BadRequest(c, err)
return
}
res, err := runtimeService.GetPHPExtensions(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Runtime
// @Summary Install php extension
// @Accept json
// @Param request body request.PHPExtensionInstallReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/extensions/install [post]
func (b *BaseApi) InstallPHPExtension(c *gin.Context) {
var req request.PHPExtensionInstallReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := runtimeService.InstallPHPExtension(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary UnInstall php extension
// @Accept json
// @Param request body request.PHPExtensionInstallReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/extensions/uninstall [post]
func (b *BaseApi) UnInstallPHPExtension(c *gin.Context) {
var req request.PHPExtensionInstallReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := runtimeService.UnInstallPHPExtension(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Load php runtime conf
// @Accept json
// @Param id path integer true "request"
// @Success 200 {object} response.PHPConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/config/:id [get]
func (b *BaseApi) GetPHPConfig(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.BadRequest(c, err)
return
}
data, err := runtimeService.GetPHPConfig(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Runtime
// @Summary Update runtime php conf
// @Accept json
// @Param request body request.PHPConfigUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/config [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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) UpdatePHPConfig(c *gin.Context) {
var req request.PHPConfigUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := runtimeService.UpdatePHPConfig(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Update php conf file
// @Accept json
// @Param request body request.PHPFileUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/update [post]
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFunctions":[{"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.PHPFileUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := runtimeService.UpdatePHPConfigFile(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Get php conf file
// @Accept json
// @Param request body request.PHPFileReq true "request"
// @Success 200 {object} response.FileInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/file [post]
func (b *BaseApi) GetPHPConfigFile(c *gin.Context) {
var req request.PHPFileReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := runtimeService.GetPHPConfigFile(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Runtime
// @Summary Update fpm config
// @Accept json
// @Param request body request.FPMConfig true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/fpm/config [post]
func (b *BaseApi) UpdateFPMConfig(c *gin.Context) {
var req request.FPMConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := runtimeService.UpdateFPMConfig(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Get fpm config
// @Accept json
// @Param id path integer true "request"
// @Success 200 {object} request.FPMConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/fpm/config/:id [get]
func (b *BaseApi) GetFPMConfig(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.BadRequest(c, err)
return
}
data, err := runtimeService.GetFPMConfig(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Runtime
// @Summary Get supervisor process
// @Accept json
// @Param id path integer true "request"
// @Success 200 {array} response.SupervisorProcessConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/supervisor/process/:id [get]
func (b *BaseApi) GetSupervisorProcess(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.BadRequest(c, err)
return
}
data, err := runtimeService.GetSupervisorProcess(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Runtime
// @Summary Operate supervisor process
// @Accept json
// @Param request body request.PHPSupervisorProcessConfig true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/supervisor/process [post]
func (b *BaseApi) OperateSupervisorProcess(c *gin.Context) {
var req request.PHPSupervisorProcessConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := runtimeService.OperateSupervisorProcess(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Operate supervisor process file
// @Accept json
// @Param request body request.PHPSupervisorProcessFileReq true "request"
// @Success 200 {string} content
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/supervisor/process/file [post]
func (b *BaseApi) OperateSupervisorProcessFile(c *gin.Context) {
var req request.PHPSupervisorProcessFileReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := runtimeService.OperateSupervisorProcessFile(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Runtime
// @Summary Update PHP container config
// @Accept json
// @Param request body request.PHPContainerConfig true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/container/update [post]
func (b *BaseApi) UpdatePHPContainer(c *gin.Context) {
var req request.PHPContainerConfig
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := runtimeService.UpdatePHPContainer(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Get PHP container config
// @Accept json
// @Param id path integer true "request"
// @Success 200 {object} request.PHPContainerConfig
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/container/:id [get]
func (b *BaseApi) GetPHPContainerConfig(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.BadRequest(c, err)
return
}
data, err := runtimeService.GetPHPContainerConfig(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags Runtime
// @Summary Update runtime remark
// @Accept json
// @Param request body request.RuntimeRemark true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/remark [post]
func (b *BaseApi) UpdateRuntimeRemark(c *gin.Context) {
var req request.RuntimeRemark
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := runtimeService.UpdateRemark(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Runtime
// @Summary Get PHP runtime status
// @Accept json
// @Param id path integer true "request"
// @Success 200 {object} map[string]interface{}
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /runtimes/php/fpm/status/:id [get]
func (b *BaseApi) GetFPMStatus(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.BadRequest(c, err)
return
}
data, err := runtimeService.GetFPMStatus(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}

@ -0,0 +1,200 @@
package v2
import (
"encoding/json"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/model"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/ssh"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
)
// @Tags System Setting
// @Summary Load system setting info
// @Success 200 {object} dto.SettingInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/search [post]
func (b *BaseApi) GetSettingInfo(c *gin.Context) {
setting, err := settingService.GetSettingInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, setting)
}
// @Tags System Setting
// @Summary Load system available status
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/search/available [get]
func (b *BaseApi) GetSystemAvailable(c *gin.Context) {
helper.Success(c)
}
// @Tags System Setting
// @Summary Update system setting
// @Accept json
// @Param request body dto.SettingUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/update [post]
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统配置 [key] => [value]","formatEN":"update system setting [key] => [value]"}
func (b *BaseApi) UpdateSetting(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := settingService.Update(req.Key, req.Value); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Load local backup dir
// @Success 200 {string} path
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/basedir [get]
func (b *BaseApi) LoadBaseDir(c *gin.Context) {
helper.SuccessWithData(c, global.Dir.DataDir)
}
// @Tags System Setting
// @Summary Load local conn
// @Success 200 {object} dto.SSHConnData
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/ssh/conn [get]
func (b *BaseApi) LoadLocalConn(c *gin.Context) {
helper.SuccessWithData(c, settingService.GetLocalConn())
}
func (b *BaseApi) CheckLocalConn(c *gin.Context) {
_, err := loadLocalConn()
helper.SuccessWithData(c, err == nil)
}
// @Tags System Setting
// @Summary Update local is conn
// @Accept json
// @Param request body dto.SSHDefaultConn true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/ssh/conn/default [post]
// @x-panel-log {"bodyKeys":["defaultConn"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"本地终端默认连接 [defaultConn]","formatEN":"update system default conn [defaultConn]"}
func (b *BaseApi) SetDefaultIsConn(c *gin.Context) {
var req dto.SSHDefaultConn
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := settingService.SetDefaultIsConn(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Check local conn info
// @Success 200 {boolean} isOk
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/ssh/check/info [post]
func (b *BaseApi) CheckLocalConnByInfo(c *gin.Context) {
var req dto.SSHConnData
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
helper.SuccessWithData(c, settingService.TestConnByInfo(req))
}
// @Tags System Setting
// @Summary Save local conn info
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/ssh [post]
func (b *BaseApi) SaveLocalConn(c *gin.Context) {
var req dto.SSHConnData
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := settingService.SaveConnInfo(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func loadLocalConn() (*ssh.SSHClient, error) {
connInfoInDB := settingService.GetSettingByKey("LocalSSHConn")
if len(connInfoInDB) == 0 {
return nil, errors.New("no such ssh conn info in db!")
}
var connInDB model.LocalConnInfo
if err := json.Unmarshal([]byte(connInfoInDB), &connInDB); err != nil {
return nil, err
}
sshInfo := ssh.ConnInfo{
Addr: connInDB.Addr,
Port: int(connInDB.Port),
User: connInDB.User,
AuthMode: connInDB.AuthMode,
Password: connInDB.Password,
PrivateKey: []byte(connInDB.PrivateKey),
PassPhrase: []byte(connInDB.PassPhrase),
}
return ssh.NewClient(sshInfo)
}
// @Tags System Setting
// @Summary Load system setting by key
// @Param key path string true "key"
// @Success 200 {object} dto.SettingInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/get/{key} [get]
func (b *BaseApi) GetSettingByKey(c *gin.Context) {
key := c.Param("key")
if len(key) == 0 {
helper.BadRequest(c, errors.New("key is empty"))
return
}
value := settingService.GetSettingByKey(key)
helper.SuccessWithData(c, value)
}
// @Tags System Setting
// @Summary Save common description
// @Accept json
// @Param request body dto.CommonDescription true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/description/save [post]
func (b *BaseApi) SaveDescription(c *gin.Context) {
var req dto.CommonDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := settingService.SaveDescription(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,201 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags System Setting
// @Summary Load system snapshot data
// @Success 200 {object} dto.SnapshotData
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/load [get]
func (b *BaseApi) LoadSnapshotData(c *gin.Context) {
data, err := snapshotService.LoadSnapshotData()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags System Setting
// @Summary Create system snapshot
// @Accept json
// @Param request body dto.SnapshotCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot [post]
// @x-panel-log {"bodyKeys":["from", "description"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建系统快照 [description] 到 [from]","formatEN":"Create system backup [description] to [from]"}
func (b *BaseApi) CreateSnapshot(c *gin.Context) {
var req dto.SnapshotCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := snapshotService.SnapshotCreate(nil, req, 0, 3); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Recreate system snapshot
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/recreate [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"重试创建快照 [name]","formatEN":"recrete the snapshot [name]"}
func (b *BaseApi) RecreateSnapshot(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := snapshotService.SnapshotReCreate(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Import system snapshot
// @Accept json
// @Param request body dto.SnapshotImport true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/import [post]
// @x-panel-log {"bodyKeys":["from", "names"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [from] 同步系统快照 [names]","formatEN":"Sync system snapshots [names] from [from]"}
func (b *BaseApi) ImportSnapshot(c *gin.Context) {
var req dto.SnapshotImport
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := snapshotService.SnapshotImport(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Update snapshot description
// @Accept json
// @Param request body dto.UpdateDescription true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/description/update [post]
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := snapshotService.UpdateDescription(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Page system snapshot
// @Accept json
// @Param request body dto.PageSnapshot true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/search [post]
func (b *BaseApi) SearchSnapshot(c *gin.Context) {
var req dto.PageSnapshot
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, accounts, err := snapshotService.SearchWithPage(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: accounts,
})
}
// @Tags System Setting
// @Summary Recover system backup
// @Accept json
// @Param request body dto.SnapshotRecover true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/recover [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := snapshotService.SnapshotRecover(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Rollback system backup
// @Accept json
// @Param request body dto.SnapshotRecover true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/rollback [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := snapshotService.SnapshotRollback(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags System Setting
// @Summary Delete system backup
// @Accept json
// @Param request body dto.SnapshotBatchDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/snapshot/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"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.SnapshotBatchDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := snapshotService.Delete(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,294 @@
package v2
import (
"encoding/base64"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags SSH
// @Summary Load host SSH setting info
// @Success 200 {object} dto.SSHInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/search [post]
func (b *BaseApi) GetSSHInfo(c *gin.Context) {
info, err := sshService.GetSSHInfo()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, info)
}
// @Tags SSH
// @Summary Operate SSH
// @Accept json
// @Param request body dto.Operate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/operate [post]
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] SSH ","formatEN":"[operation] SSH"}
func (b *BaseApi) OperateSSH(c *gin.Context) {
var req dto.Operate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := sshService.OperateSSH(req.Operation); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags SSH
// @Summary Update host SSH setting
// @Accept json
// @Param request body dto.SSHUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/update [post]
// @x-panel-log {"bodyKeys":["key","newValue"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置 [key] => [newValue]","formatEN":"update SSH setting [key] => [newValue]"}
func (b *BaseApi) UpdateSSH(c *gin.Context) {
var req dto.SSHUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := sshService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags SSH
// @Summary Generate host SSH secret
// @Accept json
// @Param request body dto.RootCertOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/cert [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
func (b *BaseApi) CreateRootCert(c *gin.Context) {
var req dto.RootCertOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := loadCertAfterDecrypt(&req); err != nil {
helper.BadRequest(c, err)
}
if err := sshService.CreateRootCert(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags SSH
// @Summary Update host SSH secret
// @Accept json
// @Param request body dto.RootCertOperate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/cert/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
func (b *BaseApi) EditRootCert(c *gin.Context) {
var req dto.RootCertOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := loadCertAfterDecrypt(&req); err != nil {
helper.BadRequest(c, err)
}
if err := sshService.EditRootCert(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags SSH
// @Summary Sycn host SSH secret
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/cert/sync [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"同步 SSH 密钥 ","formatEN":"sync SSH secret"}
func (b *BaseApi) SyncRootCert(c *gin.Context) {
if err := sshService.SyncRootCert(); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags SSH
// @Summary Load host SSH secret
// @Accept json
// @Param request body dto.SearchWithPage true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/cert/search [post]
func (b *BaseApi) SearchRootCert(c *gin.Context) {
var req dto.SearchWithPage
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, data, err := sshService.SearchRootCerts(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: data,
})
}
// @Tags SSH
// @Summary Delete host SSH secret
// @Accept json
// @Param request body dto.ForceDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/cert/delete [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除 SSH 密钥 ","formatEN":"delete SSH secret"}
func (b *BaseApi) DeleteRootCert(c *gin.Context) {
var req dto.ForceDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := sshService.DeleteRootCerts(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags SSH
// @Summary Load host SSH logs
// @Accept json
// @Param request body dto.SearchSSHLog true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/log [post]
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
var req dto.SearchSSHLog
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, data, err := sshService.LoadLog(c, req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: data,
})
}
// @Tags SSH
// @Summary Export host SSH logs
// @Accept json
// @Param request body dto.SearchSSHLog true "request"
// @Success 200 {string} path
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/log/export [post]
func (b *BaseApi) ExportSSHLogs(c *gin.Context) {
var req dto.SearchSSHLog
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
tmpFile, err := sshService.ExportLog(c, req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, tmpFile)
}
// @Tags SSH
// @Summary Load host SSH conf
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200 {string} conf
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/file [post]
func (b *BaseApi) LoadSSHFile(c *gin.Context) {
var req dto.OperationWithName
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := sshService.LoadSSHFile(req.Name)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, data)
}
// @Tags SSH
// @Summary Update host SSH setting by file
// @Accept json
// @Param request body dto.SSHConf true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/ssh/file/update [post]
// @x-panel-log {"bodyKeys":["key"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置文件 [key]","formatEN":"update SSH conf [key]"}
func (b *BaseApi) UpdateSSHByFile(c *gin.Context) {
var req dto.SettingUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := sshService.UpdateByFile(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func loadCertAfterDecrypt(req *dto.RootCertOperate) error {
if len(req.PassPhrase) != 0 {
passPhrase, err := base64.StdEncoding.DecodeString(req.PassPhrase)
if err != nil {
return err
}
req.PassPhrase = string(passPhrase)
}
if len(req.PrivateKey) != 0 {
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
if err != nil {
return err
}
req.PrivateKey = string(privateKey)
}
if len(req.PublicKey) != 0 {
publicKey, err := base64.StdEncoding.DecodeString(req.PublicKey)
if err != nil {
return err
}
req.PublicKey = string(publicKey)
}
return nil
}

@ -0,0 +1,26 @@
package v2
import (
"errors"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/gin-gonic/gin"
)
// @Tags Host
// @Summary Check if a system component exists
// @Accept json
// @Param name path string true "Component name to check (e.g., rsync, docker)"
// @Success 200 {object} response.ComponentInfo
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /hosts/components/{name} [get]
func (b *BaseApi) CheckComponentExistence(c *gin.Context) {
name := c.Param("name")
if name == "" {
helper.BadRequest(c, errors.New("empty component name"))
return
}
info := systemService.IsComponentExist(name)
helper.SuccessWithData(c, info)
}

@ -0,0 +1,46 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/gin-gonic/gin"
)
// @Tags TaskLog
// @Summary Page task logs
// @Accept json
// @Param request body dto.SearchTaskLogReq true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /logs/tasks/search [post]
func (b *BaseApi) PageTasks(c *gin.Context) {
var req dto.SearchTaskLogReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, list, err := taskService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
// @Tags TaskLog
// @Summary Get the number of executing tasks
// @Success 200 {object} int64
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /logs/tasks/executing/count [get]
func (b *BaseApi) CountExecutingTasks(c *gin.Context) {
count, err := taskService.CountExecutingTask()
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, count)
}

@ -0,0 +1,68 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
func (b *BaseApi) PageTensorRTLLMs(c *gin.Context) {
var req request.TensorRTLLMSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list := tensorrtLLMService.Page(req)
helper.SuccessWithData(c, list)
}
func (b *BaseApi) CreateTensorRTLLM(c *gin.Context) {
var req request.TensorRTLLMCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := tensorrtLLMService.Create(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) UpdateTensorRTLLM(c *gin.Context) {
var req request.TensorRTLLMUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := tensorrtLLMService.Update(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) DeleteTensorRTLLM(c *gin.Context) {
var req request.TensorRTLLMDelete
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := tensorrtLLMService.Delete(req.ID)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func (b *BaseApi) OperateTensorRTLLM(c *gin.Context) {
var req request.TensorRTLLMOperate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
err := tensorrtLLMService.Operate(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,236 @@
package v2
import (
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/terminal"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
)
func (b *BaseApi) WsSSH(c *gin.Context) {
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
global.LOG.Errorf("gin context http handler failed, err: %v", err)
return
}
defer wsConn.Close()
if global.CONF.Base.IsDemo {
if wshandleError(wsConn, errors.New(" demo server, prohibit this operation!")) {
return
}
}
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
return
}
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
return
}
client, err := loadLocalConn()
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
return
}
defer client.Close()
command := c.DefaultQuery("command", "")
sws, err := terminal.NewLogicSshWsSession(cols, rows, client.Client, wsConn, command)
if wshandleError(wsConn, err) {
return
}
defer sws.Close()
quitChan := make(chan bool, 3)
sws.Start(quitChan)
go sws.Wait(quitChan)
<-quitChan
dt := time.Now().Add(time.Second)
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
}
func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
global.LOG.Errorf("gin context http handler failed, err: %v", err)
return
}
defer wsConn.Close()
if global.CONF.Base.IsDemo {
if wshandleError(wsConn, errors.New(" demo server, prohibit this operation!")) {
return
}
}
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
return
}
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
return
}
source := c.Query("source")
var initCmd []string
switch source {
case "redis", "redis-cluster":
initCmd, err = loadRedisInitCmd(c, source)
case "ollama":
initCmd, err = loadOllamaInitCmd(c)
case "container":
initCmd, err = loadContainerInitCmd(c)
case "database":
initCmd, err = loadDatabaseInitCmd(c)
default:
if wshandleError(wsConn, fmt.Errorf("not support such source %s", source)) {
return
}
}
if wshandleError(wsConn, err) {
return
}
slave, err := terminal.NewCommand("docker", initCmd...)
if wshandleError(wsConn, err) {
return
}
defer slave.Close()
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave, false)
if wshandleError(wsConn, err) {
return
}
quitChan := make(chan bool, 3)
tty.Start(quitChan)
go slave.Wait(quitChan)
<-quitChan
global.LOG.Info("websocket finished")
dt := time.Now().Add(time.Second)
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
}
func loadRedisInitCmd(c *gin.Context, redisType string) ([]string, error) {
name := c.Query("name")
from := c.Query("from")
commands := []string{"exec", "-it"}
database, err := databaseService.Get(name)
if err != nil {
return nil, fmt.Errorf("no such database in db, err: %v", err)
}
if from == "local" {
redisInfo, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Name: name, Type: redisType})
if err != nil {
return nil, fmt.Errorf("no such app in db, err: %v", err)
}
name = redisInfo.ContainerName
commands = append(commands, []string{name, "redis-cli"}...)
if len(database.Password) != 0 {
commands = append(commands, []string{"-a", database.Password, "--no-auth-warning"}...)
}
} else {
name = "1Panel-redis-cli-tools"
commands = append(commands, []string{name, "redis-cli", "-h", database.Address, "-p", fmt.Sprintf("%v", database.Port)}...)
if len(database.Password) != 0 {
commands = append(commands, []string{"-a", database.Password, "--no-auth-warning"}...)
}
}
return commands, nil
}
func loadOllamaInitCmd(c *gin.Context) ([]string, error) {
name := c.Query("name")
if cmd.CheckIllegal(name) {
return nil, fmt.Errorf("ollama model %s contains illegal characters", name)
}
ollamaInfo, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Name: "", Type: "ollama"})
if err != nil {
return nil, fmt.Errorf("no such app in db, err: %v", err)
}
containerName := ollamaInfo.ContainerName
return []string{"exec", "-it", containerName, "ollama", "run", name}, nil
}
func loadContainerInitCmd(c *gin.Context) ([]string, error) {
containerID := c.Query("containerid")
command := c.Query("command")
user := c.Query("user")
if cmd.CheckIllegal(user, containerID, command) {
return nil, fmt.Errorf("the command contains illegal characters. command: %s, user: %s, containerID: %s", command, user, containerID)
}
if len(command) == 0 || len(containerID) == 0 {
return nil, fmt.Errorf("error param of command: %s or containerID: %s", command, containerID)
}
commands := []string{"exec", "-it", containerID, command}
if len(user) != 0 {
commands = []string{"exec", "-it", "-u", user, containerID, command}
}
return commands, nil
}
func loadDatabaseInitCmd(c *gin.Context) ([]string, error) {
database := c.Query("database")
databaseType := c.Query("databaseType")
if len(database) == 0 || len(databaseType) == 0 {
return nil, fmt.Errorf("error param of database: %s or database type: %s", database, databaseType)
}
databaseConn, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Type: databaseType, Name: database})
if err != nil {
return nil, fmt.Errorf("no such database in db, err: %v", err)
}
commands := []string{"exec", "-it", databaseConn.ContainerName}
switch databaseType {
case "mysql", "mysql-cluster":
commands = append(commands, []string{"mysql", "-uroot", "-p" + databaseConn.Password}...)
case "mariadb":
commands = append(commands, []string{"mariadb", "-uroot", "-p" + databaseConn.Password}...)
case "postgresql", "postgresql-cluster":
commands = []string{"exec", "-e", fmt.Sprintf("PGPASSWORD=%s", databaseConn.Password), "-it", databaseConn.ContainerName, "psql", "-t", "-U", databaseConn.Username}
}
return commands, nil
}
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 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
}
var upGrader = websocket.Upgrader{
ReadBufferSize: 4096,
WriteBufferSize: 16384,
CheckOrigin: func(r *http.Request) bool {
return true
},
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,97 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Website Acme
// @Summary Page website acme accounts
// @Accept json
// @Param request body dto.PageInfo true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/acme/search [post]
func (b *BaseApi) PageWebsiteAcmeAccount(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, accounts, err := websiteAcmeAccountService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: accounts,
})
}
// @Tags Website Acme
// @Summary Create website acme account
// @Accept json
// @Param request body request.WebsiteAcmeAccountCreate true "request"
// @Success 200 {object} response.WebsiteAcmeAccountDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/acme [post]
// @x-panel-log {"bodyKeys":["email"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 acme [email]","formatEN":"Create website acme [email]"}
func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
var req request.WebsiteAcmeAccountCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := websiteAcmeAccountService.Create(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website Acme
// @Summary Delete website acme account
// @Accept json
// @Param request body request.WebsiteResourceReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/acme/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteAcmeAccountService.Delete(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website Acme
// @Summary Update website acme account
// @Accept json
// @Param request body request.WebsiteAcmeAccountUpdate true "request"
// @Success 200 {object} response.WebsiteAcmeAccountDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/acme/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_acme_accounts","output_column":"email","output_value":"email"}],"formatZH":"更新 acme [email]","formatEN":"Update acme [email]"}
func (b *BaseApi) UpdateWebsiteAcmeAccount(c *gin.Context) {
var req request.WebsiteAcmeAccountUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := websiteAcmeAccountService.Update(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}

@ -0,0 +1,178 @@
package v2
import (
"net/http"
"net/url"
"strconv"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Website CA
// @Summary Page website ca
// @Accept json
// @Param request body request.WebsiteCASearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ca/search [post]
func (b *BaseApi) PageWebsiteCA(c *gin.Context) {
var req request.WebsiteCASearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, cas, err := websiteCAService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: cas,
})
}
// @Tags Website CA
// @Summary Create website ca
// @Accept json
// @Param request body request.WebsiteCACreate true "request"
// @Success 200 {object} request.WebsiteCACreate
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ca [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 ca [name]","formatEN":"Create website ca [name]"}
func (b *BaseApi) CreateWebsiteCA(c *gin.Context) {
var req request.WebsiteCACreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := websiteCAService.Create(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website CA
// @Summary Get website ca
// @Accept json
// @Param id path int true "id"
// @Success 200 {object} response.WebsiteCADTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ca/{id} [get]
func (b *BaseApi) GetWebsiteCA(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
return
}
res, err := websiteCAService.GetCA(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website CA
// @Summary Delete website ca
// @Accept json
// @Param request body request.WebsiteCommonReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ca/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_cas","output_column":"name","output_value":"name"}],"formatZH":"删除网站 ca [name]","formatEN":"Delete website ca [name]"}
func (b *BaseApi) DeleteWebsiteCA(c *gin.Context) {
var req request.WebsiteCommonReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteCAService.Delete(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website CA
// @Summary Obtain SSL
// @Accept json
// @Param request body request.WebsiteCAObtain true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ca/obtain [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_cas","output_column":"name","output_value":"name"}],"formatZH":"自签 SSL 证书 [name]","formatEN":"Obtain SSL [name]"}
func (b *BaseApi) ObtainWebsiteCA(c *gin.Context) {
var req request.WebsiteCAObtain
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := websiteCAService.ObtainSSL(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website CA
// @Summary Obtain SSL
// @Accept json
// @Param request body request.WebsiteCAObtain true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ca/renew [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_cas","output_column":"name","output_value":"name"}],"formatZH":"自签 SSL 证书 [name]","formatEN":"Obtain SSL [name]"}
func (b *BaseApi) RenewWebsiteCA(c *gin.Context) {
var req request.WebsiteCARenew
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if _, err := websiteCAService.ObtainSSL(request.WebsiteCAObtain{
SSLID: req.SSLID,
Renew: true,
Unit: "year",
Time: 1,
}); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website CA
// @Summary Download CA file
// @Accept json
// @Param request body request.WebsiteResourceReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ca/download [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_cas","output_column":"name","output_value":"name"}],"formatZH":"下载 CA 证书文件 [name]","formatEN":"download ca file [name]"}
func (b *BaseApi) DownloadCAFile(c *gin.Context) {
var req request.WebsiteResourceReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
file, err := websiteCAService.DownloadFile(req.ID)
if err != nil {
helper.InternalServer(c, err)
return
}
defer file.Close()
info, err := file.Stat()
if err != nil {
helper.InternalServer(c, err)
return
}
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)
}

@ -0,0 +1,95 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Website DNS
// @Summary Page website dns accounts
// @Accept json
// @Param request body dto.PageInfo true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/dns/search [post]
func (b *BaseApi) PageWebsiteDnsAccount(c *gin.Context) {
var req dto.PageInfo
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
total, accounts, err := websiteDnsAccountService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Total: total,
Items: accounts,
})
}
// @Tags Website DNS
// @Summary Create website dns account
// @Accept json
// @Param request body request.WebsiteDnsAccountCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/dns [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 dns [name]","formatEN":"Create website dns [name]"}
func (b *BaseApi) CreateWebsiteDnsAccount(c *gin.Context) {
var req request.WebsiteDnsAccountCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if _, err := websiteDnsAccountService.Create(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website DNS
// @Summary Update website dns account
// @Accept json
// @Param request body request.WebsiteDnsAccountUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/dns/update [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新网站 dns [name]","formatEN":"Update website dns [name]"}
func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
var req request.WebsiteDnsAccountUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if _, err := websiteDnsAccountService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website DNS
// @Summary Delete website dns account
// @Accept json
// @Param request body request.WebsiteResourceReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/dns/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteDnsAccountService.Delete(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,93 @@
package v2
import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Website Domain
// @Summary Delete website domain
// @Accept json
// @Param request body request.WebsiteDomainDelete true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/domains/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteService.DeleteWebsiteDomain(req.ID); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website Domain
// @Summary Create website domain
// @Accept json
// @Param request body request.WebsiteDomainCreate true "request"
// @Success 200 {object} model.WebsiteDomain
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/domains [post]
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建域名 [domain]","formatEN":"Create domain [domain]"}
func (b *BaseApi) CreateWebDomain(c *gin.Context) {
var req request.WebsiteDomainCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
domain, err := websiteService.CreateWebsiteDomain(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, domain)
}
// @Tags Website Domain
// @Summary Search website domains by websiteId
// @Accept json
// @Param websiteId path integer true "request"
// @Success 200 {array} model.WebsiteDomain
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/domains/:websiteId [get]
func (b *BaseApi) GetWebDomains(c *gin.Context) {
websiteId, err := helper.GetIntParamByKey(c, "websiteId")
if err != nil {
helper.BadRequest(c, err)
return
}
list, err := websiteService.GetWebsiteDomain(websiteId)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, list)
}
// @Tags Website Domain
// @Summary Update website domain
// @Accept json
// @Param request body request.WebsiteDomainUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/domains/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"更新域名 [domain]","formatEN":"Update domain [domain]"}
func (b *BaseApi) UpdateWebDomain(c *gin.Context) {
var req request.WebsiteDomainUpdate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteService.UpdateWebsiteDomain(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,335 @@
package v2
import (
"io"
"mime/multipart"
"net/http"
"net/url"
"reflect"
"strconv"
"github.com/1Panel-dev/1Panel/agent/app/model"
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/gin-gonic/gin"
)
// @Tags Website SSL
// @Summary Page website ssl
// @Accept json
// @Param request body request.WebsiteSSLSearch true "request"
// @Success 200 {array} response.WebsiteSSLDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/search [post]
func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLSearch
if err := helper.CheckBind(&req, c); err != nil {
return
}
if !reflect.DeepEqual(req.PageInfo, dto.PageInfo{}) {
total, accounts, err := websiteSSLService.Page(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithDataGzipped(c, dto.PageResult{
Total: total,
Items: accounts,
})
} else {
list, err := websiteSSLService.Search(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithDataGzipped(c, list)
}
}
// @Tags Website SSL
// @Summary Create website ssl
// @Accept json
// @Param request body request.WebsiteSSLCreate true "request"
// @Success 200 {object} request.WebsiteSSLCreate
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl [post]
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站 ssl [primaryDomain]","formatEN":"Create website ssl [primaryDomain]"}
func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLCreate
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := websiteSSLService.Create(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website SSL
// @Summary Apply ssl
// @Accept json
// @Param request body request.WebsiteSSLApply true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/obtain [post]
// @x-panel-log {"bodyKeys":["ID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ID","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"申请证书 [domain]","formatEN":"apply ssl [domain]"}
func (b *BaseApi) ApplyWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLApply
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteSSLService.ObtainSSL(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website SSL
// @Summary Resolve website ssl
// @Accept json
// @Param request body request.WebsiteDNSReq true "request"
// @Success 200 {array} response.WebsiteDNSRes
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/resolve [post]
func (b *BaseApi) GetDNSResolve(c *gin.Context) {
var req request.WebsiteDNSReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
res, err := websiteSSLService.GetDNSResolve(req)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, res)
}
// @Tags Website SSL
// @Summary Delete website ssl
// @Accept json
// @Param request body request.WebsiteBatchDelReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"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.WebsiteBatchDelReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteSSLService.Delete(req.IDs); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website SSL
// @Summary Search website ssl by website id
// @Accept json
// @Param websiteId path integer true "request"
// @Success 200 {object} response.WebsiteSSLDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/website/:websiteId [get]
func (b *BaseApi) GetWebsiteSSLByWebsiteId(c *gin.Context) {
websiteId, err := helper.GetIntParamByKey(c, "websiteId")
if err != nil {
helper.BadRequest(c, err)
return
}
websiteSSL, err := websiteSSLService.GetWebsiteSSL(websiteId)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, websiteSSL)
}
// @Tags Website SSL
// @Summary Search website ssl by id
// @Accept json
// @Param id path integer true "request"
// @Success 200 {object} response.WebsiteSSLDTO
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/:id [get]
func (b *BaseApi) GetWebsiteSSLById(c *gin.Context) {
id, err := helper.GetParamID(c)
if err != nil {
helper.BadRequest(c, err)
return
}
websiteSSL, err := websiteSSLService.GetSSL(id)
if err != nil {
helper.InternalServer(c, err)
return
}
helper.SuccessWithData(c, websiteSSL)
}
// @Tags Website SSL
// @Summary Update ssl
// @Accept json
// @Param request body request.WebsiteSSLUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/update [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"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 := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteSSLService.Update(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website SSL
// @Summary Upload ssl
// @Accept json
// @Param request body request.WebsiteSSLUpload true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/upload [post]
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传 ssl [type]","formatEN":"Upload ssl [type]"}
func (b *BaseApi) UploadWebsiteSSL(c *gin.Context) {
var req request.WebsiteSSLUpload
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteSSLService.Upload(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
// @Tags Website SSL
// @Summary Upload SSL file
// @Accept multipart/form-data
// @Param type formData string true "type"
// @Param description formData string false "description"
// @Param sslID formData string false "sslID"
// @Param privateKeyFile formData file true "privateKeyFile"
// @Param certificateFile formData file true "certificateFile"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/upload/file [post]
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传 ssl 文件 [type]","formatEN":"Upload ssl file [type]"}
func (b *BaseApi) UploadSSLFile(c *gin.Context) {
var req request.WebsiteSSLFileUpload
req.Description = c.PostForm("description")
sslID := c.PostForm("sslID")
if sslID != "" {
req.SSLID, _ = strconv.ParseUint(sslID, 10, 64)
}
privateKeyFile, err := c.FormFile("privateKeyFile")
if err != nil {
helper.InternalServer(c, err)
return
}
certificateFile, err := c.FormFile("certificateFile")
if err != nil {
helper.InternalServer(c, err)
return
}
privateKeyContent, err := readUploadedFile(privateKeyFile)
if err != nil {
helper.InternalServer(c, err)
return
}
certificateContent, err := readUploadedFile(certificateFile)
if err != nil {
helper.InternalServer(c, err)
return
}
uploadReq := request.WebsiteSSLUpload{
Type: "paste",
PrivateKey: string(privateKeyContent),
Certificate: string(certificateContent),
Description: req.Description,
SSLID: uint(req.SSLID),
}
if err := websiteSSLService.Upload(uploadReq); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
func readUploadedFile(fileHeader *multipart.FileHeader) ([]byte, error) {
file, err := fileHeader.Open()
if err != nil {
return nil, err
}
defer file.Close()
return io.ReadAll(file)
}
// @Tags Website SSL
// @Summary Download SSL file
// @Accept json
// @Param request body request.WebsiteResourceReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /websites/ssl/download [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"下载证书文件 [domain]","formatEN":"download ssl file [domain]"}
func (b *BaseApi) DownloadWebsiteSSL(c *gin.Context) {
var req request.WebsiteResourceReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
file, err := websiteSSLService.DownloadFile(req.ID)
if err != nil {
helper.InternalServer(c, err)
return
}
defer file.Close()
info, err := file.Stat()
if err != nil {
helper.InternalServer(c, err)
return
}
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)
}
func (b *BaseApi) ImportMasterSSL(c *gin.Context) {
var req model.WebsiteSSL
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteSSLService.ImportMasterSSL(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}

@ -0,0 +1,46 @@
package dto
import "time"
type OllamaModelInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
Size string `json:"size"`
From string `json:"from"`
LogFileExist bool `json:"logFileExist"`
Status string `json:"status"`
Message string `json:"message"`
CreatedAt time.Time `json:"createdAt"`
}
type OllamaModelDropList struct {
ID uint `json:"id"`
Name string `json:"name"`
}
type OllamaModelName struct {
Name string `json:"name"`
TaskID string `json:"taskID"`
}
type OllamaBindDomain struct {
Domain string `json:"domain" validate:"required"`
AppInstallID uint `json:"appInstallID" validate:"required"`
SSLID uint `json:"sslID"`
WebsiteID uint `json:"websiteID"`
IPList string `json:"ipList"`
}
type OllamaBindDomainReq struct {
AppInstallID uint `json:"appInstallID" validate:"required"`
}
type OllamaBindDomainRes struct {
Domain string `json:"domain"`
SSLID uint `json:"sslID"`
AllowIPs []string `json:"allowIPs"`
WebsiteID uint `json:"websiteID"`
ConnUrl string `json:"connUrl"`
AcmeAccountID uint `json:"acmeAccountID"`
}

@ -0,0 +1,337 @@
package dto
import (
"encoding/json"
"github.com/1Panel-dev/1Panel/agent/app/model"
"time"
)
type CreateOrUpdateAlert struct {
AlertTitle string `json:"alertTitle"`
AlertType string `json:"alertType"`
AlertMethod string `json:"alertMethod"`
AlertCount uint `json:"alertCount"`
EntryID uint `json:"entryID"`
}
type AlertBase struct {
AlertType string `json:"alertType"`
EntryID uint `json:"entryID"`
}
type PushAlert struct {
TaskName string `json:"taskName"`
AlertType string `json:"alertType"`
EntryID uint `json:"entryID"`
Param string `json:"param"`
}
type AlertSearch struct {
PageInfo
OrderBy string `json:"orderBy" validate:"required,oneof=created_at"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
Type string `json:"type"`
Status string `json:"status"`
Method string `json:"method"`
}
type AlertDTO struct {
ID uint `json:"id"`
Type string `json:"type"`
Cycle uint `json:"cycle"`
Count uint `json:"count"`
Method string `json:"method"`
Title string `json:"title"`
Project string `json:"project"`
Status string `json:"status"`
SendCount uint `json:"sendCount"`
AdvancedParams string `json:"advancedParams"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type AlertCreate struct {
Type string `json:"type" validate:"required"`
Cycle uint `json:"cycle"`
Count uint `json:"count"`
Method string `json:"method" validate:"required"`
Title string `json:"title"`
Project string `json:"project"`
Status string `json:"status"`
SendCount uint `json:"sendCount"`
AdvancedParams string `json:"advancedParams"`
}
type AlertUpdate struct {
ID uint `json:"id" validate:"required"`
Type string `json:"type"`
Cycle uint `json:"cycle"`
Count uint `json:"count"`
Method string `json:"method"`
Title string `json:"title"`
Project string `json:"project"`
Status string `json:"status"`
SendCount uint `json:"sendCount"`
AdvancedParams string `json:"advancedParams"`
}
type DeleteRequest struct {
ID uint `json:"id" validate:"required"`
}
type AlertUpdateStatus struct {
ID uint `json:"id" validate:"required"`
Status string `json:"status" validate:"required"`
}
type DiskDTO 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"`
UsedPercent float64 `json:"usedPercent"`
InodesTotal uint64 `json:"inodesTotal"`
InodesUsed uint64 `json:"inodesUsed"`
InodesFree uint64 `json:"inodesFree"`
InodesUsedPercent float64 `json:"inodesUsedPercent"`
}
type AlertLogSearch struct {
PageInfo
Count uint `json:"count"`
Status string `json:"status"`
}
type AlertLogDTO struct {
ID uint `json:"id"`
Type string `json:"type"`
Count uint `json:"count"`
AlertId uint `json:"alertId"`
AlertDetail AlertDetail `json:"alertDetail"`
AlertRule AlertRule `json:"alertRule"`
Status string `json:"status"`
Method string `json:"method"`
Message string `json:"message"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type AlertLogCreate struct {
Type string `json:"type" validate:"required"`
Count uint `json:"count" validate:"required"`
AlertId uint `json:"alertId" validate:"required"`
AlertDetail string `json:"alertDetail" validate:"required"`
AlertRule string `json:"alertRule" validate:"required"`
Status string `json:"status" validate:"required"`
Method string `json:"method" validate:"required"`
Message string `json:"message"`
RecordId uint `json:"recordId"`
LicenseId string `json:"licenseId" validate:"required"`
}
type AlertLog struct {
ID uint `json:"id" validate:"required"`
}
type AlertDetail struct {
LicenseId string `json:"licenseId"`
Type string `json:"type"`
SubType string `json:"subType"`
Title string `json:"title"`
Method string `json:"method"`
LicenseCode string `json:"licenseCode"`
DeviceId string `json:"deviceId"`
Project string `json:"project"`
Params []Param `json:"params"`
Phone string `json:"phone"`
}
type AlertRule struct {
ID uint `json:"id"`
Type string `json:"type"`
Cycle uint `json:"cycle"`
Count uint `json:"count"`
Method string `json:"method"`
Title string `json:"title"`
Project string `json:"project"`
Status string `json:"status"`
SendCount uint `json:"sendCount"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type Param struct {
Index string `json:"index"`
Key string `json:"key"`
Value string `json:"value"`
}
type ClamDTO struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Name string `json:"name"`
Status string `json:"status"`
Path string `json:"path"`
}
type CronJobDTO struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Name string `json:"name"`
Status string `json:"status"`
Type string `json:"type"`
}
type CronJobReq struct {
Name string `json:"name"`
Status string `json:"status"`
Type string `json:"type"`
}
type UpgradeInfo struct {
TestVersion string `json:"testVersion"`
NewVersion string `json:"newVersion"`
LatestVersion string `json:"latestVersion"`
ReleaseNote string `json:"releaseNote"`
}
type AlertDiskInfo struct {
Type string
Mount string
Device string
}
type SyncResult struct {
ID uint `json:"id"`
LicenseID string `json:"licenseId"`
SendStatus string `json:"sendStatus"`
CreateTime string `json:"createTime"`
UpdateTime string `json:"updateTime"`
Remarks string `json:"remarks"`
MsgCount int `json:"msgCount"`
MsgCountMax int `json:"msgCountMax"`
}
type QueryRequest struct {
QueryIds []uint `json:"queryIds"`
LicenseId string `json:"licenseId"`
}
type AlertResponse struct {
Result bool `json:"result"`
Data json.RawMessage `json:"data"`
Message string `json:"message"`
}
type PushResult struct {
RecordId uint `json:"recordId"`
LicenseId string `json:"licenseId"`
}
type UpdateOfflineAlertLog struct {
ID uint `json:"id"`
Status string `json:"status"`
Message string `json:"message"`
RecordId uint `json:"recordId"`
LicenseId string `json:"licenseId"`
}
type SyncOfflineAlertLogDTO struct {
QueryRequest string `json:"queryRequest"`
Ids []uint `json:"ids"`
AlertLogs []model.AlertLog `json:"alertLogs"`
LicenseId string `json:"licenseId"`
}
type OfflineAlertResponse struct {
ID uint `json:"id"`
Type string `json:"type"`
RemoteErr error `json:"remoteErr"`
ResponseStruct AlertResponse `json:"responseStruct"`
AlertLogs []model.AlertLog `json:"alertLogs"`
Ids []uint `json:"ids"`
LicenseId string `json:"licenseId"`
}
type OfflineAlertLogDTO struct {
ID uint `json:"id"`
Type string `json:"type"`
Count uint `json:"count"`
AlertId uint `json:"alertId"`
AlertDetail string `json:"alertDetail"`
AlertRule string `json:"alertRule"`
Status string `json:"status"`
Method string `json:"method"`
Message string `json:"message"`
RecordId uint `json:"recordId"`
LicenseId string `json:"licenseId"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type OfflineQueryRequest struct {
Ids []uint `json:"ids"`
QueryIds []uint `json:"queryIds"`
LicenseId string `json:"licenseId"`
}
type AlertConfigUpdate struct {
ID uint `json:"id"`
Type string `json:"type"`
Title string `json:"title"`
Status string `json:"status"`
Config string `json:"config"`
}
type AlertConfigTest struct {
Host string `json:"host"`
Port int `json:"port"`
Sender string `json:"sender"`
UserName string `json:"userName"`
Password string `json:"password"`
DisplayName string `json:"displayName"`
Encryption string `json:"encryption"` // "ssl" / "tls" / "none"
Recipient string `json:"recipient"`
}
type AlertSendTimeRange struct {
NoticeAlert struct {
SendTimeRange string `json:"sendTimeRange"`
Type []string `json:"type"`
} `json:"noticeAlert"`
ResourceAlert struct {
SendTimeRange string `json:"sendTimeRange"`
Type []string `json:"type"`
} `json:"resourceAlert"`
}
type AlertCommonConfig struct {
IsOffline string `json:"isOffline"`
AlertSendTimeRange AlertSendTimeRange `json:"alertSendTimeRange"`
}
type AlertSmsConfig struct {
Phone string `json:"phone"`
AlertDailyNum string `json:"alertDailyNum"`
}
type AlertEmailConfig struct {
Host string `json:"host"`
Port int `json:"port"`
Sender string `json:"sender"`
UserName string `json:"userName"`
Password string `json:"password"`
DisplayName string `json:"displayName"`
Encryption string `json:"encryption"` // "ssl" / "tls" / "none"
Recipient string `json:"recipient"`
}
type AgentInfo struct {
NodeName string `json:"nodeName"`
NodeAddr string `json:"nodeAddr"`
}

@ -0,0 +1,191 @@
package dto
import (
"context"
"github.com/1Panel-dev/1Panel/agent/app/model"
"github.com/1Panel-dev/1Panel/agent/app/task"
)
type AppDatabase struct {
ServiceName string `json:"PANEL_DB_HOST"`
DbName string `json:"PANEL_DB_NAME"`
DbUser string `json:"PANEL_DB_USER"`
Password string `json:"PANEL_DB_USER_PASSWORD"`
DatabaseName string `json:"DATABASE_NAME"`
Format string `json:"format"`
Collation string `json:"collation"`
}
type AuthParam struct {
RootPassword string `json:"PANEL_DB_ROOT_PASSWORD"`
RootUser string `json:"PANEL_DB_ROOT_USER"`
}
type RedisAuthParam struct {
RootPassword string `json:"PANEL_REDIS_ROOT_PASSWORD"`
}
type MinioAuthParam struct {
RootPassword string `json:"PANEL_MINIO_ROOT_PASSWORD"`
RootUser string `json:"PANEL_MINIO_ROOT_USER"`
}
type ContainerExec struct {
ContainerName string `json:"containerName"`
DbParam AppDatabase `json:"dbParam"`
Auth AuthParam `json:"auth"`
}
type AppOssConfig struct {
Version string `json:"version"`
Package string `json:"package"`
}
type AppVersion struct {
Version string `json:"version"`
DetailId uint `json:"detailId"`
DockerCompose string `json:"dockerCompose"`
}
type AppList struct {
Valid bool `json:"valid"`
Violations []string `json:"violations"`
LastModified int `json:"lastModified"`
Apps []AppDefine `json:"apps"`
Extra ExtraProperties `json:"additionalProperties"`
}
type AppDefine struct {
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 AppProperty `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"`
Version string `json:"version"`
}
type AppProperty struct {
Name string `json:"name"`
Type string `json:"type"`
Tags []string `json:"tags"`
ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh"`
ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn"`
Description Locale `json:"description"`
Key string `json:"key"`
Required []string `json:"Required"`
CrossVersionUpdate bool `json:"crossVersionUpdate" yaml:"crossVersionUpdate"`
Limit int `json:"limit" yaml:"limit"`
Recommend int `json:"recommend" yaml:"recommend"`
Website string `json:"website"`
Github string `json:"github"`
Document string `json:"document"`
Architectures []string `json:"architectures"`
MemoryRequired int `json:"memoryRequired" yaml:"memoryRequired"`
GpuSupport bool `json:"gpuSupport" yaml:"gpuSupport"`
Version float64 `json:"version"`
Deprecated float64 `json:"deprecated"`
BatchInstallSupport bool `json:"batchInstallSupport"`
}
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 {
Key string `json:"key"`
Name string `json:"name"`
Sort int `json:"sort"`
Locales Locale `json:"locales"`
}
type Locale struct {
En string `json:"en"`
Ja string `json:"ja"`
Ms string `json:"ms"`
PtBr string `json:"pt-br" yaml:"pt-br"`
Ru string `json:"ru"`
ZhHant string `json:"zh-hant" yaml:"zh-hant"`
Zh string `json:"zh"`
Ko string `json:"ko"`
Tr string `json:"tr"`
Es string `json:"es-es" yaml:"es-es"`
}
type AppForm struct {
FormFields []AppFormFields `json:"formFields"`
SupportVersion float64 `json:"supportVersion"`
}
type AppFormFields struct {
Type string `json:"type"`
LabelZh string `json:"labelZh"`
LabelEn string `json:"labelEn"`
Label Locale `json:"label"`
Description Locale `json:"description"`
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 {
Type string `json:"type"`
Name string `json:"name"`
}
var AppToolMap = map[string]string{
"mysql": "phpmyadmin",
"redis": "redis-commander",
}
type AppInstallInfo struct {
ID uint `json:"id"`
Key string `json:"key"`
Name string `json:"name"`
}
type DelAppLink struct {
Ctx context.Context
Task *task.Task
Install *model.AppInstall
ForceDelete bool
}
type PHPForm struct {
AdditionalProperties struct {
FormFields []interface{} `yaml:"formFields"`
} `yaml:"additionalProperties"`
}

@ -0,0 +1,136 @@
package dto
import (
"time"
)
type BackupOperate struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type" validate:"required"`
IsPublic bool `json:"isPublic"`
Bucket string `json:"bucket"`
AccessKey string `json:"accessKey"`
Credential string `json:"credential"`
BackupPath string `json:"backupPath"`
Vars string `json:"vars" validate:"required"`
RememberAuth bool `json:"rememberAuth"`
}
type BackupInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
IsPublic bool `json:"isPublic"`
Bucket string `json:"bucket"`
AccessKey string `json:"accessKey"`
Credential string `json:"credential"`
BackupPath string `json:"backupPath"`
Vars string `json:"vars"`
CreatedAt time.Time `json:"createdAt"`
RememberAuth bool `json:"rememberAuth"`
}
type BackupCheckRes struct {
IsOk bool `json:"isOk"`
Msg string `json:"msg"`
Token string `json:"token"`
}
type ForBuckets struct {
Type string `json:"type" validate:"required"`
AccessKey string `json:"accessKey"`
Credential string `json:"credential" validate:"required"`
Vars string `json:"vars" validate:"required"`
}
type SyncFromMaster struct {
Name string `json:"name" validate:"required"`
Operation string `json:"operation" validate:"required,oneof=create delete update"`
Data string `json:"data"`
}
type BackupOption struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
IsPublic bool `json:"isPublic"`
}
type UploadForRecover struct {
FilePath string `json:"filePath"`
TargetDir string `json:"targetDir"`
}
type CommonBackup struct {
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster"`
Name string `json:"name"`
DetailName string `json:"detailName"`
Secret string `json:"secret"`
TaskID string `json:"taskID"`
FileName string `json:"fileName"`
Args []string `json:"args"`
Description string `json:"description"`
}
type CommonRecover struct {
DownloadAccountID uint `json:"downloadAccountID" validate:"required"`
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster"`
Name string `json:"name"`
DetailName string `json:"detailName"`
File string `json:"file"`
Secret string `json:"secret"`
TaskID string `json:"taskID"`
BackupRecordID uint `json:"backupRecordID"`
Timeout int `json:"timeout"`
}
type RecordSearch struct {
PageInfo
Type string `json:"type" validate:"required"`
Name string `json:"name"`
DetailName string `json:"detailName"`
}
type RecordSearchByCronjob struct {
PageInfo
CronjobID uint `json:"cronjobID" validate:"required"`
}
type BackupRecords struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
AccountType string `json:"accountType"`
AccountName string `json:"accountName"`
DownloadAccountID uint `json:"downloadAccountID"`
FileDir string `json:"fileDir"`
FileName string `json:"fileName"`
TaskID string `json:"taskID"`
Status string `json:"status"`
Message string `json:"message"`
Description string `json:"description"`
}
type DownloadRecord struct {
DownloadAccountID uint `json:"downloadAccountID" validate:"required"`
FileDir string `json:"fileDir" validate:"required"`
FileName string `json:"fileName" validate:"required"`
}
type SearchForSize struct {
PageInfo
Type string `json:"type" validate:"required"`
Name string `json:"name"`
DetailName string `json:"detailName"`
Info string `json:"info"`
CronjobID uint `json:"cronjobID"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
}
type RecordFileSize struct {
ID uint `json:"id"`
Name string `json:"name"`
Size int64 `json:"size"`
}

@ -0,0 +1,111 @@
package dto
import (
"time"
)
type SearchClamWithPage struct {
PageInfo
Info string `json:"info"`
OrderBy string `json:"orderBy" validate:"required,oneof=name status createdAt"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
}
type ClamBaseInfo struct {
Version string `json:"version"`
IsActive bool `json:"isActive"`
IsExist bool `json:"isExist"`
FreshVersion string `json:"freshVersion"`
FreshIsActive bool `json:"freshIsActive"`
FreshIsExist bool `json:"freshIsExist"`
}
type ClamInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
Status string `json:"status"`
Path string `json:"path"`
InfectedStrategy string `json:"infectedStrategy"`
InfectedDir string `json:"infectedDir"`
LastRecordStatus string `json:"lastRecordStatus"`
LastRecordTime string `json:"lastRecordTime"`
Spec string `json:"spec"`
Timeout uint `json:"timeout"`
Description string `json:"description"`
AlertCount uint `json:"alertCount"`
AlertMethod string `json:"alertMethod"`
}
type ClamLogSearch struct {
PageInfo
ClamID uint `json:"clamID"`
Status string `json:"status"`
StartTime time.Time `json:"startTime"`
EndTime time.Time `json:"endTime"`
}
type ClamLogReq struct {
Tail string `json:"tail"`
ClamName string `json:"clamName"`
RecordName string `json:"recordName"`
}
type ClamFileReq struct {
Tail string `json:"tail"`
Name string `json:"name" validate:"required"`
}
type ClamRecord struct {
ID uint `json:"id"`
TaskID string `json:"taskID"`
StartTime time.Time `json:"startTime"`
ScanTime string `json:"scanTime"`
InfectedFiles string `json:"infectedFiles"`
TotalError string `json:"totalError"`
Status string `json:"status"`
Message string `json:"message"`
}
type ClamCreate struct {
Name string `json:"name"`
Status string `json:"status"`
Path string `json:"path"`
InfectedStrategy string `json:"infectedStrategy"`
InfectedDir string `json:"infectedDir"`
Spec string `json:"spec"`
Timeout uint `json:"timeout"`
Description string `json:"description"`
AlertCount uint `json:"alertCount"`
AlertTitle string `json:"alertTitle"`
AlertMethod string `json:"alertMethod"`
}
type ClamUpdate struct {
ID uint `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
InfectedStrategy string `json:"infectedStrategy"`
InfectedDir string `json:"infectedDir"`
Spec string `json:"spec"`
Timeout uint `json:"timeout"`
Description string `json:"description"`
AlertCount uint `json:"alertCount"`
AlertTitle string `json:"alertTitle"`
AlertMethod string `json:"alertMethod"`
}
type ClamUpdateStatus struct {
ID uint `json:"id"`
Status string `json:"status"`
}
type ClamDelete struct {
RemoveInfected bool `json:"removeInfected"`
Ids []uint `json:"ids" validate:"required"`
}

@ -0,0 +1,38 @@
package dto
type SearchCommandWithPage struct {
PageInfo
OrderBy string `json:"orderBy" validate:"required,oneof=name command createdAt"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
GroupID uint `json:"groupID"`
Info string `json:"info"`
Name string `json:"name"`
}
type CommandOperate struct {
ID uint `json:"id"`
GroupID uint `json:"groupID"`
GroupBelong string `json:"groupBelong"`
Name string `json:"name" validate:"required"`
Command string `json:"command" validate:"required"`
}
type CommandInfo struct {
ID uint `json:"id"`
GroupID uint `json:"groupID"`
Name string `json:"name"`
Command string `json:"command"`
GroupBelong string `json:"groupBelong"`
}
type CommandTree struct {
ID uint `json:"id"`
Label string `json:"label"`
Children []CommandInfo `json:"children"`
}
type RedisCommand struct {
ID uint `json:"id"`
Name string `json:"name"`
Command string `json:"command"`
}

@ -0,0 +1,86 @@
package dto
type SearchWithPage struct {
PageInfo
Info string `json:"info"`
}
type SearchPageWithType struct {
PageInfo
Info string `json:"info"`
Type string `json:"type"`
}
type PageInfo struct {
Page int `json:"page" validate:"required,number"`
PageSize int `json:"pageSize" validate:"required,number"`
}
type UpdateDescription struct {
ID uint `json:"id" validate:"required"`
Description string `json:"description" validate:"max=256"`
}
type OperationWithName struct {
Name string `json:"name" validate:"required"`
}
type OperateByID struct {
ID uint `json:"id" validate:"required"`
}
type OperateByIDs struct {
IDs []uint `json:"ids"`
}
type Operate struct {
Operation string `json:"operation" validate:"required"`
}
type SearchByFilter struct {
Filter string `json:"filter"`
}
type BatchDeleteReq struct {
Ids []uint `json:"ids" validate:"required"`
}
type FilePath struct {
Path string `json:"path" validate:"required"`
}
type DeleteByName struct {
Name string `json:"name" validate:"required"`
}
type UpdateByFile struct {
File string `json:"file"`
}
type UpdateByNameAndFile struct {
Name string `json:"name"`
File string `json:"file"`
}
type OperationWithNameAndType struct {
Name string `json:"name"`
Type string `json:"type" validate:"required"`
}
type UpdateGroup struct {
Group uint `json:"group"`
NewGroup uint `json:"newGroup"`
}
type OperateWithTask struct {
TaskID string `json:"taskID"`
}
type ForceDelete struct {
IDs []uint `json:"ids"`
ForceDelete bool `json:"forceDelete"`
}
type ChangeGroup struct {
ID uint `json:"id" validate:"required"`
GroupID uint `json:"groupID" validate:"required"`
}

@ -0,0 +1,16 @@
package dto
type PageResult struct {
Total int64 `json:"total"`
Items interface{} `json:"items"`
}
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
type Options struct {
Option string `json:"option"`
}

@ -0,0 +1,27 @@
package dto
import "time"
type ComposeTemplateCreate struct {
Name string `json:"name" validate:"required"`
Description string `json:"description"`
Content string `json:"content"`
}
type ComposeTemplateBatch struct {
Templates []ComposeTemplateCreate `json:"templates" validate:"required"`
}
type ComposeTemplateUpdate struct {
ID uint `json:"id"`
Description string `json:"description"`
Content string `json:"content"`
}
type ComposeTemplateInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
Description string `json:"description"`
Content string `json:"content"`
}

@ -0,0 +1,318 @@
package dto
import (
"time"
)
type PageContainer struct {
PageInfo
Name string `json:"name"`
State string `json:"state" validate:"required,oneof=all created running paused restarting removing exited dead"`
OrderBy string `json:"orderBy" validate:"required,oneof=name createdAt state"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
Filters string `json:"filters"`
ExcludeAppStore bool `json:"excludeAppStore"`
}
type InspectReq struct {
ID string `json:"id" validate:"required"`
Type string `json:"type" validate:"required"`
Detail string `json:"detail"`
}
type ContainerInfo struct {
ContainerID string `json:"containerID"`
Name string `json:"name"`
ImageId string `json:"imageID"`
ImageName string `json:"imageName"`
CreateTime string `json:"createTime"`
State string `json:"state"`
RunTime string `json:"runTime"`
Network []string `json:"network"`
Ports []string `json:"ports"`
IsFromApp bool `json:"isFromApp"`
IsFromCompose bool `json:"isFromCompose"`
AppName string `json:"appName"`
AppInstallName string `json:"appInstallName"`
Websites []string `json:"websites"`
IsPinned bool `json:"isPinned"`
Description string `json:"description"`
}
type ContainerOptions struct {
Name string `json:"name"`
State string `json:"state"`
}
type ContainerStatus struct {
Created int `json:"created"`
Running int `json:"running"`
Paused int `json:"paused"`
Restarting int `json:"restarting"`
Removing int `json:"removing"`
Exited int `json:"exited"`
Dead int `json:"dead"`
ContainerCount int `json:"containerCount"`
ComposeCount int `json:"composeCount"`
ComposeTemplateCount int `json:"composeTemplateCount"`
ImageCount int `json:"imageCount"`
NetworkCount int `json:"networkCount"`
VolumeCount int `json:"volumeCount"`
RepoCount int `json:"repoCount"`
}
type ResourceLimit struct {
CPU int `json:"cpu"`
Memory uint64 `json:"memory"`
}
type ContainerOperate struct {
TaskID string `json:"taskID"`
ForcePull bool `json:"forcePull"`
Name string `json:"name" validate:"required"`
Image string `json:"image" validate:"required"`
Hostname string `json:"hostname"`
DomainName string `json:"domainName"`
DNS []string `json:"dns"`
Networks []ContainerNetwork `json:"networks"`
PublishAllPorts bool `json:"publishAllPorts"`
ExposedPorts []PortHelper `json:"exposedPorts"`
Tty bool `json:"tty"`
OpenStdin bool `json:"openStdin"`
WorkingDir string `json:"workingDir"`
User string `json:"user"`
Cmd []string `json:"cmd"`
Entrypoint []string `json:"entrypoint"`
CPUShares int64 `json:"cpuShares"`
NanoCPUs float64 `json:"nanoCPUs"`
Memory float64 `json:"memory"`
Privileged bool `json:"privileged"`
AutoRemove bool `json:"autoRemove"`
Volumes []VolumeHelper `json:"volumes"`
Labels []string `json:"labels"`
Env []string `json:"env"`
RestartPolicy string `json:"restartPolicy"`
}
type ContainerNetwork struct {
Network string `json:"network"`
Ipv4 string `json:"ipv4"`
Ipv6 string `json:"ipv6"`
MacAddr string `json:"macAddr"`
}
type ContainerCreateByCommand struct {
TaskID string `json:"taskID"`
Command string `json:"command"`
}
type ContainerUpgrade struct {
TaskID string `json:"taskID"`
Names []string `json:"names" validate:"required"`
Image string `json:"image" validate:"required"`
ForcePull bool `json:"forcePull"`
}
type ContainerItemStats struct {
SizeRw int64 `json:"sizeRw"`
SizeRootFs int64 `json:"sizeRootFs"`
ContainerUsage int64 `json:"containerUsage"`
ContainerReclaimable int64 `json:"containerReclaimable"`
ImageUsage int64 `json:"imageUsage"`
ImageReclaimable int64 `json:"imageReclaimable"`
VolumeUsage int64 `json:"volumeUsage"`
VolumeReclaimable int64 `json:"volumeReclaimable"`
BuildCacheUsage int64 `json:"buildCacheUsage"`
BuildCacheReclaimable int64 `json:"buildCacheReclaimable"`
}
type ContainerListStats struct {
ContainerID string `json:"containerID"`
CPUTotalUsage uint64 `json:"cpuTotalUsage"`
SystemUsage uint64 `json:"systemUsage"`
CPUPercent float64 `json:"cpuPercent"`
PercpuUsage int `json:"percpuUsage"`
MemoryCache uint64 `json:"memoryCache"`
MemoryUsage uint64 `json:"memoryUsage"`
MemoryLimit uint64 `json:"memoryLimit"`
MemoryPercent float64 `json:"memoryPercent"`
}
type ContainerStats struct {
CPUPercent float64 `json:"cpuPercent"`
Memory float64 `json:"memory"`
Cache float64 `json:"cache"`
IORead float64 `json:"ioRead"`
IOWrite float64 `json:"ioWrite"`
NetworkRX float64 `json:"networkRX"`
NetworkTX float64 `json:"networkTX"`
ShotTime time.Time `json:"shotTime"`
}
type VolumeHelper struct {
Type string `json:"type"`
SourceDir string `json:"sourceDir"`
ContainerDir string `json:"containerDir"`
Mode string `json:"mode"`
Shared string `json:"shared"`
}
type PortHelper struct {
HostIP string `json:"hostIP"`
HostPort string `json:"hostPort"`
ContainerPort string `json:"containerPort"`
Protocol string `json:"protocol"`
}
type ContainerOperation struct {
TaskID string `json:"taskID"`
Names []string `json:"names" validate:"required"`
Operation string `json:"operation" validate:"required,oneof=up start stop restart kill pause unpause remove"`
}
type ContainerRename struct {
Name string `json:"name" validate:"required"`
NewName string `json:"newName" validate:"required"`
}
type ContainerCommit struct {
ContainerId string `json:"containerID" validate:"required"`
ContainerName string `json:"containerName"`
NewImageName string `json:"newImageName"`
Comment string `json:"comment"`
Author string `json:"author"`
Pause bool `json:"pause"`
TaskID string `json:"taskID"`
}
type ContainerPrune struct {
TaskID string `json:"taskID"`
PruneType string `json:"pruneType" validate:"required,oneof=container image volume network buildcache"`
WithTagAll bool `json:"withTagAll"`
}
type Network struct {
ID string `json:"id"`
Name string `json:"name"`
Labels []string `json:"labels"`
Driver string `json:"driver"`
IPAMDriver string `json:"ipamDriver"`
Subnet string `json:"subnet"`
Gateway string `json:"gateway"`
CreatedAt time.Time `json:"createdAt"`
Attachable bool `json:"attachable"`
}
type NetworkCreate struct {
Name string `json:"name" validate:"required"`
Driver string `json:"driver" validate:"required"`
Options []string `json:"options"`
Ipv4 bool `json:"ipv4"`
Subnet string `json:"subnet"`
Gateway string `json:"gateway"`
IPRange string `json:"ipRange"`
AuxAddress []SettingUpdate `json:"auxAddress"`
Ipv6 bool `json:"ipv6"`
SubnetV6 string `json:"subnetV6"`
GatewayV6 string `json:"gatewayV6"`
IPRangeV6 string `json:"ipRangeV6"`
AuxAddressV6 []SettingUpdate `json:"auxAddressV6"`
Labels []string `json:"labels"`
}
type Volume struct {
Name string `json:"name"`
Labels []VolumeOption `json:"labels"`
Driver string `json:"driver"`
Mountpoint string `json:"mountpoint"`
CreatedAt time.Time `json:"createdAt"`
Options []VolumeOption `json:"options"`
}
type VolumeCreate struct {
Name string `json:"name" validate:"required"`
Driver string `json:"driver" validate:"required"`
Options []string `json:"options"`
Labels []string `json:"labels"`
}
type VolumeOption struct {
Key string `json:"key"`
Value string `json:"value"`
}
type BatchDelete struct {
TaskID string `json:"taskID"`
Force bool `json:"force"`
Names []string `json:"names" validate:"required"`
}
type ComposeInfo struct {
Name string `json:"name"`
CreatedAt string `json:"createdAt"`
CreatedBy string `json:"createdBy"`
ContainerCount int `json:"containerCount"`
RunningCount int `json:"runningCount"`
ConfigFile string `json:"configFile"`
Workdir string `json:"workdir"`
Path string `json:"path"`
Containers []ComposeContainer `json:"containers"`
Env string `json:"env"`
}
type ComposeContainer struct {
ContainerID string `json:"containerID"`
Name string `json:"name"`
CreateTime string `json:"createTime"`
State string `json:"state"`
Ports []string `json:"ports"`
}
type ComposeCreate struct {
TaskID string `json:"taskID"`
Name string `json:"name"`
From string `json:"from" validate:"required,oneof=edit path template"`
File string `json:"file"`
Path string `json:"path"`
Template uint `json:"template"`
Env string `json:"env"`
PullImage *bool `json:"pullImage,omitempty"`
}
type ComposeOperation struct {
Name string `json:"name" validate:"required"`
Path string `json:"path"`
Operation string `json:"operation" validate:"required,oneof=up start restart stop down delete"`
WithFile bool `json:"withFile"`
Force bool `json:"force"`
}
type ComposeUpdate struct {
Name string `json:"name" validate:"required"`
Path string `json:"path" validate:"required"`
DetailPath string `json:"detailPath"`
Content string `json:"content" validate:"required"`
Env string `json:"env"`
}
type ComposeLogClean struct {
Name string `json:"name" validate:"required"`
Path string `json:"path" validate:"required"`
DetailPath string `json:"detailPath"`
}
type ContainerLog struct {
Container string `json:"container" validate:"required"`
Since string `json:"since"`
Tail uint `json:"tail"`
ContainerType string `json:"containerType"`
}
type StreamLog struct {
Compose string
Container string
Since string
Follow bool
Tail string
Type string
}

@ -0,0 +1,208 @@
package dto
import (
"time"
)
type PageCronjob struct {
PageInfo
Info string `json:"info"`
GroupIDs []uint `json:"groupIDs"`
OrderBy string `json:"orderBy" validate:"required,oneof=name status createdAt"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
}
type CronjobSpec struct {
Spec string `json:"spec" validate:"required"`
}
type CronjobOperate struct {
ID uint `json:"id"`
Name string `json:"name" validate:"required"`
Type string `json:"type" validate:"required"`
GroupID uint `json:"groupID"`
SpecCustom bool `json:"specCustom"`
Spec string `json:"spec" validate:"required"`
Executor string `json:"executor"`
ScriptMode string `json:"scriptMode"`
Script string `json:"script"`
Command string `json:"command"`
ContainerName string `json:"containerName"`
User string `json:"user"`
ScriptID uint `json:"scriptID"`
AppID string `json:"appID"`
Website string `json:"website"`
ExclusionRules string `json:"exclusionRules"`
DBType string `json:"dbType"`
DBName string `json:"dbName"`
URL string `json:"url"`
IsDir bool `json:"isDir"`
SourceDir string `json:"sourceDir"`
SnapshotRule SnapshotRule `json:"snapshotRule"`
SourceAccountIDs string `json:"sourceAccountIDs"`
DownloadAccountID uint `json:"downloadAccountID"`
RetainCopies int `json:"retainCopies" validate:"number,min=1"`
RetryTimes int `json:"retryTimes" validate:"number,min=0"`
Timeout uint `json:"timeout" validate:"number,min=1"`
IgnoreErr bool `json:"ignoreErr"`
Secret string `json:"secret"`
Args string `json:"args"`
AlertCount uint `json:"alertCount"`
AlertTitle string `json:"alertTitle"`
AlertMethod string `json:"alertMethod"`
CleanLogConfig
}
type CleanLogConfig struct {
Scopes []string `json:"scopes"`
}
type SnapshotRule struct {
WithImage bool `json:"withImage"`
IgnoreAppIDs []uint `json:"ignoreAppIDs"`
}
type CronjobUpdateStatus struct {
ID uint `json:"id" validate:"required"`
Status string `json:"status" validate:"required"`
}
type CronjobClean struct {
IsDelete bool `json:"isDelete"`
CleanData bool `json:"cleanData"`
CronjobID uint `json:"cronjobID" validate:"required"`
CleanRemoteData bool `json:"cleanRemoteData"`
}
type CronjobBatchDelete struct {
CleanData bool `json:"cleanData"`
CleanRemoteData bool `json:"cleanRemoteData"`
IDs []uint `json:"ids" validate:"required"`
}
type CronjobInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
GroupID uint `json:"groupID"`
SpecCustom bool `json:"specCustom"`
Spec string `json:"spec"`
Executor string `json:"executor"`
ScriptMode string `json:"scriptMode"`
Script string `json:"script"`
Command string `json:"command"`
ContainerName string `json:"containerName"`
User string `json:"user"`
ScriptID uint `json:"scriptID"`
AppID string `json:"appID"`
Website string `json:"website"`
ExclusionRules string `json:"exclusionRules"`
DBType string `json:"dbType"`
DBName string `json:"dbName"`
URL string `json:"url"`
IsDir bool `json:"isDir"`
SourceDir string `json:"sourceDir"`
RetainCopies int `json:"retainCopies"`
RetryTimes int `json:"retryTimes"`
Timeout uint `json:"timeout"`
IgnoreErr bool `json:"ignoreErr"`
SnapshotRule SnapshotRule `json:"snapshotRule"`
SourceAccounts []string `json:"sourceAccounts"`
DownloadAccount string `json:"downloadAccount"`
SourceAccountIDs string `json:"sourceAccountIDs"`
DownloadAccountID uint `json:"downloadAccountID"`
LastRecordStatus string `json:"lastRecordStatus"`
LastRecordTime string `json:"lastRecordTime"`
Status string `json:"status"`
Secret string `json:"secret"`
Args string `json:"args"`
AlertCount uint `json:"alertCount"`
}
type CronjobImport struct {
Cronjobs []CronjobTrans `json:"cronjobs"`
}
type CronjobTrans struct {
Name string `json:"name"`
Type string `json:"type"`
GroupID uint `json:"groupID"`
SpecCustom bool `json:"specCustom"`
Spec string `json:"spec"`
Executor string `json:"executor"`
ScriptMode string `json:"scriptMode"`
Script string `json:"script"`
Command string `json:"command"`
ContainerName string `json:"containerName"`
User string `json:"user"`
URL string `json:"url"`
ScriptName string `json:"scriptName"`
Apps []TransHelper `json:"apps"`
Websites []string `json:"websites"`
DBType string `json:"dbType"`
DBNames []TransHelper `json:"dbName"`
ExclusionRules string `json:"exclusionRules"`
IsDir bool `json:"isDir"`
SourceDir string `json:"sourceDir"`
RetainCopies uint64 `json:"retainCopies"`
RetryTimes uint `json:"retryTimes"`
Timeout uint `json:"timeout"`
IgnoreErr bool `json:"ignoreErr"`
SnapshotRule SnapshotTransHelper `json:"snapshotRule"`
Secret string `json:"secret"`
Args string `json:"args"`
SourceAccounts []string `json:"sourceAccounts"`
DownloadAccount string `json:"downloadAccount"`
AlertCount uint `json:"alertCount"`
AlertTitle string `json:"alertTitle"`
AlertMethod string `json:"alertMethod"`
}
type TransHelper struct {
Name string `json:"name"`
DetailName string `json:"detailName"`
}
type SnapshotTransHelper struct {
WithImage bool `json:"withImage"`
IgnoreApps []TransHelper `json:"ignoreApps"`
}
type ScriptOptions struct {
ID uint `json:"id"`
Name string `json:"name"`
}
type SearchRecord struct {
PageInfo
CronjobID int `json:"cronjobID"`
StartTime time.Time `json:"startTime"`
EndTime time.Time `json:"endTime"`
Status string `json:"status"`
}
type Record struct {
ID uint `json:"id"`
TaskID string `json:"taskID"`
StartTime string `json:"startTime"`
Records string `json:"records"`
Status string `json:"status"`
Message string `json:"message"`
TargetPath string `json:"targetPath"`
Interval int `json:"interval"`
File string `json:"file"`
}

@ -0,0 +1,203 @@
package dto
import "time"
type DashboardBase struct {
WebsiteNumber int `json:"websiteNumber"`
DatabaseNumber int `json:"databaseNumber"`
CronjobNumber int `json:"cronjobNumber"`
AppInstalledNumber int `json:"appInstalledNumber"`
Hostname string `json:"hostname"`
OS string `json:"os"`
Platform string `json:"platform"`
PlatformFamily string `json:"platformFamily"`
PlatformVersion string `json:"platformVersion"`
PrettyDistro string `json:"prettyDistro"`
KernelArch string `json:"kernelArch"`
KernelVersion string `json:"kernelVersion"`
VirtualizationSystem string `json:"virtualizationSystem"`
IpV4Addr string `json:"ipV4Addr"`
SystemProxy string `json:"systemProxy"`
CPUCores int `json:"cpuCores"`
CPULogicalCores int `json:"cpuLogicalCores"`
CPUModelName string `json:"cpuModelName"`
CPUMhz float64 `json:"cpuMhz"`
QuickJumps []QuickJump `json:"quickJump"`
CurrentInfo DashboardCurrent `json:"currentInfo"`
}
type ChangeQuicks struct {
Quicks []QuickJump `json:"quicks"`
}
type QuickJump struct {
ID uint `json:"id"`
Name string `json:"name"`
Alias string `json:"alias"`
Title string `json:"title"`
Detail string `json:"detail"`
Recommend int `json:"recommend"`
IsShow bool `json:"isShow"`
Router string `json:"router"`
}
type OsInfo struct {
OS string `json:"os"`
Platform string `json:"platform"`
PlatformFamily string `json:"platformFamily"`
KernelArch string `json:"kernelArch"`
KernelVersion string `json:"kernelVersion"`
PrettyDistro string `json:"prettyDistro"`
DiskSize int64 `json:"diskSize"`
}
type NodeCurrent struct {
Load1 float64 `json:"load1"`
Load5 float64 `json:"load5"`
Load15 float64 `json:"load15"`
LoadUsagePercent float64 `json:"loadUsagePercent"`
CPUUsedPercent float64 `json:"cpuUsedPercent"`
CPUUsed float64 `json:"cpuUsed"`
CPUTotal int `json:"cpuTotal"`
CPUDetailedPercent []float64 `json:"cpuDetailedPercent"`
MemoryTotal uint64 `json:"memoryTotal"`
MemoryAvailable uint64 `json:"memoryAvailable"`
MemoryUsed uint64 `json:"memoryUsed"`
MemoryUsedPercent float64 `json:"memoryUsedPercent"`
SwapMemoryTotal uint64 `json:"swapMemoryTotal"`
SwapMemoryAvailable uint64 `json:"swapMemoryAvailable"`
SwapMemoryUsed uint64 `json:"swapMemoryUsed"`
SwapMemoryUsedPercent float64 `json:"swapMemoryUsedPercent"`
}
type DashboardCurrent struct {
Uptime uint64 `json:"uptime"`
TimeSinceUptime string `json:"timeSinceUptime"`
Procs uint64 `json:"procs"`
Load1 float64 `json:"load1"`
Load5 float64 `json:"load5"`
Load15 float64 `json:"load15"`
LoadUsagePercent float64 `json:"loadUsagePercent"`
CPUPercent []float64 `json:"cpuPercent"`
CPUUsedPercent float64 `json:"cpuUsedPercent"`
CPUUsed float64 `json:"cpuUsed"`
CPUTotal int `json:"cpuTotal"`
CPUDetailedPercent []float64 `json:"cpuDetailedPercent"`
MemoryTotal uint64 `json:"memoryTotal"`
MemoryUsed uint64 `json:"memoryUsed"`
MemoryFree uint64 `json:"memoryFree"`
MemoryShard uint64 `json:"memoryShard"`
MemoryCache uint64 `json:"memoryCache"`
MemoryAvailable uint64 `json:"memoryAvailable"`
MemoryUsedPercent float64 `json:"memoryUsedPercent"`
SwapMemoryTotal uint64 `json:"swapMemoryTotal"`
SwapMemoryAvailable uint64 `json:"swapMemoryAvailable"`
SwapMemoryUsed uint64 `json:"swapMemoryUsed"`
SwapMemoryUsedPercent float64 `json:"swapMemoryUsedPercent"`
IOReadBytes uint64 `json:"ioReadBytes"`
IOWriteBytes uint64 `json:"ioWriteBytes"`
IOCount uint64 `json:"ioCount"`
IOReadTime uint64 `json:"ioReadTime"`
IOWriteTime uint64 `json:"ioWriteTime"`
DiskData []DiskInfo `json:"diskData"`
NetBytesSent uint64 `json:"netBytesSent"`
NetBytesRecv uint64 `json:"netBytesRecv"`
GPUData []GPUInfo `json:"gpuData"`
XPUData []XPUInfo `json:"xpuData"`
TopCPUItems []Process `json:"topCPUItems"`
TopMemItems []Process `json:"topMemItems"`
ShotTime time.Time `json:"shotTime"`
}
type AppLauncherSync struct {
Keys []string `json:"keys"`
}
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"`
UsedPercent float64 `json:"usedPercent"`
InodesTotal uint64 `json:"inodesTotal"`
InodesUsed uint64 `json:"inodesUsed"`
InodesFree uint64 `json:"inodesFree"`
InodesUsedPercent float64 `json:"inodesUsedPercent"`
}
type GPUInfo struct {
Index uint `json:"index"`
ProductName string `json:"productName"`
GPUUtil string `json:"gpuUtil"`
Temperature string `json:"temperature"`
PerformanceState string `json:"performanceState"`
PowerUsage string `json:"powerUsage"`
PowerDraw string `json:"powerDraw"`
MaxPowerLimit string `json:"maxPowerLimit"`
MemoryUsage string `json:"memoryUsage"`
MemUsed string `json:"memUsed"`
MemTotal string `json:"memTotal"`
FanSpeed string `json:"fanSpeed"`
}
type AppLauncher struct {
Key string `json:"key"`
Type string `json:"type"`
Name string `json:"name"`
Icon string `json:"icon"`
Limit int `json:"limit"`
Description string `json:"description"`
Recommend int `json:"recommend"`
IsInstall bool `json:"isInstall"`
IsRecommend bool `json:"isRecommend"`
Detail []InstallDetail `json:"detail"`
}
type InstallDetail struct {
InstallID uint `json:"installID"`
DetailID uint `json:"detailID"`
Name string `json:"name"`
Version string `json:"version"`
Path string `json:"path"`
Status string `json:"status"`
WebUI string `json:"webUI"`
HttpPort int `json:"httpPort"`
HttpsPort int `json:"httpsPort"`
}
type LauncherOption struct {
Key string `json:"key"`
IsShow bool `json:"isShow"`
}
type XPUInfo struct {
DeviceID int `json:"deviceID"`
DeviceName string `json:"deviceName"`
Memory string `json:"memory"`
Temperature string `json:"temperature"`
MemoryUsed string `json:"memoryUsed"`
Power string `json:"power"`
MemoryUtil string `json:"memoryUtil"`
}

@ -0,0 +1,346 @@
package dto
import "time"
// common
type DBConfUpdateByFile struct {
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mysql-cluster postgresql-cluster redis-cluster"`
Database string `json:"database" validate:"required"`
File string `json:"file"`
}
type ChangeDBInfo struct {
ID uint `json:"id"`
From string `json:"from" validate:"required,oneof=local remote"`
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mysql-cluster postgresql-cluster redis-cluster"`
Database string `json:"database" validate:"required"`
Value string `json:"value" validate:"required"`
}
type DBBaseInfo struct {
Name string `json:"name"`
ContainerName string `json:"containerName"`
Port int64 `json:"port"`
}
// mysql
type MysqlDBSearch struct {
PageInfo
Info string `json:"info"`
Database string `json:"database" validate:"required"`
OrderBy string `json:"orderBy" validate:"required,oneof=name createdAt"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
}
type MysqlDBInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
From string `json:"from"`
MysqlName string `json:"mysqlName"`
Format string `json:"format"`
Collation string `json:"collation"`
Username string `json:"username"`
Password string `json:"password"`
Permission string `json:"permission"`
IsDelete bool `json:"isDelete"`
Description string `json:"description"`
}
type MysqlOption struct {
ID uint `json:"id"`
From string `json:"from"`
Type string `json:"type"`
Database string `json:"database"`
Name string `json:"name"`
}
type MysqlDBCreate struct {
Name string `json:"name" validate:"required"`
From string `json:"from" validate:"required,oneof=local remote"`
Database string `json:"database" validate:"required"`
Format string `json:"format" validate:"required"`
Collation string `json:"collation"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Permission string `json:"permission" validate:"required"`
Description string `json:"description"`
}
type MysqlFormatCollationOption struct {
Format string `json:"format"`
Collations []string `json:"collations"`
}
type BindUser struct {
Database string `json:"database" validate:"required"`
DB string `json:"db" validate:"required"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Permission string `json:"permission" validate:"required"`
}
type MysqlLoadDB struct {
From string `json:"from" validate:"required,oneof=local remote"`
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
Database string `json:"database" validate:"required"`
}
type MysqlDBDeleteCheck struct {
ID uint `json:"id" validate:"required"`
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
Database string `json:"database" validate:"required"`
}
type MysqlDBDelete struct {
ID uint `json:"id" validate:"required"`
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
Database string `json:"database" validate:"required"`
ForceDelete bool `json:"forceDelete"`
DeleteBackup bool `json:"deleteBackup"`
}
type MysqlStatus struct {
AbortedClients string `json:"Aborted_clients"`
AbortedConnects string `json:"Aborted_connects"`
BytesReceived string `json:"Bytes_received"`
BytesSent string `json:"Bytes_sent"`
ComCommit string `json:"Com_commit"`
ComRollback string `json:"Com_rollback"`
Connections string `json:"Connections"`
CreatedTmpDiskTables string `json:"Created_tmp_disk_tables"`
CreatedTmpTables string `json:"Created_tmp_tables"`
InnodbBufferPoolPagesDirty string `json:"Innodb_buffer_pool_pages_dirty"`
InnodbBufferPoolReadRequests string `json:"Innodb_buffer_pool_read_requests"`
InnodbBufferPoolReads string `json:"Innodb_buffer_pool_reads"`
KeyReadRequests string `json:"Key_read_requests"`
KeyReads string `json:"Key_reads"`
KeyWriteEequests string `json:"Key_write_requests"`
KeyWrites string `json:"Key_writes"`
MaxUsedConnections string `json:"Max_used_connections"`
OpenTables string `json:"Open_tables"`
OpenedFiles string `json:"Opened_files"`
OpenedTables string `json:"Opened_tables"`
QcacheHits string `json:"Qcache_hits"`
QcacheInserts string `json:"Qcache_inserts"`
Questions string `json:"Questions"`
SelectFullJoin string `json:"Select_full_join"`
SelectRangeCheck string `json:"Select_range_check"`
SortMergePasses string `json:"Sort_merge_passes"`
TableLocksWaited string `json:"Table_locks_waited"`
ThreadsCached string `json:"Threads_cached"`
ThreadsConnected string `json:"Threads_connected"`
ThreadsCreated string `json:"Threads_created"`
ThreadsRunning string `json:"Threads_running"`
Uptime string `json:"Uptime"`
Run string `json:"Run"`
File string `json:"File"`
Position string `json:"Position"`
}
type MysqlVariables struct {
BinlogCacheSize string `json:"binlog_cache_size"`
InnodbBufferPoolSize string `json:"innodb_buffer_pool_size"`
InnodbLogBufferSize string `json:"innodb_log_buffer_size"`
JoinBufferSize string `json:"join_buffer_size"`
KeyBufferSize string `json:"key_buffer_size"`
MaxConnections string `json:"max_connections"`
MaxHeapTableSize string `json:"max_heap_table_size"`
QueryCacheSize string `json:"query_cache_size"`
QueryCacheType string `json:"query_cache_type"`
ReadBufferSize string `json:"read_buffer_size"`
ReadRndBufferSize string `json:"read_rnd_buffer_size"`
SortBufferSize string `json:"sort_buffer_size"`
TableOpenCache string `json:"table_open_cache"`
ThreadCacheSize string `json:"thread_cache_size"`
ThreadStack string `json:"thread_stack"`
TmpTableSize string `json:"tmp_table_size"`
SlowQueryLog string `json:"slow_query_log"`
LongQueryTime string `json:"long_query_time"`
}
type MysqlVariablesUpdate struct {
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
Database string `json:"database" validate:"required"`
Variables []MysqlVariablesUpdateHelper `json:"variables"`
}
type MysqlVariablesUpdateHelper struct {
Param string `json:"param"`
Value interface{} `json:"value"`
}
// redis
type ChangeRedisPass struct {
Database string `json:"database" validate:"required"`
Value string `json:"value"`
}
type RedisConfUpdate struct {
Database string `json:"database" validate:"required"`
Timeout string `json:"timeout"`
Maxclients string `json:"maxclients"`
Maxmemory string `json:"maxmemory"`
DBType string `json:"dbType" validate:"required,oneof=redis redis-cluster"`
}
type RedisConfPersistenceUpdate struct {
Database string `json:"database" validate:"required"`
Type string `json:"type" validate:"required,oneof=aof rbd"`
Appendonly string `json:"appendonly"`
Appendfsync string `json:"appendfsync"`
Save string `json:"save"`
DBType string `json:"dbType" validate:"required,oneof=redis redis-cluster"`
}
type RedisConf struct {
Database string `json:"database" validate:"required"`
Name string `json:"name"`
Port int64 `json:"port"`
ContainerName string `json:"containerName"`
Timeout string `json:"timeout"`
Maxclients string `json:"maxclients"`
Requirepass string `json:"requirepass"`
Maxmemory string `json:"maxmemory"`
}
type RedisPersistence struct {
Database string `json:"database" validate:"required"`
Appendonly string `json:"appendonly"`
Appendfsync string `json:"appendfsync"`
Save string `json:"save"`
}
type RedisStatus struct {
Database string `json:"database" validate:"required"`
TcpPort string `json:"tcp_port"`
UptimeInDays string `json:"uptime_in_days"`
ConnectedClients string `json:"connected_clients"`
UsedMemory string `json:"used_memory"`
UsedMemoryRss string `json:"used_memory_rss"`
UsedMemoryPeak string `json:"used_memory_peak"`
MemFragmentationRatio string `json:"mem_fragmentation_ratio"`
TotalConnectionsReceived string `json:"total_connections_received"`
TotalCommandsProcessed string `json:"total_commands_processed"`
InstantaneousOpsPerSec string `json:"instantaneous_ops_per_sec"`
KeyspaceHits string `json:"keyspace_hits"`
KeyspaceMisses string `json:"keyspace_misses"`
LatestForkUsec string `json:"latest_fork_usec"`
}
type DatabaseFileRecords struct {
Database string `json:"database" validate:"required"`
FileName string `json:"fileName"`
FileDir string `json:"fileDir"`
CreatedAt string `json:"createdAt"`
Size int `json:"size"`
}
type RedisBackupRecover struct {
Database string `json:"database" validate:"required"`
FileName string `json:"fileName"`
FileDir string `json:"fileDir"`
}
// database
type DatabaseSearch struct {
PageInfo
Info string `json:"info"`
Type string `json:"type"`
OrderBy string `json:"orderBy" validate:"required,oneof=name createdAt"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
}
type DatabaseInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name" validate:"max=256"`
From string `json:"from"`
Type string `json:"type"`
Version string `json:"version"`
Address string `json:"address"`
Port uint `json:"port"`
InitialDB string `json:"initialDB"`
Username string `json:"username"`
Password string `json:"password"`
SSL bool `json:"ssl"`
RootCert string `json:"rootCert"`
ClientKey string `json:"clientKey"`
ClientCert string `json:"clientCert"`
SkipVerify bool `json:"skipVerify"`
Timeout uint `json:"timeout"`
Description string `json:"description"`
}
type DatabaseOption struct {
ID uint `json:"id"`
Type string `json:"type"`
From string `json:"from"`
Database string `json:"database"`
Version string `json:"version"`
Address string `json:"address"`
}
type DatabaseItem struct {
ID uint `json:"id"`
From string `json:"from"`
Database string `json:"database"`
Name string `json:"name"`
}
type DatabaseCreate struct {
Name string `json:"name" validate:"required,max=256"`
Type string `json:"type" validate:"required"`
From string `json:"from" validate:"required,oneof=local remote"`
Version string `json:"version" validate:"required"`
Address string `json:"address"`
Port uint `json:"port"`
InitialDB string `json:"initialDB"`
Username string `json:"username" validate:"required"`
Password string `json:"password"`
SSL bool `json:"ssl"`
RootCert string `json:"rootCert"`
ClientKey string `json:"clientKey"`
ClientCert string `json:"clientCert"`
SkipVerify bool `json:"skipVerify"`
Timeout uint `json:"timeout"`
Description string `json:"description"`
}
type DatabaseUpdate struct {
ID uint `json:"id"`
Type string `json:"type" validate:"required"`
Version string `json:"version" validate:"required"`
Address string `json:"address"`
Port uint `json:"port"`
InitialDB string `json:"initialDB"`
Username string `json:"username" validate:"required"`
Password string `json:"password"`
SSL bool `json:"ssl"`
RootCert string `json:"rootCert"`
ClientKey string `json:"clientKey"`
ClientCert string `json:"clientCert"`
SkipVerify bool `json:"skipVerify"`
Timeout uint `json:"timeout"`
Description string `json:"description"`
}
type DatabaseDelete struct {
ID uint `json:"id" validate:"required"`
ForceDelete bool `json:"forceDelete"`
DeleteBackup bool `json:"deleteBackup"`
}
type LoadRedisStatus struct {
Name string `json:"name" validate:"required"`
Type string `json:"type" validate:"required"`
}
type DBResource struct {
Type string `json:"type"`
Name string `json:"name"`
}

@ -0,0 +1,79 @@
package dto
import "time"
type PostgresqlDBSearch struct {
PageInfo
Info string `json:"info"`
Database string `json:"database" validate:"required"`
OrderBy string `json:"orderBy" validate:"required,oneof=name createdAt"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
}
type PostgresqlDBInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
From string `json:"from"`
PostgresqlName string `json:"postgresqlName"`
Format string `json:"format"`
Username string `json:"username"`
Password string `json:"password"`
SuperUser bool `json:"superUser"`
IsDelete bool `json:"isDelete"`
Description string `json:"description"`
}
type PostgresqlOption struct {
ID uint `json:"id"`
From string `json:"from"`
Type string `json:"type"`
Database string `json:"database"`
Name string `json:"name"`
}
type PostgresqlDBCreate struct {
Name string `json:"name" validate:"required"`
From string `json:"from" validate:"required,oneof=local remote"`
Database string `json:"database" validate:"required"`
Format string `json:"format"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
SuperUser bool `json:"superUser"`
Description string `json:"description"`
}
type PostgresqlBindUser struct {
Name string `json:"name" validate:"required"`
Database string `json:"database" validate:"required"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
SuperUser bool `json:"superUser"`
}
type PostgresqlPrivileges struct {
Name string `json:"name" validate:"required"`
Database string `json:"database" validate:"required"`
Username string `json:"username" validate:"required"`
SuperUser bool `json:"superUser"`
}
type PostgresqlLoadDB struct {
From string `json:"from" validate:"required,oneof=local remote"`
Type string `json:"type" validate:"required,oneof=postgresql postgresql-cluster"`
Database string `json:"database" validate:"required"`
}
type PostgresqlDBDeleteCheck struct {
ID uint `json:"id" validate:"required"`
Type string `json:"type" validate:"required,oneof=postgresql postgresql-cluster"`
Database string `json:"database" validate:"required"`
}
type PostgresqlDBDelete struct {
ID uint `json:"id" validate:"required"`
Type string `json:"type" validate:"required,oneof=postgresql postgresql-cluster"`
Database string `json:"database" validate:"required"`
ForceDelete bool `json:"forceDelete"`
DeleteBackup bool `json:"deleteBackup"`
}

@ -0,0 +1,42 @@
package dto
type DeviceBaseInfo struct {
DNS []string `json:"dns"`
Hosts []HostHelper `json:"hosts"`
Hostname string `json:"hostname"`
TimeZone string `json:"timeZone"`
LocalTime string `json:"localTime"`
Ntp string `json:"ntp"`
User string `json:"user"`
SwapMemoryTotal uint64 `json:"swapMemoryTotal"`
SwapMemoryAvailable uint64 `json:"swapMemoryAvailable"`
SwapMemoryUsed uint64 `json:"swapMemoryUsed"`
MaxSize uint64 `json:"maxSize"`
SwapDetails []SwapHelper `json:"swapDetails"`
}
type HostHelper struct {
IP string `json:"ip"`
Host string `json:"host"`
}
type SwapHelper struct {
Path string `json:"path" validate:"required"`
Size uint64 `json:"size"`
Used string `json:"used"`
IsNew bool `json:"isNew"`
TaskID string `json:"taskID"`
}
type TimeZoneOptions struct {
From string `json:"from"`
Zones []string `json:"zones"`
}
type ChangePasswd struct {
User string `json:"user"`
Passwd string `json:"passwd"`
}

@ -0,0 +1,25 @@
package dto
type LsblkDevice struct {
Name string `json:"name"`
Size string `json:"size"`
Type string `json:"type"`
MountPoint *string `json:"mountpoint"`
FsType *string `json:"fstype"`
Model *string `json:"model"`
Serial string `json:"serial"`
Tran string `json:"tran"`
Rota bool `json:"rota"`
Children []LsblkDevice `json:"children,omitempty"`
}
type LsblkOutput struct {
BlockDevices []LsblkDevice `json:"blockdevices"`
}
type DiskFormatRequest struct {
Device string `json:"device" `
Filesystem string `json:"filesystem" `
Label string `json:"label,omitempty" `
QuickFormat bool `json:"quickFormat,omitempty"`
}

@ -0,0 +1,43 @@
package dto
type DaemonJsonUpdateByFile struct {
File string `json:"file"`
}
type DockerStatus struct {
IsActive bool `json:"isActive"`
IsExist bool `json:"isExist"`
}
type DaemonJsonConf struct {
IsSwarm bool `json:"isSwarm"`
Version string `json:"version"`
Mirrors []string `json:"registryMirrors"`
Registries []string `json:"insecureRegistries"`
LiveRestore bool `json:"liveRestore"`
IPTables bool `json:"iptables"`
CgroupDriver string `json:"cgroupDriver"`
Ipv6 bool `json:"ipv6"`
FixedCidrV6 string `json:"fixedCidrV6"`
Ip6Tables bool `json:"ip6Tables"`
Experimental bool `json:"experimental"`
LogMaxSize string `json:"logMaxSize"`
LogMaxFile string `json:"logMaxFile"`
}
type LogOption struct {
LogMaxSize string `json:"logMaxSize"`
LogMaxFile string `json:"logMaxFile"`
}
type Ipv6Option struct {
FixedCidrV6 string `json:"fixedCidrV6"`
Ip6Tables bool `json:"ip6Tables" validate:"required"`
Experimental bool `json:"experimental"`
}
type DockerOperation struct {
Operation string `json:"operation" validate:"required,oneof=start restart stop"`
}

@ -0,0 +1,29 @@
package dto
type Fail2BanBaseInfo struct {
IsEnable bool `json:"isEnable"`
IsActive bool `json:"isActive"`
IsExist bool `json:"isExist"`
Version string `json:"version"`
Port int `json:"port"`
MaxRetry int `json:"maxRetry"`
BanTime string `json:"banTime"`
FindTime string `json:"findTime"`
BanAction string `json:"banAction"`
LogPath string `json:"logPath"`
}
type Fail2BanSearch struct {
Status string `json:"status" validate:"required,oneof=banned ignore"`
}
type Fail2BanUpdate struct {
Key string `json:"key" validate:"required,oneof=port bantime findtime maxretry banaction logpath port"`
Value string `json:"value"`
}
type Fail2BanSet struct {
IPs []string `json:"ips"`
Operate string `json:"operate" validate:"required,oneof=banned ignore"`
}

@ -0,0 +1,8 @@
package dto
type LogFileRes struct {
Lines []string `json:"lines"`
IsEndOfFile bool `json:"isEndOfFile"`
TotalPages int `json:"totalPages"`
TotalLines int `json:"totalLines"`
}

@ -0,0 +1,113 @@
package dto
type FirewallBaseInfo struct {
Name string `json:"name"`
IsExist bool `json:"isExist"`
IsActive bool `json:"isActive"`
IsInit bool `json:"isInit"`
IsBind bool `json:"isBind"`
Version string `json:"version"`
PingStatus string `json:"pingStatus"`
}
type RuleSearch struct {
PageInfo
Info string `json:"info"`
Status string `json:"status"`
Strategy string `json:"strategy"`
Type string `json:"type" validate:"required"`
}
type FirewallOperation struct {
Operation string `json:"operation" validate:"required,oneof=start stop restart disableBanPing enableBanPing"`
WithDockerRestart bool `json:"withDockerRestart"`
}
type PortRuleOperate struct {
ID uint `json:"id"`
Operation string `json:"operation" validate:"required,oneof=add remove"`
Chain string `json:"chain"`
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"`
Description string `json:"description"`
}
type ForwardRuleOperate struct {
ForceDelete bool `json:"forceDelete"`
Rules []struct {
Operation string `json:"operation" validate:"required,oneof=add remove"`
Num string `json:"num"`
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
Interface string `json:"interface"`
Port string `json:"port" validate:"required"`
TargetIP string `json:"targetIP"`
TargetPort string `json:"targetPort" validate:"required"`
} `json:"rules"`
}
type UpdateFirewallDescription struct {
Type string `json:"type"`
Chain string `json:"chain"`
SrcIP string `json:"srcIP"`
DstIP string `json:"dstIP"`
SrcPort string `json:"srcPort"`
DstPort string `json:"dstPort"`
Protocol string `json:"protocol"`
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
Description string `json:"description"`
}
type AddrRuleOperate struct {
ID uint `json:"id"`
Operation string `json:"operation" validate:"required,oneof=add remove"`
Address string `json:"address" validate:"required"`
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
Description string `json:"description"`
}
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"`
}
type IptablesOp struct {
Name string `json:"name" validate:"required,oneof=1PANEL_INPUT 1PANEL_OUTPUT 1PANEL_BASIC"`
Operate string `json:"operate" validate:"required,oneof=init-base init-forward init-advance bind-base unbind-base bind unbind"`
}
type IptablesRuleOp struct {
Operation string `json:"operation" validate:"required,oneof=add remove"`
ID uint `json:"id"`
Chain string `json:"chain" validate:"required,oneof=1PANEL_BASIC 1PANEL_BASIC_BEFORE 1PANEL_INPUT 1PANEL_OUTPUT"`
Protocol string `json:"protocol"`
SrcIP string `json:"srcIP"`
SrcPort uint `json:"srcPort"`
DstIP string `json:"dstIP"`
DstPort uint `json:"dstPort"`
Strategy string `json:"strategy" validate:"required,oneof=accept drop reject"`
Description string `json:"description"`
}
type IptablesBatchOperate struct {
Rules []IptablesRuleOp `json:"rules"`
}
type IptablesChainStatus struct {
IsBind bool `json:"isBind"`
DefaultStrategy string `json:"defaultStrategy"`
}

@ -0,0 +1,43 @@
package dto
import (
"time"
)
type FtpInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
User string `json:"user"`
Password string `json:"password"`
Path string `json:"path"`
Status string `json:"status"`
Description string `json:"description"`
}
type FtpBaseInfo struct {
IsActive bool `json:"isActive"`
IsExist bool `json:"isExist"`
}
type FtpLogSearch struct {
PageInfo
User string `json:"user"`
Operation string `json:"operation"`
}
type FtpCreate struct {
User string `json:"user" validate:"required"`
Password string `json:"password" validate:"required"`
Path string `json:"path" validate:"required"`
Description string `json:"description"`
}
type FtpUpdate struct {
ID uint `json:"id"`
Password string `json:"password" validate:"required"`
Path string `json:"path" validate:"required"`
Status string `json:"status"`
Description string `json:"description"`
}

@ -0,0 +1,29 @@
package dto
type GroupCreate struct {
ID uint `json:"id"`
Name string `json:"name" validate:"required"`
Type string `json:"type" validate:"required"`
}
type GroupSearch struct {
Type string `json:"type" validate:"required"`
}
type GroupUpdate struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type" validate:"required"`
IsDefault bool `json:"isDefault"`
}
type GroupInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
IsDefault bool `json:"isDefault"`
}
type OperateByType struct {
Type string `json:"type"`
}

@ -0,0 +1,60 @@
package dto
import "time"
type PageImage struct {
PageInfo
Name string `json:"name"`
OrderBy string `json:"orderBy" validate:"required,oneof=size tags createdAt isUsed"`
Order string `json:"order" validate:"required,oneof=null ascending descending"`
}
type ImageInfo struct {
ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"`
IsUsed bool `json:"isUsed"`
Tags []string `json:"tags"`
Size int64 `json:"size"`
IsPinned bool `json:"isPinned"`
Description string `json:"description"`
}
type ImageLoad struct {
TaskID string `json:"taskID"`
Paths []string `json:"paths" validate:"required,dive,required"`
}
type ImageBuild struct {
TaskID string `json:"taskID"`
From string `json:"from" validate:"required"`
Name string `json:"name" validate:"required"`
Dockerfile string `json:"dockerfile" validate:"required"`
Tags []string `json:"tags"`
Args []string `json:"args"`
}
type ImagePull struct {
TaskID string `json:"taskID"`
RepoID uint `json:"repoID"`
ImageName []string `json:"imageName" validate:"required"`
}
type ImageTag struct {
SourceID string `json:"sourceID" validate:"required"`
Tags []string `json:"tags" validate:"required"`
}
type ImagePush struct {
TaskID string `json:"taskID"`
RepoID uint `json:"repoID" validate:"required"`
TagName string `json:"tagName" validate:"required"`
Name string `json:"name" validate:"required"`
}
type ImageSave struct {
TaskID string `json:"taskID"`
TagName string `json:"tagName" validate:"required"`
Path string `json:"path" validate:"required"`
Name string `json:"name" validate:"required"`
}

@ -0,0 +1,44 @@
package dto
import "time"
type ImageRepoCreate struct {
Name string `json:"name" validate:"required"`
DownloadUrl string `json:"downloadUrl"`
Protocol string `json:"protocol"`
Username string `json:"username"`
Password string `json:"password"`
Auth bool `json:"auth"`
}
type ImageRepoUpdate struct {
ID uint `json:"id"`
DownloadUrl string `json:"downloadUrl"`
Protocol string `json:"protocol"`
Username string `json:"username"`
Password string `json:"password"`
Auth bool `json:"auth"`
}
type ImageRepoInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
DownloadUrl string `json:"downloadUrl"`
Protocol string `json:"protocol"`
Username string `json:"username"`
Auth bool `json:"auth"`
Status string `json:"status"`
Message string `json:"message"`
}
type ImageRepoOption struct {
ID uint `json:"id"`
Name string `json:"name"`
DownloadUrl string `json:"downloadUrl"`
}
type ImageRepoDelete struct {
Ids []uint `json:"ids" validate:"required"`
}

@ -0,0 +1,15 @@
package dto
import (
"github.com/1Panel-dev/1Panel/agent/app/model"
)
type SearchTaskLogReq struct {
Status string `json:"status"`
Type string `json:"type"`
PageInfo
}
type TaskDTO struct {
model.Task
}

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

Loading…
Cancel
Save