diff --git a/.gitignore b/.gitignore index ccd5937f2..abf165e2e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ celerybeat.pid django.db celerybeat-schedule.db data/static +_build/ diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index 5ce195783..7facaed22 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -12,7 +12,7 @@ __all__ = ['Node'] class Node(models.Model): id = models.UUIDField(default=uuid.uuid4, primary_key=True) key = models.CharField(unique=True, max_length=64, verbose_name=_("Key")) # '1:1:1:1' - value = models.CharField(max_length=128, unique=True, verbose_name=_("Value")) + value = models.CharField(max_length=128, verbose_name=_("Value")) child_mark = models.IntegerField(default=0) date_create = models.DateTimeField(auto_now_add=True) diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index a429d9895..7eaff63e6 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -26,14 +26,14 @@ signer = get_signer() class AssetUser(models.Model): id = models.UUIDField(default=uuid.uuid4, primary_key=True) name = models.CharField(max_length=128, unique=True, verbose_name=_('Name')) - username = models.CharField(max_length=16, verbose_name=_('Username')) + username = models.CharField(max_length=128, verbose_name=_('Username')) _password = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Password')) _private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator, ]) _public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key')) comment = models.TextField(blank=True, verbose_name=_('Comment')) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) - created_by = models.CharField(max_length=32, null=True, verbose_name=_('Created by')) + created_by = models.CharField(max_length=128, null=True, verbose_name=_('Created by')) @property def password(self): diff --git a/apps/assets/tasks.py b/apps/assets/tasks.py index 30f463597..a20ab3a74 100644 --- a/apps/assets/tasks.py +++ b/apps/assets/tasks.py @@ -91,7 +91,7 @@ def update_assets_hardware_info_util(assets, task_name=None): if task_name is None: task_name = _("Update some assets hardware info") tasks = const.UPDATE_ASSETS_HARDWARE_TASKS - hostname_list = [asset.hostname for asset in assets] + hostname_list = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] task, created = update_or_create_ansible_task( task_name, hosts=hostname_list, tasks=tasks, pattern='all', options=const.TASK_OPTIONS, run_as_admin=True, created_by='System', @@ -120,7 +120,10 @@ def update_assets_hardware_info_period(): """ from ops.utils import update_or_create_ansible_task task_name = _("Update assets hardware info period") - hostname_list = [asset.hostname for asset in Asset.objects.all()] + hostname_list = [ + asset.hostname for asset in Asset.objects.all() + if asset.is_active and asset.is_unixlike() + ] tasks = const.UPDATE_ASSETS_HARDWARE_TASKS # Only create, schedule by celery beat @@ -165,7 +168,8 @@ def test_admin_user_connectability_util(admin_user, task_name): from ops.utils import update_or_create_ansible_task assets = admin_user.get_related_assets() - hosts = [asset.hostname for asset in assets] + hosts = [asset.hostname for asset in assets + if asset.is_active and asset.is_unixlike()] if not hosts: return tasks = const.TEST_ADMIN_USER_CONN_TASKS @@ -257,7 +261,7 @@ def test_system_user_connectability_util(system_user, task_name): """ from ops.utils import update_or_create_ansible_task assets = system_user.assets - hosts = [asset.hostname for asset in assets] + hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] tasks = const.TEST_SYSTEM_USER_CONN_TASKS if not hosts: logger.info("No hosts, passed") @@ -346,7 +350,7 @@ def push_system_user_util(system_users, assets, task_name): logger.info("Not tasks, passed") return {} - hosts = [asset.hostname for asset in assets] + hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] if not hosts: logger.info("Not hosts, passed") return {} diff --git a/apps/assets/templates/assets/_system_user.html b/apps/assets/templates/assets/_system_user.html index fe06a6fc7..528e271e6 100644 --- a/apps/assets/templates/assets/_system_user.html +++ b/apps/assets/templates/assets/_system_user.html @@ -13,7 +13,7 @@
- 符合4A规范的专业运维审计系统:拥有跳板机的所有功能,认证,授权,审计,文件上传; + 全球首款完全开源的堡垒机,使用GNU GPL v2.0开源协议,是符合 4A 的专业运维审计系统。
- 极致的用户使用体验:拥有时尚外观是区别与以往版本和其他软件的铭牌,高雅的气质让你爱不释手; + 使用Python / Django 进行开发,遵循 Web 2.0 规范,配备了业界领先的 Web Terminal 解决方案,交互界面美观、用户体验好。
- 混合云环境下的堡垒机:怎么能容忍传统堡垒机的繁琐步骤,Jumpserver让你极致省力; + 采纳分布式架构,支持多机房跨区域部署,中心节点提供 API,各机房部署登录节点,可横向扩展、无并发访问限制。
- 改变世界,从一点点开始。 + 改变世界,从一点点开始。
+ Demo账号: admin 密码: admin +
+ {% endif %} + {% trans 'Forgot password' %}? --
diff --git a/apps/users/views/group.py b/apps/users/views/group.py index fb279b582..958c00ccc 100644 --- a/apps/users/views/group.py +++ b/apps/users/views/group.py @@ -92,8 +92,8 @@ class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView): def get_context_data(self, **kwargs): context = { - 'app': 'User', - 'action': 'User group granted asset', + 'app': _('Users'), + 'action': _('User group granted asset'), } kwargs.update(context) return super().get_context_data(**kwargs) diff --git a/apps/users/views/login.py b/apps/users/views/login.py index 10ad697ba..0b70238c0 100644 --- a/apps/users/views/login.py +++ b/apps/users/views/login.py @@ -1,6 +1,7 @@ # ~*~ coding: utf-8 ~*~ from __future__ import unicode_literals +import os from django import forms from django.shortcuts import render from django.contrib.auth import login as auth_login, logout as auth_logout @@ -56,6 +57,7 @@ class UserLoginView(FormView): return HttpResponse(_("Please enable cookies and try again.")) auth_login(self.request, form.get_user()) x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR', '').split(',') + if x_forwarded_for and x_forwarded_for[0]: login_ip = x_forwarded_for[0] else: @@ -75,6 +77,13 @@ class UserLoginView(FormView): self.redirect_field_name, self.request.GET.get(self.redirect_field_name, reverse('index'))) + def get_context_data(self, **kwargs): + context = { + 'demo_mode': os.environ.get("DEMO_MODE"), + } + kwargs.update(context) + return super().get_context_data(**kwargs) + @method_decorator(never_cache, name='dispatch') class UserLogoutView(TemplateView): @@ -237,7 +246,7 @@ class LoginLogListView(DatetimeSearchMixin, ListView): if self.user: queryset = queryset.filter(username=self.user) if self.keyword: - queryset = self.queryset.filter( + queryset = queryset.filter( Q(ip__contains=self.keyword) | Q(city__contains=self.keyword) | Q(username__contains=self.keyword) diff --git a/apps/users/views/user.py b/apps/users/views/user.py index e85f04877..bf2ecca57 100644 --- a/apps/users/views/user.py +++ b/apps/users/views/user.py @@ -313,7 +313,6 @@ class UserProfileView(LoginRequiredMixin, TemplateView): def get_context_data(self, **kwargs): context = { - 'app': _('Users'), 'action': _('Profile'), } kwargs.update(context) diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..526c8f5df --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = Jumpserver +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/_static/img/logo-text.png b/docs/_static/img/logo-text.png new file mode 100644 index 000000000..cb76b555a Binary files /dev/null and b/docs/_static/img/logo-text.png differ diff --git a/docs/_static/img/structure.png b/docs/_static/img/structure.png new file mode 100644 index 000000000..90476014c Binary files /dev/null and b/docs/_static/img/structure.png differ diff --git a/docs/admin_asset.rst b/docs/admin_asset.rst new file mode 100644 index 000000000..758db8912 --- /dev/null +++ b/docs/admin_asset.rst @@ -0,0 +1,2 @@ +资产管理模块 +============= \ No newline at end of file diff --git a/docs/admin_guide.rst b/docs/admin_guide.rst new file mode 100644 index 000000000..df59969cc --- /dev/null +++ b/docs/admin_guide.rst @@ -0,0 +1,10 @@ +管理文档 +========= + +这里介绍管理员功能。 + +.. toctree:: + :maxdepth: 1 + + admin_user + admin_asset diff --git a/docs/admin_user.rst b/docs/admin_user.rst new file mode 100644 index 000000000..cdce938e1 --- /dev/null +++ b/docs/admin_user.rst @@ -0,0 +1,51 @@ +用户管理 +======== + +这里介绍用户管理模块的功能。 + +点击页面左侧“用户列表”菜单下的“用户列表,进入用户列表页面。 + +.. contents:: Topics + +.. _create_user: + +创建用户 +```````` + +点击页面左上角“创建用户”按钮,进入创建用户页面,填写账户,角色安全,个人等信息,点击“提交”按钮,用户创建完成。 + + +.. _update_user: + +更新用户 +```````` + +点击页面右边的“更新”按钮,进入编辑用户页面,编辑用户信息,点击“提交”按钮,更新用户完成。 + +.. _delete_user: + +删除用户 +```````` + +点击页面右边的“删除”按钮,弹出是否删除确认框,点击“确定”按钮,删除用户完成。 + +.. _export_user: + +导出用户 +```````` + +选中用户,点击右上角的“导出”按钮,导出用户完成。 + +.. _inport_user: + +导入用户 +```````` + +点击右上角的“导入”按钮,弹出导入对话框,选择要导入的CSV格式文件,点击“确认”按钮,导入用户完成。 + +.. _batch_operation: + +批量操作 +```````` + +选中用户,选择页面左下角的批量操作选项,点击”提交“按钮,批量操作完成。 \ No newline at end of file diff --git a/docs/api_style_guide.rst b/docs/api_style_guide.rst new file mode 100644 index 000000000..438a6d94a --- /dev/null +++ b/docs/api_style_guide.rst @@ -0,0 +1,166 @@ +REST API规范约定 +---------------- + +这里仅考虑REST API的基本情况。参考 + +`RESTful API 设计指南`_ + +`github api文档`_ + +协议 +~~~~ + +API与用户的通信协议,总是使用HTTPs协议。 + +域名 +~~~~ + +这版api相对简单, 没有前后端分离, 没有独立app, 所以放在主域名下 + +:: + + https://example.org/api/ + +版本 +~~~~ + +将API的版本号放入URL中, 由于一个项目多个app所以Jumpserver使用以下风格, +将版本号放到app后面 + +:: + + https://example.com/api/:app:/:version:/:resource: + https://example.com/api/assets/v1.0/assets [GET, POST] + https://example.com/api/assets/v1.0/assets/1 [GET, PUT, DELETE] + +路径 +~~~~ + +路径又称“终点”(endpoint),表示API的具体网址。 +在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的“集合”(collection),所以API中的名词也应该使用复数。 +举例来说 cmdb中的assets列表, idc列表 + +:: + + https://example.com/api/:app:/:version:/:resource: + + https://example.com/api/assets/v1.0/assets [GET, POST] + https://example.com/api/assets/v1.0/assets/1 [GET, PUT, DELETE] + https://example.com/api/assets/v1.0/idcs [GET, POST] + +一般性的增删查改(CRUD)API,完全使用HTTP +method加上url提供的语义,url中的可变部分(比如上面提到的) +一般用来传递该API操作的核心实体对象的唯一ID,如果有更多的参数需要提供,GET方法请使用url +parameter +(例如:“?client_id=xxxxx&app_id=xxxxxx”),PUT/POST/DELETE方法请使用请求体传递参数。 + +HTTP Method +~~~~~~~~~~~ + +对于资源的具体操作类型,由HTTP动词表示。 + +常用的HTTP动词有下面五个(括号里是对应的SQL命令)。 + +- GET(SELECT):从服务器取出资源(一项或多项)。 +- POST(CREATE):在服务器新建一个资源。 +- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源, 幂等 +- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。 +- DELETE(DELETE):从服务器删除资源。 + +.. _RESTful API 设计指南: http://www.ruanyifeng.com/blog/2014/05/restful_api.html +.. _github api文档: https://developer.github.com/v3/ + + +过滤信息 +~~~~~~~~ + +常见参数约定 + +:: + + ?keyword=localhost 模糊搜索 + ?limit=10:指定返回记录的数量 + ?offset=10:指定返回记录的开始位置。 + ?page=2&per_page=100:指定第几页,以及每页的记录数。 + ?sort=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。 + ?asset_id=1:指定筛选条件 + +状态码 +~~~~~~ + +服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。 + +- 200 OK - + [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 +- 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 +- 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) +- 204 NO CONTENT - [DELETE]:用户删除数据成功。 +- 400 INVALID REQUEST - + [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 +- 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 +- 403 Forbidden - [*] + 表示用户得到授权(与401错误相对),但是访问是被禁止的。 +- 404 NOT FOUND - + [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 +- 406 Not Acceptable - + [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。 +- 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 +- 422 Unprocesable entity - [POST/PUT/PATCH] + 当创建一个对象时,发生一个验证错误。 +- 500 INTERNAL SERVER ERROR - + [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 + +错误处理 +~~~~~~~~ + +如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。 + +:: + + { + error: "Invalid API key" + } + + +返回结果 +~~~~~~~~ + +针对不同操作,服务器向用户返回的结果应该符合以下规范。 + +:: + + GET /collection:返回资源对象的列表(数组) + GET /collection/resource:返回单个资源对象 + POST /collection:返回新生成的资源对象 + PUT /collection/resource:返回完整的资源对象 + PATCH /collection/resource:返回完整的资源对象 + DELETE /collection/resource:返回一个空文档 + +Hypermedia API +~~~~~~~~~~~~~~ + +RESTful +API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。 +比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。 + +:: + + {"link": { + "rel": "collection https://www.example.com/zoos", + "href": "https://api.example.com/zoos", + "title": "List of zoos", + "type": "application/vnd.yourformat+json" + }} + +上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。 + +rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址), + +href表示API的路径,title表示API的标题,type表示返回类型。 Hypermedia +API的设计被称为HATEOAS。 Github的API就是这种设计. + +其它 +~~~~ + +(1)API的身份认证应该使用OAuth 2.0框架。 +(2)服务器返回的数据格式,应该尽量使用JSON \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..068048c0f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/stable/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) +import sphinx_rtd_theme + + +# -- Project information ----------------------------------------------------- + +project = 'jumpserver' +copyright = '北京堆栈科技有限公司 © 2014-2018' +author = 'Jumpserver team' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '0.5.0' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.viewcode', + 'sphinx.ext.githubpages', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'zh_CN' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' +html_show_sourcelink = False + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +# html_theme = 'alabaster' +html_theme = "sphinx_rtd_theme" +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +html_theme_options = { + 'logo_only': True, + 'display_version': False +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Jumpserver 文档' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'jumpserver.tex', 'jumpserver Documentation', + 'Jumpserver team', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'jumpserver', 'jumpserver Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'jumpserver', 'jumpserver Documentation', + author, 'jumpserver', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- +html_logo = '_static/img/logo-text.png' diff --git a/docs/contact.rst b/docs/contact.rst new file mode 100644 index 000000000..767554517 --- /dev/null +++ b/docs/contact.rst @@ -0,0 +1,33 @@ +联系方式 ++++++++++++++++++++++++++ + +QQ群 +~~~~~~~~ + +群1: 390139816 +群2: 399218702 +群3: 552054376 + + +Github +~~~~~~~~ + +https://github.com/jumpserver/jumpserver.git + + +官网 +~~~~~~~~ + +http://www.jumpserver.org + + +Demo +~~~~~~~~ + +http://demo.jumpserver.org:8080 + + +邮件 +~~~~~~~~ + +ibuler#fit2cloud.com (#替换为@) \ No newline at end of file diff --git a/docs/contributor.rst b/docs/contributor.rst new file mode 100644 index 000000000..05c2604f1 --- /dev/null +++ b/docs/contributor.rst @@ -0,0 +1,13 @@ +贡献者 +++++++++++++++++++++++++ + +感谢一下朋友为Jumpserver做出的贡献,世界因你们而不同,排名不分先后 + + +- **小彧 <李磊>** Django资深开发者,为用户模块贡献了很多代码 +- **sofia <周小侠>** 资深前端工程师, 前端代码贡献者 +- **liuz <刘正> 全栈工程师** 编写了Web terminal大部分代码 +- **jiaxiangkong <陈尚委>** Jumpserver测试运营 +- **halcyon <王墉>** DevOps 资深开发者, 0.3.2 核心开发者之一 +- **yumaojun03 <喻茂峻>** DevOps 资深开发者,擅长Python, Go以及PAAS平台开发 +- **kelianchun <柯连春>** DevOps 资产开发者,fix了很多bug \ No newline at end of file diff --git a/docs/development.rst b/docs/development.rst new file mode 100644 index 000000000..9e2411ea9 --- /dev/null +++ b/docs/development.rst @@ -0,0 +1,12 @@ +开发文档 +====================================== + +.. toctree:: + :maxdepth: 1 + :caption: 开发文档 + + api_style_guide + python_style_guide + project_structure + + diff --git a/docs/faq.rst b/docs/faq.rst new file mode 100644 index 000000000..d02cca126 --- /dev/null +++ b/docs/faq.rst @@ -0,0 +1,2 @@ +FAQ ++++++++++++++++++++++ \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 000000000..787f05564 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,29 @@ +.. jumpserver documentation master file, created by + sphinx-quickstart on Mon Feb 26 23:28:27 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Jumpserver 文档 +====================================== + +.. toctree:: + :maxdepth: 2 + :caption: 文档: + + intro + installation + admin_guide + user_guide + development + contributor + contact + faq + + + +索引 +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 000000000..e9dde1f48 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,9 @@ +安装文档 +++++++++++++++++++++++++ + +.. toctree:: + :maxdepth: 1 + + quickstart + step_by_step + upgrade diff --git a/docs/intro.rst b/docs/intro.rst new file mode 100644 index 000000000..a8810e14f --- /dev/null +++ b/docs/intro.rst @@ -0,0 +1,51 @@ +简介 +============ + +Jumpserver是混合云下更好用的堡垒机, 分布式架构设计无限扩展,轻松对接混合云资产,支持使用云存储(AWS S3, ES等)存储录像、命令 + +Jumpserver颠覆传统堡垒机, 无主机和并发数量限制,支持水平扩容,FIT2CLOUD提供完备的商业服务支持,用户无后顾之忧 + +Jumpserver拥有极致的用户体验, 极致UI体验,容器化的部署方式,部署过程方便快捷,可持续升级 + + +组件说明 +++++++++++++++++++++++++ + +Jumpserver +``````````` +现指Jumpserver管理后台,是核心组件(Core), 使用 Django Class Based View 风格开发,支持Restful API。 + +`Github