APISIX Dashboard中文文档(三)

2022年7月6日14:51:49

APISIX Dashboard中文文档(一)
APISIX Dashboard中文文档(二)
APISIX Dashboard中文文档(三)

开发指南

Dashboard 包含 manager-apiweb 部分,因此您需要单独启动开发环境。

先决条件

在开发之前,请参考本指南 安装依赖项。

Clone the project

$ git clone -b release/2.13 https://github.com/apache/apisix-dashboard.git

开始开发

$ cd apisix-dashboard

manager-api

  1. 请更改api/conf/conf.yaml中的配置。

  2. 在根目录下,启动开发模式。

$ make api-run
  1. 在根目录下,停止开发模式
$ make api-stop
  1. 关于添加自定义插件或修改插件schema后仪表盘显示异常的问题,请参考FAQ

  2. 如果编写后端E2E测试,请参考后端E2E编写指南

web

  1. 转到 web 目录.
$ cd ./web
  1. 请更改 config/defaultSettings.ts 文件中的 manager-api 地址。 如果您遵循本指南,则可能需要按如下方式设置地址。
serveUrlMap:{
    dev: 'http://localhost:9000'
}
  1. 启动开发模式
$ yarn install

$ yarn start

如果在安装yarn的过程中出现gyp的错误,请忽略它并继续!

  1. 如果编写前端E2E测试,请参考前端E2E编写指南

i18n 用户指南

Apache APISIX Dashboard 使用 @umijs/plugin-locale 来解决 i18n 的问题,为了让 i18n 更清晰合理,建议遵守 以下规则

语言环境配置的位置

  • 请把全局语言环境放在src/locales下。
  • 请将每个页面的语言环境文件放在src/pages/$PAGE/locales文件夹下。
  • 请将组件的语言环境文件放在src/components/$COMPONENT/locales文件夹下,我们必须手动导入它们

如何为每个区域设置文件命名key

键可以是这样的:[basicModule].[moduleName].[elementName].[...desc]

  • 第一个拖曳级别是什么?例如:app.pwapage.consumercomponent.actionBar

  • 子键分为 $element + $description 样式 e.g: app.pwa.message.offline, component.actionBar.button.nextStep

    • 如果文本是元素的一部分,我们可以使用 [elementNameProps] 例如:page.consumer.proTableColumns.username
    • 如果一个元素有两个或多个相同级别的部分语言环境,我们可以添加数字后缀,例如:page.route.form.itemRulesExtraMessage1.pathpage.route.form.itemRulesExtraMessage2.path
  • 通用文本,其他部分不要重复,通用语言环境键省略[elementName]会更好。

    • 如果文本在模块内的两个或多个位置使用,我们建议共享模块中的文本,例如:page.route.parameterPosition
    • 如果文本在模块之间的两个或多个地方使用,我们建议全局共享文本,并添加global作为moduleName,git例如:component.global.confirm

全局语言环境键

我们已经定义了很多全局key,在做i18n之前,可以参考那些

推荐的子键命名

  • 表单
element props locale subKey
Form.Item label form.itemLabel
Form.Item rules.required form.itemRulesRequiredMessage
Form.Item rules.pattern form.itemRulesPatternMessage
Form.Item extra form.itemExtraMessage

Example:

'page.route.form.itemRulesExtraMessage.parameterName': '仅支持字母和数字,且只能以字母开头',
'page.route.form.itemRulesPatternMessage.apiNameRule': '最大长度应小于100',
  • Input
element props locale subKey
Input placeholder input.placeholder

Example:

'page.route.input.placeholder.parameterNameHttpHeader': '请求头键名,例如:HOST',
  • Button
element props locale subKey
Button null button

Example:

'page.route.button.returnList': '返回路由列表',
  • Steps
element props locale subKey
Steps.step title steps.stepTitle

Example:

'page.route.steps.stepTitle.defineApiRequest': '设置路由信息',
  • Select
element props locale subKey
Select.Option null select.option

Example:

'page.route.select.option.enableHttps': '启用 HTTPS',
  • Radio
element props locale subKey
Radio null radio

Example:

'page.route.radio.staySame': '保持原样',
  • ProTable
