InPanel 1.2.3__tar.gz → 1.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {inpanel-1.2.3 → inpanel-1.2.4}/InPanel.egg-info/PKG-INFO +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/InPanel.egg-info/SOURCES.txt +17 -9
- {inpanel-1.2.3 → inpanel-1.2.4}/PKG-INFO +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/app.py +32 -31
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/base.py +3 -3
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/config.py +4 -1
- {inpanel-1.2.3/inpanel → inpanel-1.2.4/inpanel/mod}/acme.py +29 -29
- {inpanel-1.2.3/inpanel → inpanel-1.2.4/inpanel/mod}/aliyuncs.py +1 -1
- inpanel-1.2.4/inpanel/mod/apt.py +820 -0
- inpanel-1.2.4/inpanel/mod/brew.py +602 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/certificate.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/config.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/cron.py +1 -1
- inpanel-1.2.4/inpanel/mod/dnf.py +611 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/docker.py +1 -1
- inpanel-1.2.4/inpanel/mod/docker_source.py +407 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/file.py +1 -1
- inpanel-1.2.4/inpanel/mod/firewall.py +204 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/firewall_base.py +18 -19
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/firewall_firewalld.py +16 -17
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/firewall_iptables.py +16 -17
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/firewall_macos.py +17 -18
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/firewall_ufw.py +16 -17
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/ftp.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/httpd.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/lighttpd.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/login.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/mysql.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/named.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/nginx.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/package.py +2 -4
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/package_apt.py +18 -13
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/package_base.py +29 -10
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/package_dnf.py +18 -13
- inpanel-1.2.4/inpanel/mod/package_map.py +100 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/package_yum.py +21 -13
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/php.py +1 -1
- inpanel-1.2.4/inpanel/mod/pip.py +373 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/plugins.py +22 -23
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/process.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/proftpd.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/pureftpd.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/query.py +1 -1
- {inpanel-1.2.3/inpanel → inpanel-1.2.4/inpanel/mod}/remote.py +5 -5
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/server.py +216 -27
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/service.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/setting.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/shell.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/ssh.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/system.py +16 -17
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/task.py +2 -2
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/ufw.py +2 -2
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/user.py +1 -1
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/vsftpd.py +1 -1
- inpanel-1.2.4/inpanel/mod/yum.py +816 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/plugin.py +16 -17
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/utils.js +490 -23
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/core.js +5 -2
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/storage/index.html +13 -11
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/index.html +3 -3
- inpanel-1.2.4/inpanel/public/partials/utils/sources.html +1182 -0
- inpanel-1.2.4/inpanel/templates/__init__.py +1 -0
- inpanel-1.2.4/inpanel/templates/sources/__init__.py +74 -0
- inpanel-1.2.4/inpanel/templates/sources/apt.json +224 -0
- inpanel-1.2.4/inpanel/templates/sources/brew.json +50 -0
- inpanel-1.2.4/inpanel/templates/sources/dnf.json +204 -0
- inpanel-1.2.4/inpanel/templates/sources/docker.json +49 -0
- inpanel-1.2.4/inpanel/templates/sources/package_map.json +71 -0
- inpanel-1.2.4/inpanel/templates/sources/pip.json +12 -0
- inpanel-1.2.4/inpanel/templates/sources/third_party.json +474 -0
- inpanel-1.2.4/inpanel/templates/sources/yum.json +690 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/utils.py +26 -27
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/web.py +156 -255
- {inpanel-1.2.3 → inpanel-1.2.4}/pyproject.toml +1 -1
- inpanel-1.2.3/inpanel/apt.py +0 -223
- inpanel-1.2.3/inpanel/dnf.py +0 -225
- inpanel-1.2.3/inpanel/mod/apt.py +0 -445
- inpanel-1.2.3/inpanel/mod/brew.py +0 -242
- inpanel-1.2.3/inpanel/mod/dnf.py +0 -370
- inpanel-1.2.3/inpanel/mod/firewall.py +0 -199
- inpanel-1.2.3/inpanel/mod/package_map.py +0 -366
- inpanel-1.2.3/inpanel/mod/pip.py +0 -207
- inpanel-1.2.3/inpanel/mod/yum.py +0 -372
- inpanel-1.2.3/inpanel/public/partials/utils/repository.html +0 -644
- inpanel-1.2.3/inpanel/yum.py +0 -756
- {inpanel-1.2.3 → inpanel-1.2.4}/InPanel.egg-info/dependency_links.txt +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/InPanel.egg-info/entry_points.txt +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/InPanel.egg-info/requires.txt +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/InPanel.egg-info/top_level.txt +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/LICENSE +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/MANIFEST.in +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/README.md +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/__init__.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/lib/__init__.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/lib/async_process.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/lib/filelock.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/lib/magic.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/lib/pxssh.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/lib/pyDes.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/__init__.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/mod/disk.py +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/css/global.css +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/favicon.ico +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/images/alipay.jpg +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/images/loading.gif +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/images/weixin.jpg +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/container.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/controllers.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/database.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/ecs.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/file.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/plugins.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/service.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/controllers/site.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/directives.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/filters.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/js/services.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/angular/1.0.2/angular-resource.min.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/angular/1.0.2/angular.min.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap-theme.css +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap-theme.css.map +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css.map +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap.css +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap.css.map +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap.min.css +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/css/bootstrap.min.css.map +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.svg +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/img/glyphicons-halflings.png +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/js/bootstrap.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/js/bootstrap.min.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/bootstrap/js/npm.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/codemirror/codemirror-compressed.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/codemirror/codemirror.css +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/jquery/jquery-1.12.4.min.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/md5/md5.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/lib/md5/md5.min.js +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/container/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/database/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/database/mysql/dbedit.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/database/mysql/dbnew.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/database/mysql/useredit.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/database/mysql/usernew.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/message.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/navbar.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/selector.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvbase.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvext.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvfile.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvinstall.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvlog.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvminiop.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvuninstall.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/directives/srvupdate.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/ecs/account.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/ecs/ecs.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/ecs/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/ecs/setings.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/file/file.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/file/trash.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/ftp.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/log.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/login.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/logout.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/main.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/plugins/config.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/plugins/detail.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/plugins/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/plugins/info.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/secure.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/apache.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/cron.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/fail2ban.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/firewalld.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/iptables.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/java11.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/java17.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/java21.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/java8.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/lighttpd.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/mariadb.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/memcache.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/minio.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/mongodb.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/mysql.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/named.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/nginx.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/nodejs18.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/nodejs20.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/nodejs22.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/nodejs24.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/ntp.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php56.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php74.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php80.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php81.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php82.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php83.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/php84.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/proftpd.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/pureftpd.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/redis.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/samba.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/sendmail.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/ssh.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/tomcat.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/ufw.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/service/vsftpd.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/setting.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/site/apache/site.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/site/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/site/nginx/site.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/sorry.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/storage/autofm.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/storage/backup.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/storage/migrate.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/storage/movedata.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/storage/remote.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/cron.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/firewall.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/network.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/process.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/shell.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/ssl.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/time.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/partials/utils/user.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/inpanel/public/robots.txt +0 -0
- {inpanel-1.2.3/inpanel → inpanel-1.2.4/inpanel/public}/templates/file/preview.html +0 -0
- {inpanel-1.2.3/inpanel → inpanel-1.2.4/inpanel/public}/templates/index.html +0 -0
- {inpanel-1.2.3 → inpanel-1.2.4}/setup.cfg +0 -0
|
@@ -9,18 +9,12 @@ InPanel.egg-info/entry_points.txt
|
|
|
9
9
|
InPanel.egg-info/requires.txt
|
|
10
10
|
InPanel.egg-info/top_level.txt
|
|
11
11
|
inpanel/__init__.py
|
|
12
|
-
inpanel/acme.py
|
|
13
|
-
inpanel/aliyuncs.py
|
|
14
12
|
inpanel/app.py
|
|
15
|
-
inpanel/apt.py
|
|
16
13
|
inpanel/base.py
|
|
17
14
|
inpanel/config.py
|
|
18
|
-
inpanel/dnf.py
|
|
19
15
|
inpanel/plugin.py
|
|
20
|
-
inpanel/remote.py
|
|
21
16
|
inpanel/utils.py
|
|
22
17
|
inpanel/web.py
|
|
23
|
-
inpanel/yum.py
|
|
24
18
|
inpanel/lib/__init__.py
|
|
25
19
|
inpanel/lib/async_process.py
|
|
26
20
|
inpanel/lib/filelock.py
|
|
@@ -28,6 +22,8 @@ inpanel/lib/magic.py
|
|
|
28
22
|
inpanel/lib/pxssh.py
|
|
29
23
|
inpanel/lib/pyDes.py
|
|
30
24
|
inpanel/mod/__init__.py
|
|
25
|
+
inpanel/mod/acme.py
|
|
26
|
+
inpanel/mod/aliyuncs.py
|
|
31
27
|
inpanel/mod/apt.py
|
|
32
28
|
inpanel/mod/brew.py
|
|
33
29
|
inpanel/mod/certificate.py
|
|
@@ -36,6 +32,7 @@ inpanel/mod/cron.py
|
|
|
36
32
|
inpanel/mod/disk.py
|
|
37
33
|
inpanel/mod/dnf.py
|
|
38
34
|
inpanel/mod/docker.py
|
|
35
|
+
inpanel/mod/docker_source.py
|
|
39
36
|
inpanel/mod/file.py
|
|
40
37
|
inpanel/mod/firewall.py
|
|
41
38
|
inpanel/mod/firewall_base.py
|
|
@@ -63,6 +60,7 @@ inpanel/mod/process.py
|
|
|
63
60
|
inpanel/mod/proftpd.py
|
|
64
61
|
inpanel/mod/pureftpd.py
|
|
65
62
|
inpanel/mod/query.py
|
|
63
|
+
inpanel/mod/remote.py
|
|
66
64
|
inpanel/mod/server.py
|
|
67
65
|
inpanel/mod/service.py
|
|
68
66
|
inpanel/mod/setting.py
|
|
@@ -208,10 +206,20 @@ inpanel/public/partials/utils/firewall.html
|
|
|
208
206
|
inpanel/public/partials/utils/index.html
|
|
209
207
|
inpanel/public/partials/utils/network.html
|
|
210
208
|
inpanel/public/partials/utils/process.html
|
|
211
|
-
inpanel/public/partials/utils/repository.html
|
|
212
209
|
inpanel/public/partials/utils/shell.html
|
|
210
|
+
inpanel/public/partials/utils/sources.html
|
|
213
211
|
inpanel/public/partials/utils/ssl.html
|
|
214
212
|
inpanel/public/partials/utils/time.html
|
|
215
213
|
inpanel/public/partials/utils/user.html
|
|
216
|
-
inpanel/templates/index.html
|
|
217
|
-
inpanel/templates/file/preview.html
|
|
214
|
+
inpanel/public/templates/index.html
|
|
215
|
+
inpanel/public/templates/file/preview.html
|
|
216
|
+
inpanel/templates/__init__.py
|
|
217
|
+
inpanel/templates/sources/__init__.py
|
|
218
|
+
inpanel/templates/sources/apt.json
|
|
219
|
+
inpanel/templates/sources/brew.json
|
|
220
|
+
inpanel/templates/sources/dnf.json
|
|
221
|
+
inpanel/templates/sources/docker.json
|
|
222
|
+
inpanel/templates/sources/package_map.json
|
|
223
|
+
inpanel/templates/sources/pip.json
|
|
224
|
+
inpanel/templates/sources/third_party.json
|
|
225
|
+
inpanel/templates/sources/yum.json
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Copyright (c) 2017-2026 Jackson Dou
|
|
5
5
|
# All rights reserved.
|
|
6
6
|
#
|
|
7
|
-
# InPanel is distributed under the terms of
|
|
7
|
+
# InPanel is distributed under the terms of the (new) BSD License.
|
|
8
8
|
# The full license can be found in 'LICENSE'.
|
|
9
9
|
|
|
10
10
|
import os
|
|
@@ -27,7 +27,7 @@ from .utils import make_cookie_secret
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def _read_pid(pidfile):
|
|
30
|
-
"""
|
|
30
|
+
"""从 pid 文件读取进程 ID,若文件不存在或内容无效则返回 None"""
|
|
31
31
|
pidfile_path = Path(pidfile)
|
|
32
32
|
if not pidfile_path.exists():
|
|
33
33
|
return None
|
|
@@ -39,7 +39,7 @@ def _read_pid(pidfile):
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def _is_running(pid):
|
|
42
|
-
"""
|
|
42
|
+
"""检查指定 PID 的进程是否正在运行"""
|
|
43
43
|
if pid is None or pid <= 0:
|
|
44
44
|
return False
|
|
45
45
|
try:
|
|
@@ -50,7 +50,7 @@ def _is_running(pid):
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def _wait_stop(pid, timeout=10):
|
|
53
|
-
"""
|
|
53
|
+
"""等待进程停止,超时返回 False,成功停止返回 True"""
|
|
54
54
|
for _ in range(timeout * 2):
|
|
55
55
|
if not _is_running(pid):
|
|
56
56
|
return True
|
|
@@ -94,7 +94,7 @@ Examples:
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
def cmd_start():
|
|
97
|
-
"""
|
|
97
|
+
"""以后台守护进程方式启动服务"""
|
|
98
98
|
pid = _read_pid(pidfile)
|
|
99
99
|
if pid and _is_running(pid):
|
|
100
100
|
print(f'InPanel is already running with PID: {pid}')
|
|
@@ -132,11 +132,11 @@ def cmd_start():
|
|
|
132
132
|
print(f'InPanel: fork failed: {e}')
|
|
133
133
|
sys.exit(1)
|
|
134
134
|
|
|
135
|
-
#
|
|
135
|
+
# 子进程:脱离终端并运行服务器
|
|
136
136
|
os.setsid()
|
|
137
137
|
os.umask(0)
|
|
138
138
|
|
|
139
|
-
#
|
|
139
|
+
# 重定向标准输入/输出/错误到日志文件
|
|
140
140
|
sys.stdout.flush()
|
|
141
141
|
sys.stderr.flush()
|
|
142
142
|
with open('/dev/null', 'r') as f:
|
|
@@ -150,7 +150,7 @@ def cmd_start():
|
|
|
150
150
|
|
|
151
151
|
|
|
152
152
|
def cmd_stop():
|
|
153
|
-
"""
|
|
153
|
+
"""停止服务"""
|
|
154
154
|
pid = _read_pid(pidfile)
|
|
155
155
|
if not pid:
|
|
156
156
|
print('InPanel is not running (no pid file)')
|
|
@@ -178,7 +178,7 @@ def cmd_stop():
|
|
|
178
178
|
|
|
179
179
|
|
|
180
180
|
def cmd_status():
|
|
181
|
-
"""
|
|
181
|
+
"""显示服务运行状态"""
|
|
182
182
|
pid = _read_pid(pidfile)
|
|
183
183
|
if not pid:
|
|
184
184
|
print('InPanel: not running')
|
|
@@ -197,7 +197,7 @@ def cmd_status():
|
|
|
197
197
|
|
|
198
198
|
|
|
199
199
|
def cmd_restart():
|
|
200
|
-
"""
|
|
200
|
+
"""重启服务"""
|
|
201
201
|
pid = _read_pid(pidfile)
|
|
202
202
|
if pid and _is_running(pid):
|
|
203
203
|
cmd_stop()
|
|
@@ -206,13 +206,13 @@ def cmd_restart():
|
|
|
206
206
|
|
|
207
207
|
|
|
208
208
|
def cmd_reload():
|
|
209
|
-
"""
|
|
209
|
+
"""重新加载服务(与重启相同)"""
|
|
210
210
|
print('InPanel: reloading (restart)...')
|
|
211
211
|
cmd_restart()
|
|
212
212
|
|
|
213
213
|
|
|
214
214
|
def cmd_uninstall(args=None):
|
|
215
|
-
"""
|
|
215
|
+
"""卸载 InPanel"""
|
|
216
216
|
if os.geteuid() != 0:
|
|
217
217
|
print('Error: uninstall must be run as root.')
|
|
218
218
|
sys.exit(1)
|
|
@@ -246,7 +246,7 @@ def cmd_uninstall(args=None):
|
|
|
246
246
|
|
|
247
247
|
print('Uninstalling InPanel...')
|
|
248
248
|
|
|
249
|
-
#
|
|
249
|
+
# 移除 systemd 服务
|
|
250
250
|
if os.path.exists(systemd_service):
|
|
251
251
|
try:
|
|
252
252
|
subprocess.run(['systemctl', 'stop', 'inpanel'], stderr=subprocess.DEVNULL)
|
|
@@ -263,7 +263,7 @@ def cmd_uninstall(args=None):
|
|
|
263
263
|
except Exception:
|
|
264
264
|
pass
|
|
265
265
|
|
|
266
|
-
#
|
|
266
|
+
# 移除 init.d 脚本
|
|
267
267
|
if os.path.exists(initd_script):
|
|
268
268
|
try:
|
|
269
269
|
subprocess.run(['chkconfig', '--del', 'inpanel'], stderr=subprocess.DEVNULL)
|
|
@@ -276,19 +276,19 @@ def cmd_uninstall(args=None):
|
|
|
276
276
|
os.remove(initd_script)
|
|
277
277
|
print(f' removed: {initd_script}')
|
|
278
278
|
|
|
279
|
-
#
|
|
279
|
+
# 移除二进制文件 / 控制台脚本
|
|
280
280
|
if os.path.exists(bin_path):
|
|
281
281
|
os.remove(bin_path)
|
|
282
282
|
print(f' removed: {bin_path}')
|
|
283
283
|
|
|
284
|
-
#
|
|
284
|
+
# 通过 pip 移除 Python 包
|
|
285
285
|
if run_type == 'system':
|
|
286
286
|
try:
|
|
287
287
|
subprocess.run([sys.executable, '-m', 'pip', 'uninstall', '-y', 'inpanel'],
|
|
288
288
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
289
289
|
print(' removed: inpanel python package')
|
|
290
290
|
except Exception:
|
|
291
|
-
#
|
|
291
|
+
# 尝试手动查找并删除
|
|
292
292
|
pkg_path = Path(__file__).parent.resolve()
|
|
293
293
|
if pkg_path.exists() and ('site-packages' in str(pkg_path) or 'dist-packages' in str(pkg_path)):
|
|
294
294
|
egg_info = pkg_path.parent / 'inpanel.egg-info'
|
|
@@ -297,12 +297,12 @@ def cmd_uninstall(args=None):
|
|
|
297
297
|
shutil.rmtree(pkg_path, ignore_errors=True)
|
|
298
298
|
print(f' removed: {pkg_path}')
|
|
299
299
|
|
|
300
|
-
#
|
|
300
|
+
# 移除配置文件(可选)
|
|
301
301
|
if purge_config and config_path and os.path.exists(config_path):
|
|
302
302
|
shutil.rmtree(config_path, ignore_errors=True)
|
|
303
303
|
print(f' removed: {config_path} (config files)')
|
|
304
304
|
|
|
305
|
-
#
|
|
305
|
+
# 移除日志文件(可选)
|
|
306
306
|
if purge_logs and logging_path and os.path.exists(logging_path):
|
|
307
307
|
shutil.rmtree(logging_path, ignore_errors=True)
|
|
308
308
|
print(f' removed: {logging_path} (log files)')
|
|
@@ -320,7 +320,7 @@ def cmd_uninstall(args=None):
|
|
|
320
320
|
|
|
321
321
|
|
|
322
322
|
def run_server():
|
|
323
|
-
"""
|
|
323
|
+
"""以前台模式运行服务器"""
|
|
324
324
|
try:
|
|
325
325
|
Path(logfile).parent.mkdir(parents=True, exist_ok=True)
|
|
326
326
|
Path(logerror).parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -356,8 +356,8 @@ def run_server():
|
|
|
356
356
|
'cookie_secret' : 'debug' if DEBUG else make_cookie_secret(),
|
|
357
357
|
'root_path' : root_path,
|
|
358
358
|
'data_path' : data_path,
|
|
359
|
-
'index_path' : str(Path(root_path) / 'templates' / 'index.html'),
|
|
360
|
-
'template_path' : str(Path(root_path) / 'templates'),
|
|
359
|
+
'index_path' : str(Path(root_path) / 'public' / 'templates' / 'index.html'),
|
|
360
|
+
'template_path' : str(Path(root_path) / 'public' / 'templates'),
|
|
361
361
|
'static_path' : str(Path(root_path) / 'public'),
|
|
362
362
|
'plugins_path' : str(Path(data_path) / 'plugins'),
|
|
363
363
|
'xsrf_cookies' : True,
|
|
@@ -374,12 +374,13 @@ def run_server():
|
|
|
374
374
|
(r'/api/process/(.+?)(?:/(.+))?', WebRequestProcess),
|
|
375
375
|
(r'/api/time/(.+?)(?:/(.+))?', web.UtilsTimeHandler),
|
|
376
376
|
(r'/api/ssl/(.+?)(?:/(.+))?', web.SSLTLSHandler),
|
|
377
|
-
(r'/api/
|
|
378
|
-
(r'/api/
|
|
379
|
-
(r'/api/
|
|
380
|
-
(r'/api/
|
|
381
|
-
(r'/api/
|
|
382
|
-
(r'/api/
|
|
377
|
+
(r'/api/sources/yum/(.+?)(?:/(.+))?', web.RepoYumHandler),
|
|
378
|
+
(r'/api/sources/dnf/(.+?)(?:/(.+))?', web.RepoDnfHandler),
|
|
379
|
+
(r'/api/sources/apt/(.+?)(?:/(.+))?', web.RepoAptHandler),
|
|
380
|
+
(r'/api/sources/brew/(.+?)(?:/(.+))?', web.RepoBrewHandler),
|
|
381
|
+
(r'/api/sources/pip/(.+?)(?:/(.+))?', web.RepoPipHandler),
|
|
382
|
+
(r'/api/sources/docker/(.+?)(?:/(.+))?', web.RepoDockerHandler),
|
|
383
|
+
(r'/api/sources/supported/?', web.RepoSupportedHandler),
|
|
383
384
|
(r'/api/firewall/(.+)', web.FirewallHandler),
|
|
384
385
|
(r'/api/setting/(.+)', web.SettingHandler),
|
|
385
386
|
(r'/api/operation/(.+)', web.OperationHandler),
|
|
@@ -468,13 +469,13 @@ def run_server():
|
|
|
468
469
|
|
|
469
470
|
|
|
470
471
|
def main():
|
|
471
|
-
#
|
|
472
|
+
# 将 'config' 子命令路由到 config 模块
|
|
472
473
|
if len(sys.argv) > 1 and sys.argv[1] == 'config':
|
|
473
474
|
from .config import main as config_main
|
|
474
475
|
config_main(sys.argv[2:])
|
|
475
476
|
return
|
|
476
477
|
|
|
477
|
-
#
|
|
478
|
+
# 服务控制命令
|
|
478
479
|
if len(sys.argv) > 1:
|
|
479
480
|
cmd = sys.argv[1].lower()
|
|
480
481
|
if cmd == 'start':
|
|
@@ -511,7 +512,7 @@ def main():
|
|
|
511
512
|
_print_help()
|
|
512
513
|
sys.exit(1)
|
|
513
514
|
|
|
514
|
-
#
|
|
515
|
+
# 无参数:显示帮助信息
|
|
515
516
|
_print_help()
|
|
516
517
|
|
|
517
518
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
#
|
|
6
6
|
# InPanel is distributed under the terms of the (new) BSD License.
|
|
7
7
|
# The full license can be found in 'LICENSE'.
|
|
8
|
-
'''
|
|
8
|
+
'''InPanel 基础信息模块'''
|
|
9
9
|
|
|
10
10
|
import sys
|
|
11
11
|
import os
|
|
@@ -41,8 +41,8 @@ __author__ = 'Jackson Dou'
|
|
|
41
41
|
__license__ = 'BSD'
|
|
42
42
|
|
|
43
43
|
app_name = 'InPanel'
|
|
44
|
-
releasetime = '2026-07-
|
|
45
|
-
DEBUG =
|
|
44
|
+
releasetime = '2026-07-17'
|
|
45
|
+
DEBUG = False
|
|
46
46
|
COMMENTFLAG = '#INPANEL#'
|
|
47
47
|
GENBY = 'AUTOMATICALLY GENERATED BY INPANEL'
|
|
48
48
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
+
'''InPanel 配置管理命令行工具'''
|
|
5
|
+
|
|
4
6
|
import sys
|
|
5
7
|
import logging
|
|
6
8
|
from pathlib import Path
|
|
@@ -115,7 +117,8 @@ Examples:
|
|
|
115
117
|
from hmac import new as hmac_new
|
|
116
118
|
from .utils import randstr
|
|
117
119
|
key = md5(randstr().encode('utf-8')).hexdigest()
|
|
118
|
-
|
|
120
|
+
md5_password = md5(value.encode('utf-8')).hexdigest()
|
|
121
|
+
pwd = hmac_new(key.encode('utf-8'), md5_password.encode('utf-8'), md5).hexdigest()
|
|
119
122
|
value = '%s:%s' % (pwd, key)
|
|
120
123
|
logger.info(f'Password hash generated, key length: {len(key)}, hash length: {len(pwd)}')
|
|
121
124
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# InPanel is distributed under the terms of the New BSD License.
|
|
7
7
|
# The full license can be found in 'LICENSE'.
|
|
8
8
|
|
|
9
|
-
'''
|
|
9
|
+
'''通过 ACME 协议从 Let's Encrypt 获取已签名 TLS 证书的模块。'''
|
|
10
10
|
|
|
11
11
|
import re
|
|
12
12
|
from base64 import urlsafe_b64encode
|
|
@@ -26,7 +26,7 @@ except ImportError:
|
|
|
26
26
|
|
|
27
27
|
class ACME():
|
|
28
28
|
|
|
29
|
-
#
|
|
29
|
+
# 参考: https://github.com/diafygi/acme-tiny,MIT 许可证,作者: Daniel Roesler
|
|
30
30
|
def __init__(self, account_key, csr, acme_check_dir, contact=None):
|
|
31
31
|
self.account_key = account_key
|
|
32
32
|
self.csr = csr
|
|
@@ -38,13 +38,13 @@ class ACME():
|
|
|
38
38
|
self.thumbprint = None
|
|
39
39
|
self.certificate = None
|
|
40
40
|
|
|
41
|
-
#
|
|
42
|
-
self.contact = contact
|
|
41
|
+
# 账号的联系方式(例如 mailto:aaa@bbb.com)
|
|
42
|
+
self.contact = contact
|
|
43
43
|
# self.ca = "https://acme-v02.api.letsencrypt.org"
|
|
44
|
-
# self.ca_directory =
|
|
45
|
-
#
|
|
44
|
+
# self.ca_directory = "https://acme-v02.api.letsencrypt.org/directory"
|
|
45
|
+
# 开发环境
|
|
46
46
|
self.ca = "https://acme-staging-v02.api.letsencrypt.org"
|
|
47
|
-
#
|
|
47
|
+
# 证书颁发机构目录 URL,默认为 Let's Encrypt
|
|
48
48
|
self.ca_directory = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
|
49
49
|
|
|
50
50
|
self.init_api_url()
|
|
@@ -54,7 +54,7 @@ class ACME():
|
|
|
54
54
|
# self.create_new_order()
|
|
55
55
|
|
|
56
56
|
def _cmd(self, cmd_list, stdin=None, cmd_input=None, err_msg="Command Line Error"):
|
|
57
|
-
'''
|
|
57
|
+
'''执行外部命令'''
|
|
58
58
|
proc = Popen(cmd_list, stdin=stdin, stdout=PIPE, stderr=PIPE)
|
|
59
59
|
out, err = proc.communicate(cmd_input)
|
|
60
60
|
if proc.returncode != 0:
|
|
@@ -62,11 +62,11 @@ class ACME():
|
|
|
62
62
|
return out
|
|
63
63
|
|
|
64
64
|
def _b64(self, b):
|
|
65
|
-
'''
|
|
65
|
+
'''JOSE 规范的 base64 编码'''
|
|
66
66
|
return urlsafe_b64encode(b).decode('utf8').replace('=', '')
|
|
67
67
|
|
|
68
68
|
def _request(self, url, data=None, err_msg='Error', depth=0):
|
|
69
|
-
'''
|
|
69
|
+
'''发送请求并自动解析 JSON 响应'''
|
|
70
70
|
try:
|
|
71
71
|
hd = {
|
|
72
72
|
"Content-Type": "application/jose+json",
|
|
@@ -84,14 +84,14 @@ class ACME():
|
|
|
84
84
|
except ValueError:
|
|
85
85
|
pass # ignore json parsing errors
|
|
86
86
|
if depth < 100 and code == 400 and res_data['type'] == 'urn:ietf:params:acme:error:badNonce':
|
|
87
|
-
raise IndexError(res_data) #
|
|
87
|
+
raise IndexError(res_data) # 允许对无效 nonce 重试 100 次
|
|
88
88
|
if code not in [200, 201, 204]:
|
|
89
89
|
raise ValueError("{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format(
|
|
90
90
|
err_msg, url, data, code, res_data))
|
|
91
91
|
return res_data, code, headers
|
|
92
92
|
|
|
93
93
|
def _s_request(self, url, payload, err_msg, depth=0):
|
|
94
|
-
'''
|
|
94
|
+
'''发送签名请求'''
|
|
95
95
|
payload64 = self._b64(dumps(payload).encode('utf8'))
|
|
96
96
|
new_nonce = self._request(self.ca_new_nonce)[2]['Replay-Nonce']
|
|
97
97
|
protected = {'url': url, 'alg': self.alg, "nonce": new_nonce}
|
|
@@ -107,10 +107,10 @@ class ACME():
|
|
|
107
107
|
})
|
|
108
108
|
try:
|
|
109
109
|
return self._request(url, data=data.encode('utf8'), err_msg=err_msg, depth=depth)
|
|
110
|
-
except IndexError: #
|
|
110
|
+
except IndexError: # 重试无效 nonce(无效 nonce 会抛出 IndexError)
|
|
111
111
|
return self._s_request(url, payload, err_msg, depth=(depth + 1))
|
|
112
112
|
|
|
113
|
-
#
|
|
113
|
+
# 辅助函数 - 轮询直到完成
|
|
114
114
|
def _poll_until_not(self, url, pending_statuses, err_msg):
|
|
115
115
|
while True:
|
|
116
116
|
result, _, _ = self._request(url, err_msg=err_msg)
|
|
@@ -120,7 +120,7 @@ class ACME():
|
|
|
120
120
|
return result
|
|
121
121
|
|
|
122
122
|
def init_api_url(self, ca_directory=None):
|
|
123
|
-
#
|
|
123
|
+
# 获取 ACME 目录 URL
|
|
124
124
|
print('API directory getting...')
|
|
125
125
|
ca = ca_directory
|
|
126
126
|
if ca is None:
|
|
@@ -135,7 +135,7 @@ class ACME():
|
|
|
135
135
|
print('API directory ready!')
|
|
136
136
|
|
|
137
137
|
def init_account(self, account_key=None):
|
|
138
|
-
#
|
|
138
|
+
# 解析账号密钥以获取公钥
|
|
139
139
|
print('Account key parsing...')
|
|
140
140
|
acc_key = account_key
|
|
141
141
|
if acc_key is None:
|
|
@@ -160,7 +160,7 @@ class ACME():
|
|
|
160
160
|
print('Account key ready...')
|
|
161
161
|
|
|
162
162
|
def registe_account(self, contact=None):
|
|
163
|
-
#
|
|
163
|
+
# 创建账号,更新联系信息(如有),并设置全局密钥标识
|
|
164
164
|
print('Account registration...')
|
|
165
165
|
reg_payload = {'termsOfServiceAgreed': True}
|
|
166
166
|
account, code, self.acct_headers = self._s_request(
|
|
@@ -180,7 +180,7 @@ class ACME():
|
|
|
180
180
|
print("Updated contact details:\n{0}".format("\n".join(account['contact'])))
|
|
181
181
|
|
|
182
182
|
def parse_csr(self, order=False):
|
|
183
|
-
#
|
|
183
|
+
# 查找域名
|
|
184
184
|
print('Domains CSR parsing...')
|
|
185
185
|
cmd = ['openssl', 'req', '-in', self.csr, '-noout', '-text']
|
|
186
186
|
out = self._cmd(cmd, err_msg="Error loading {0}".format(self.csr))
|
|
@@ -200,8 +200,8 @@ class ACME():
|
|
|
200
200
|
self.create_new_order(domains)
|
|
201
201
|
|
|
202
202
|
def create_new_order(self, domains, disable_check=False):
|
|
203
|
-
'''
|
|
204
|
-
disable_check:
|
|
203
|
+
'''创建新订单
|
|
204
|
+
disable_check: 在通知 CA 之前禁用挑战文件是否正确托管的检查
|
|
205
205
|
'''
|
|
206
206
|
print("Creating new order...")
|
|
207
207
|
order_payload = {"identifiers": [
|
|
@@ -210,13 +210,13 @@ class ACME():
|
|
|
210
210
|
self.ca_new_order, order_payload, "Error creating new order")
|
|
211
211
|
print("Order created!")
|
|
212
212
|
|
|
213
|
-
#
|
|
213
|
+
# 获取需要完成的授权
|
|
214
214
|
for auth_url in order['authorizations']:
|
|
215
215
|
authorization, _, _ = self._request(auth_url, err_msg='Error getting challenges')
|
|
216
216
|
domain = authorization['identifier']['value']
|
|
217
217
|
print("Domain {0} Verifying...".format(domain))
|
|
218
218
|
|
|
219
|
-
#
|
|
219
|
+
# 找到 http-01 挑战并写入挑战文件
|
|
220
220
|
challenge = [c for c in authorization['challenges'] if c['type'] == "http-01"][0]
|
|
221
221
|
token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
|
|
222
222
|
key_auth = "{0}.{1}".format(token, self.thumbprint)
|
|
@@ -224,7 +224,7 @@ class ACME():
|
|
|
224
224
|
with open(wellknown_path, 'w', encoding='utf-8') as f:
|
|
225
225
|
f.write(key_auth)
|
|
226
226
|
|
|
227
|
-
#
|
|
227
|
+
# 检查 wellknown 文件是否在指定位置
|
|
228
228
|
try:
|
|
229
229
|
wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(domain, token)
|
|
230
230
|
assert(disable_check or self._request(wellknown_url)[0] == key_auth)
|
|
@@ -233,7 +233,7 @@ class ACME():
|
|
|
233
233
|
raise ValueError("Wrote file to {0}, but couldn't download {1}: {2}".format(
|
|
234
234
|
wellknown_path, wellknown_url, e))
|
|
235
235
|
|
|
236
|
-
#
|
|
236
|
+
# 告知挑战已完成
|
|
237
237
|
self._s_request(
|
|
238
238
|
challenge['url'], {}, "Error submitting challenges: {0}".format(domain))
|
|
239
239
|
authorization = self._poll_until_not(auth_url, ["pending"], "Error checking challenge status for {0}".format(domain))
|
|
@@ -241,18 +241,18 @@ class ACME():
|
|
|
241
241
|
raise ValueError("Challenge did not pass for {0}: {1}".format(domain, authorization))
|
|
242
242
|
print("Domain {0} verified!".format(domain))
|
|
243
243
|
|
|
244
|
-
#
|
|
244
|
+
# 使用 CSR 完成订单
|
|
245
245
|
print('Certificate signing...')
|
|
246
246
|
csr_der = self._cmd(['openssl', 'req', '-in', self.csr, '-outform', 'DER'], err_msg='DER Export Error')
|
|
247
247
|
self._s_request(order['finalize'], {'csr': self._b64(csr_der)}, 'Error finalizing order')
|
|
248
|
-
#
|
|
248
|
+
# 轮询订单以监控其完成状态
|
|
249
249
|
order = self._poll_until_not(order_headers['Location'], ['pending', 'processing'], 'Error checking order status')
|
|
250
250
|
if order['status'] != 'valid':
|
|
251
251
|
raise ValueError("Order failed: {0}".format(order))
|
|
252
252
|
self.certificate = order['certificate']
|
|
253
253
|
|
|
254
254
|
def get_certificate(self, certificate=None):
|
|
255
|
-
#
|
|
255
|
+
# 下载证书
|
|
256
256
|
crt_url = self.certificate if certificate is None else certificate
|
|
257
257
|
if crt_url is None:
|
|
258
258
|
return None
|
|
@@ -261,12 +261,12 @@ class ACME():
|
|
|
261
261
|
return certificate_pem
|
|
262
262
|
|
|
263
263
|
def ertificate_revoke(self, crt):
|
|
264
|
-
'''
|
|
264
|
+
'''吊销证书'''
|
|
265
265
|
print(crt)
|
|
266
266
|
print('Certificate revoked!')
|
|
267
267
|
|
|
268
268
|
def certificate_renew(self, crt):
|
|
269
|
-
'''
|
|
269
|
+
'''续签证书'''
|
|
270
270
|
print(crt)
|
|
271
271
|
print('Certificate updated!')
|
|
272
272
|
|