element props locale subKey
ProTable columns.title proTable.columnsTitle

ProTable 通常与表单一起出现,并且列标题与表单项标签相同,因此我们建议将这些标题键作为模块中的公共键。

前端 E2E

本项目使用 Cypress 作为前端 E2E 测试框架。

  1. 本地启动前端项目,请参考 develop 网页部分。

  2. 打开赛普拉斯测试运行器。 关于test-runner的使用,请参考test-runner概述。

    yarn cypress:open-dev
    
  3. 编写您的测试示例:请参考 /web/cypress 目录中的测试示例,或查看 RWA 了解更多示例。

为了方便用户开发前端E2E案例,我们默认使用remote manager-api。 如果您想使用本地 manager-api,请阅读以下说明:

  1. 启动本地 manager-api 服务,请参考 develop manager-api 部分。

  2. 要在本地启动前端项目,请参考develop网页部分。 注意:启动时需要将 yarn start 更改为 yarn start:e2e

  3. 打开 Cypress test-runner.

    yarn cypress:open
    

参考链接:

后端测试

本文档提供了设置环境以在本地运行测试的详细信息,以及后端编写单元和 E2E 测试的指南。

目录

在本地运行 E2E 测试

从源代码开始

1、后端E2E测试请先启动manager-apiapisixetcdupstream-node

2.要在本地启动manager-api项目,请参考develop网页部分。

  1. 要在本地启动 etcd,请参考 etcd start 网页部分。

4.要在本地启动apisix项目,请参考apisix start网页部分。

5.要在本地启动upstream-node,请在本地环境安装docker并执行命令。

 docker run -d --name upstream -v /(Your apisix-dashboard folder path)/api/test/docker/upstream.conf:/etc/nginx/conf.d/default.conf:ro -p 80:80 -p 1980:1980 -p 1981:1981 -p 1982:1982 -p 1983:1983 -p 1984:1984 johz/upstream:v2.0
  1. 所有服务启动后,就可以开始后端E2E测试了。

  2. upstream-node IP临时改成本地IP地址。 测试完应该改成GitHub上游节点IP。 如果测试用例不涉及上游节点,则不需要修改。

  3.  # Local E2E test create route example
     {
         "uris": ["/test-test"],
         "name": "route_all",
         "desc": "test",
         "methods": ["GET"],
         "hosts": ["test.com"],
         "status": 1,
         "upstream": {
             "nodes": {
                 # upstream node IP is required for local test
                 "(local ip):1981": 1
             },
             "type": "roundrobin"
          }
     }
    
      # GitHub E2E test create route example
     {
         "uris": ["/test-test"],
         "name": "route_all",
         "desc": "test",
         "methods": ["GET"],
         "hosts": ["test.com"],
         "status": 1,
         "upstream": {
             "nodes": {
                 "172.16.238.20:1981": 1
             },
             "type": "roundrobin"
          }
     }
    

Back to TOC

从 docker-compose 开始

  1. 安装 docker-compose

    注意: 为了在本地运行 docker compose,请在 ./api/conf/conf.yaml 中更改 listen.hostetcd.endpoints 的值,如下所示:

    listen:
       host: 0.0.0.0
       port: 9000
    etcd:
       endpoints:
         - 172.16.238.10:2379
         - 172.16.238.11:2379
         - 172.16.238.12:2379
    
  2. 使用docker-compose运行manager-apiapisixetcdupstream-node等服务,运行命令。

    cd /(Your apisix-dashboard folder path)/api/test/docker
    # Download the apisix dockerfile
    curl -o Dockerfile-apisix https://raw.githubusercontent.com/apache/apisix-docker/master/alpine/Dockerfile
    docker-compose up -d
    
  3. 当您使用docker-compose运行本地端到端测试并需要更新主代码时,需要执行命令关闭集群。

    cd /(Your apisix-dashboard folder path)/api/test/docker
    # -v: Remove links to mount volumes and volumes
    docker-compose  down -v
    # If you don't want to remove the link between mount volume and volume, you can use
    docker-compose stop [serviceName]
    
  4. 然后需要删除manage-api的镜像,重建manage-api的镜像,镜像构建成功后启动集群。
    (仅当您在 manager-api 中更改/添加了任何核心功能,对于简单地添加/删除测试用例/文件,不需要重建)。

** 为了便于访问并避免重复设置所需配置的麻烦,我们提供了一个 setup.sh 脚本
它位于 api/test/docker 目录中。 您可以通过脚本直接运行、删除和构建服务以及更新和恢复 conf.yaml
有关更多详细信息,请运行

./setup.sh help

(如果您是第一次设置环境,请按照描述的手动步骤进行。它将帮助您了解后台发生的情况)。

Back to TOC

开始测试

  1. 所有服务启动后,就可以开始后端端到端测试了。

    NOTE: 有时我们需要删除 etcd 存储信息。 否则会导致测试失败。

    • 进入E2E文件夹,执行命令测试所有E2E测试文件。

       cd /(Your apisix-dashboard folder path)/api/test/e2e
       go test -v
      
    • 您还可以对单个文件进行 E2E 测试。

       cd /(Your apisix-dashboard folder path)/api/test/e2e
       go test -v E2E-test-file.go base.go
      
  2. 目前,很多测试已经使用银杏测试框架迁移到 E2ENEW 文件夹,因为它能够提供
    高表达力,使阅读和写作测试成为一种乐趣。

    • 进入 E2ENEW 文件夹,执行命令递归运行所有 E2ENEW 测试套件。

       cd /(Your apisix-dashboard folder path)/api/test/e2enew
       ginkgo -r
      
    • 您还可以使用 ginkgo 运行单个 E2ENEW 测试套件。

       cd /(Your apisix-dashboard folder path)/api/test/e2enew/(path of the specific test suite)
       ginkgo -r
      

Back to TOC

编写单元和 E2E(端到端)测试

编写单元测试

目前,manager-api 的所有单元测试都是使用 Go 的内置测试包编写的。 它没有什么新鲜事。 您可以直接在现有的 <module>_test.go 文件中添加测试或创建一个新的。 有一件事需要解决,因为 manager-api 很大程度上依赖于处理来自 etcd 的数据,在某些情况下,您需要编写一些依赖于在 etcd 内外存储和检索信息的功能。 在这种情况下,您应该使用 store.MockInterface 编写单元测试,而不是直接依赖于 etcd。

MockInterface 嵌入了来自 mock 包的 mock.Mock 对象。 如果有助于模拟具有所需输入作为参数和输出作为返回值的对象的函数调用。 目前,routeservicesslupstream 处理程序中的所有单元测试都使用模拟接口。 例如

mStore := &store.MockInterface{}
mStore.On("<exact methodname of the real method>", mock.Anything)
      .Run(func(args mock.Arguments) {
           //arguments assertions or anything
           //gets executed before returning
       })
      .Return("<same return signature of the original method>")

您可以修改上述测试以了解它是如何工作的,或者通过 docs

Back to TOC

编写 E2E 测试

目前,apisix-dashboard的后端有两种e2e测试。 一个是普通的 e2e,另一个是 e2enew,其中第一个是使用 Go 内置的原生测试包编写测试,对于后者,测试被分组到测试套件中并使用 [ginkgo](https: //onsi.github.io/ginkgo/) - 一个测试框架,有助于编写更具表现力的测试,以便阅读和编写测试提供愉快的体验。

**积极地,我们正在将所有 e2e 测试迁移到 e2enew 模块。 所以我们不再接受 e2e 模块内的测试,任何新的测试都必须按照 BDD 样式测试使用 ginkgo 添加到 e2enew 模块中。 如果您对此有任何疑问,请与社区讨论您的疑虑,我们很乐意解决这些问题。

对于值断言,我们使用 testify 的 assert 包。 它提供了许多易于使用的断言函数,其中第一个参数是 *testing.T 对象,可以从 ginkgo.GinkgoT() 获得。

如果您正在创建任何需要对以下任何涉及 manager-apiapisix 的节点进行 HTTP 调用的测试,请在设置环境后(请参阅 [本地运行 E2E 测试](#running-e2e-tests -locally)了解详细信息),您可以使用 HttpTestCase 结构,它提供了一个很好的接口来进行调用以及对响应执行必要的检查。 以下是该结构最常用字段的简要说明,

type HttpTestCase struct {
    Desc          string                // Description about the test case.
    Object        *httpexpect.Expect    // returns a httpexpect object i.e. on which host the request is going to be made.
    Method        string                // HTTP request methods ( GET, POST, PATCH, PUT, DELETE, OPTIONS).
    Path          string                // the route path of that host
    Query         string                // Query params
    Body          string                // The request Body. Commonly used in POST, PUT, PATCH.
    Headers       map[string]string     // Request headers. Include authorization header for secure routes.
    ExpectStatus  int                   // Expected HTTP status code from the response
    ExpectCode    int                   // Code generated by the host. Generally 0 for http.StatusOK.
    ExpectMessage string                // The response message provided in the response by the host.
    ExpectBody    interface{}           // The expected message body as a response.
    Sleep         time.Duration //ms    // Cooldown period before making next request.
}

现在要运行测试,请使用 e2enew 模块内的基本包中提供的 RunTestCase(tc HttpTestCase) 方法。

注意: E2ENEW 还提供了独立的方法,用于对 GET、POST、PUT、DELETE 方法发出 HTTP 请求,以及使用“multipart/form”数据发出 POST 请求。 方法签名如下所述

  • HttpGet(url string, headers map[string]string) ([]byte, int, error)
  • HttpPost(url string, headers map[string]string, reqBody string) ([]byte, int, error)
  • HttpPut(url string, headers map[string]string, reqBody string) ([]byte, int, error)
  • HttpDelete(url string, headers map[string]string) ([]byte, int, error)

现在回到编写 e2enew 测试,

*如果您是 ginkgo 新手,建议您先阅读官方 docs

  • 要创建新的测试套件,请在 e2enew 模块下创建新目录。 然后对于初始引导使用,

       mkdir <dirname> #inside e2enew
       cd <dirname>
       ginkgo bootstrap # Generates <dirname>_suite_test.go
       #to add tests in separate files
       ginkgo generate <testgroup> #Generates <testgroup>_test.go
    
  • 这可以手动完成,但是,始终建议将类似的测试分组到特定的测试文件中。 请尝试在单独的测试文件中分开测试。

  • 我们使用不同的 ginkgo 容器来编写测试,包括 DescribeItAfterSuiteBeforeEach 等。 [ ref ]。 例如,在现有测试套件中添加一些逻辑上相似的测试可能看起来像

    var _ = ginkgo.Describe("<description about the tests>", func() {
             ginkgo.It("<test 1>", func() {
                //Testing logic & assertions
             })
             ginkgo.It("<test 2>", func() {
                //Testing logic & assertions
             })
          })
    

在这里,Describe 容器通过大量使用闭包将类似的测试分组到多个 It 块中,从而使语法具有高度的表现力。

  • 虽然取决于场景,但始终建议使用 ginkgo 的表驱动测试来运行独立的 HttpTestCase 使用 table.DescribeTabletable.Entry [[ref](https://pkg.go. dev/github.com/onsi/ginkgo/extensions/table) ]。 例如,

    var _ = ginkgo.Describe("<description about the tests>", func() {
             table.DescribeTable("<logical group 1>",
                func(tc base.HttpTestCase) {
                   base.RunTestCase(tc)
                },
                table.Entry("<test 1>", base.HttpTestCase{
                   //Fill the fields
                }),
                table.Entry("<test 2>", base.HttpTestCase{
                   //Fill the fields
                }),
             })
    
             table.DescribeTable("<logical group 2>", func () {
                ...
             })
    
          })
    
  • 仅供参考,ginkgo 将每个表条目减少到It块并同时/并行运行所有It块。 Ginkgo auto 仅从 It 块内的恐慌中恢复,因此请始终将您的断言放在 It 容器中。

FAQ

1. Vue.js 版本的仪表板

如果您需要 Apache APISIX Dashboard 1.0 的 Vue.js 构建,请使用 master-vue 分支

2.Dashboard 2.0 版和 1.5 版有什么区别?

2.0 版的仪表板从 1.5 版 中删除了 MySQL,将直接在 etcd 上运行。

3. etcd 兼容性问题

如果您使用低于 v2.0 的 Apache APISIX,请注意来自 etcd v2 API 的数据不兼容 使用来自 v3 API 的数据。 Apache APISIX Dashboard v2.0 及以上版本使用 etcd v3 API,apisix 1.5 及以下版本使用 etcd v2 API。

4. 在 Apache APISIX 中修改插件架构或创建自定义插件后,为什么我在仪表板上找不到它?

由于 Dashboard 缓存了 Apache APISIX 中插件的 jsonschema 数据,因此您在 Apache APISIX 中创建自定义插件后需要同步 Dashboard 中的数据,目前 仅支持手动操作。 请遵循以下指南。

1.确认你的APISIX正在运行并且开启了控制API(默认开启并且只运行本地访问)
参考开头:
https://apisix.apache.org/docs/apisix/control-api

2、在你的APISIX服务器上执行以下命令导出jsonchema(如果配置为非本地访问,则不需要在你的APISIX服务器上执行,访问IP和端口也要相应修改)

curl 127.0.0.1:9090/v1/schema > schema.json

Refer to https://apisix.apache.org/docs/apisix/control-api#get-v1schema

  1. 将导出的 schema.json 复制到 Dashboard 工作目录下的 conf 目录下(关于工作目录请参考 https://github.com/apache/apisix-dashboard/blob/master/docs/en/latest /deploy.md#working-directory)

  2. 重新启动管理 API

5. 如何编写 API 文档

我们使用 go-swagger 生成 Swagger 2.0 文档,然后将其转换为 markdown 格式,以便在 github 存储库中直接查看。 具体步骤如下:

1、根据规范写评论。 详情请参考本项目已有的示例api/internal/handler/route/route.go

2.使用go-swagger工具生成Swagger 2.0文档。

$ swagger generate spec -o ./docs/en/latest/api/api.yaml --scan-models

3.使用 swagger-markdown 工具将 Swagger 2.0 文档转换为 markdown 文档。

$ swagger-markdown -i ./docs/en/latest/api/api.yaml

6. 如何允许所有 IP 访问 APISIX Dashboard

  1. Allow all IPv4 access

默认情况下,“127.0.0.0/24”的 IPv4 范围被允许访问“APISIX Dashboard”。 如果你想允许所有的 IPv4 访问,那么只需在 conf/conf.yaml 的配置文件中配置 conf.allow_list 如下:

conf:
  allow_list:
    - 0.0.0.0/0
  1. Allow all IPv6 access

默认情况下,允许 ::1 的 IPv6 范围访问 APISIX Dashboard。 如果要允许所有 IPv6 访问,那么只需在 conf/conf.yaml 的配置文件中配置 conf.allow_list 如下:

conf:
  allow_list:
    - ::/0
  1. Allow all IP access

如果要允许所有IP访问APISIX Dashboard,只需要在conf/conf.yaml的配置文件中进行如下配置:

conf:
  allow_list:

重启manager-api,所有IP都可以访问APISIX Dashboard

注意:您可以在开发和测试环境中使用此方法,以允许所有 IP 访问您的 APISIX Dashboard 实例,但在生产环境中使用它并不安全。 在生产环境中,请仅授权特定的 IP 地址或地址范围访问您的实例。

7. 导入重复路由时的默认策略是什么?

目前我们拒绝导入重复路由,也就是说当你导入一个具有相同属性的路由时,所有的uri uris host hosts remote_addr remote_addrs priority varsfilter_func,作为现有路由,从OAS3.0导入路由时会报错。

8. APISIX仪表板添加grafana跨域问题

修改 Grafana 配置:

  1. 启用匿名访问:
# grep 'auth.anonymous' -A 3 defaults.ini
[auth.anonymous]
# enable anonymous access
enabled = true
  1. 允许通过 iframe 访问
# grep 'allow_embedding' defaults.ini
allow_embedding = true
···

9. APISIX仪表盘配置域名,内嵌Grafana无法登录

如果地址的域名配置为HTTPS,内嵌的grafana登录后会跳转到登录页面,可以参考这个解决方案:

Grafana最好用同样的方式配置域名。 否则地址解析会有问题。

posted on 2022-07-06 16:16  zh7314  阅读(2208)  评论(0编辑  收藏  举报