├── .github ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflow │ └── workflow.yml ├── .gitignore ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.EN.md ├── README.md ├── changelog ├── Readme.md ├── RoadMap 2022.md ├── RoadMap 2023.md ├── announcing-v1.0.0.md ├── announcing-v1.1.0.md ├── announcing-v1.2.0.md ├── announcing-v1.3.0.md ├── announcing-v1.4.0.md ├── announcing-v1.5.0.md ├── announcing-v1.6.0.md └── announcing-v1.6.1.md ├── docs ├── README.md ├── curl commands │ └── Update Gateway.md ├── plugin │ ├── circuit-breaker.md │ ├── header-restriction.md │ ├── img │ │ ├── plugin_readme_entry.png │ │ ├── plugin_readme_example.png │ │ ├── plugin_readme_list.png │ │ ├── plugin_readme_route.png │ │ └── plugin_readme_success.png │ ├── ip-restriction.md │ ├── local-limiting.md │ ├── percent-limit.md │ ├── plugin-configuring-guide.md │ ├── referer-restriction.md │ ├── response-header-rewrite.md │ ├── static-downgrade.md │ ├── ua-restriction.md │ └── uri-restriction.md └── troubleshooting │ └── troubleshooting.md ├── example ├── README.md ├── expose_api.md ├── expose_api.zh_CN.md ├── expose_api_with_ui.zh_CN.md ├── plugin_template_support_guide.md ├── rider_user_guide.md ├── rider_user_guide.zh_CN.md └── schema_guide.md ├── images ├── .DS_Store ├── architecture.png ├── hango-ui-create-gateway-form.png ├── hango-ui-create-route-form1.png ├── hango-ui-create-route-form2.png ├── hango-ui-create-svc-click.png ├── hango-ui-create-svc-form.png ├── hango-ui-publish-route-form.png ├── hango-ui-publish-svc-click.png ├── hango-ui-publish-svc-done.png ├── hango-ui-publish-svc-form.png ├── hango-ui.png ├── hango-wechat.png ├── hango_route.png ├── logo.jpg ├── pod_status_ok.PNG ├── rider_ok.png └── rider_uri_restriction_test_ok.png ├── install ├── README.md ├── README.zh_CN.md ├── check.sh ├── common │ └── common.sh ├── crds │ ├── crd-10.yaml │ ├── crd-11.yaml │ ├── crd-17.yaml │ └── crd-slime.yaml ├── helm │ ├── README.md │ └── hango-gateway │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── charts │ │ ├── apigw-demo │ │ │ ├── Chart.yaml │ │ │ ├── templates │ │ │ │ ├── apigw-demo-deployment.yaml │ │ │ │ └── apigw-demo-service.yaml │ │ │ └── values.yaml │ │ └── hango-gateway │ │ │ ├── Chart.yaml │ │ │ ├── templates │ │ │ ├── _helpers.tpl │ │ │ └── base │ │ │ │ └── hango-gateway │ │ │ │ ├── hango-gateway-configmap.yaml │ │ │ │ ├── hango-gateway-deploy.yaml │ │ │ │ ├── hango-gateway-service.yaml │ │ │ │ ├── hango-gateway-serviceaccount.yaml │ │ │ │ └── hango-plugin-configmap.yaml │ │ │ └── values.yaml │ │ └── values.yaml ├── init-hango │ └── init.sh ├── install.sh └── uninstall.sh ├── projects └── README.md ├── test ├── README.md ├── const.py └── hango-test.py └── tools └── code style └── Hango_Java_Code_Style.xml /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ** DO NOT OPEN NEW ISSUES ON THIS REPOSITORY ** 2 | 3 | This repository has not been marked archived/read-only, as we do periodically 4 | update the list of packages and/or their constraints. However, this repository 5 | is a _metapackage_, and is only used to release the product. 6 | 7 | If you find an issue, you should determine which package is responsible, and 8 | report against the correct package repository. As an example, if you see an 9 | exception reported that mentions `data plane`, this indicates an issue with 10 | the `Envoy` package, and should be reported against the `Envoy` repository. 11 | 12 | In the majority of cases, we will close any new issues without comment. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. kube apply '...' 16 | 2. curl '....' 17 | 3. See error 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Additional context** 23 | Add any other context about the problem here, e.g. 24 | - Kubernetes version 25 | - OS 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Description** 2 | 3 | Please provide a description of this PR 4 | 5 | **Affects** 6 | 7 | To help us figure out who should review this PR, please put an X in all the areas that this PR affects. 8 | 9 | - [ ] Configuration Infrastructure 10 | - [ ] Docs 11 | - [ ] Installation 12 | - [ ] Performance and Scalability 13 | - [ ] Test and Release 14 | - [ ] User Experience 15 | -------------------------------------------------------------------------------- /.github/workflow/workflow.yml: -------------------------------------------------------------------------------- 1 | # Initial commit. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS Desktop Services Store 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "projects/envoy-proxy"] 2 | path = projects/envoy-proxy 3 | url = https://github.com/hango-io/envoy-proxy.git 4 | [submodule "projects/slime"] 5 | path = projects/slime 6 | url = https://github.com/slime-io/slime.git 7 | [submodule "projects/istio"] 8 | path = projects/istio 9 | url = https://github.com/istio/istio.git 10 | [submodule "projects/api-plane"] 11 | path = projects/api-plane 12 | url = https://github.com/hango-io/api-plane.git 13 | [submodule "projects/hango-ui"] 14 | path = projects/hango-ui 15 | url = https://github.com/hango-io/ui.git 16 | [submodule "projects/hango-portal"] 17 | path = projects/hango-portal 18 | url = https://github.com/hango-io/portal.git 19 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all project spaces, and it also applies when 49 | an individual is representing the project or its community in public spaces. 50 | Examples of representing a project or community include using an official 51 | project e-mail address, posting via an official social media account, or acting 52 | as an appointed representative at an online or offline event. Representation of 53 | a project may be further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 代码贡献 2 | 3 | 如果你: 4 | 5 | - 有新的想法 6 | - 提交Feature 7 | - Bug report/fix 8 | - 贡献文档 9 | - Help wanted 10 | 11 | 建议先提[Issues](https://github.com/hango-io/hango-gateway/issues),描述你的目的或者问题。 12 | 13 | ## 代码/文档贡献流程 14 | 15 | Hango 项目分多个模块仓库,下面以 Hango-portal 为例,介绍代码如何提交至我们的开源仓库! 16 | 17 | ### 1. fork代码 18 | 19 | 访问 [https://github.com/hango-io/portal](https://github.com/hango-io/portal),选择指定仓库,点击右上角的 Fork ,将 Hango-portal 仓库代码 fork 到自己的 github 仓库中。 20 | 21 | ### 2. 创建本地工程 22 | 23 | 本地 clone 远端的 github 仓库,添加、修改制定内容,如何进行本地调试可以参考本地调试章节;代码开发请遵守 [Hango 代码开发规范](https://hango-io.github.io/developer-guide/development/),否则在代码 review 阶段会被驳回 24 | 25 | ### 3. 将变更推送到远端 26 | 27 | 本地完成代码构建后,我们需要将代码内容进行 commit, commit 按如下格式进行信息提交 28 | 29 | commit message格式 30 | ``` 31 | (): 32 | ``` 33 | - type: 用于说明git commit的类别,只允许使用下面的标识。 34 | - feat: 新功能(feature)。 35 | - fix/to: 修复bug 36 | - docs: 文档(documentation)。 37 | - style: 格式(不影响代码运行的变动)。 38 | - refactor: 重构(即不是新增功能,也不是修改bug的代码变动)。 39 | - perf: 优化相关,比如提升性能、体验。 40 | - test: 增加测试。 41 | - chore: 构建过程或辅助工具的变动。 42 | - revert: 回滚到上一个版本。 43 | - merge: 代码合并。 44 | - sync: 同步主线或分支的Bug。 45 | - scope(可选): scope用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。 46 | - subject(必须): subject是commit目的的简短描述,不超过50个字符。 47 | > 结尾不加其他标点符号 48 | 49 | commit 要求功能聚合,因此在推送前请进行适当的代码 rebase 操作 50 | 51 | ### 4. 提交Pull Request 52 | 53 | 待代码提交到个人的 fork 仓库后,我们可以向 Hango-portal 主仓库进行 PR 提交, PR 提交信息如下 54 | 55 | - 关联 issue 56 | - 提交人(关联人) 57 | Signed-off-by: \[姓名\] <邮箱> 58 | - PR 简要描述 59 | - 对模块或 Hango 项目的影响点 60 | 61 | ### 5. 其他 62 | 63 | 提交 PR 后,可以通过我们的官方微信平台或邮箱方式(hango.io@gmail.com)通知我们检视合入 64 | 65 | ![wechat](./images/hango-wechat.png) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020 hango 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.EN.md: -------------------------------------------------------------------------------- 1 | [//]: # "README" 2 | 3 | # Hango Gateway 4 | 5 | ![hango](images/logo.jpg) 6 | 7 | [中文参考](README.md) 8 | 9 | Hango is a high-performance, scalable, and feature-rich cloud native API gateway built on Envoy. 10 | 11 | Hango provides functions such as request proxy, dynamic routing, load balancing, current limiting, fuse, health check, security protection, etc. It can be used in application scenarios such as microservice gateways, seven-layer load balancing, Kubernetes Ingress, and Serverless gateways. 12 | 13 | Through the Hango Rider module, users can customize multi-language plugins for capability expansion. 14 | 15 | ## Documentation 16 | 17 | [Website](https://hango-io.github.io): introducing futures, roadmaps, configurations, practices and so on 18 | 19 | [Blog](https://hango-io.github.io/blog): introducing Hango 20 | 21 | ## Summary 22 | 23 | [Why Hango](#why-hango) 24 | 25 | [Features](#features) 26 | 27 | [Architecture](#architecture) 28 | 29 | [Projects](#projects) 30 | 31 | [Installation](#installation) 32 | 33 | [Usage](#usage) 34 | 35 | [Community](#community) 36 | 37 | [License](#license) 38 | 39 | ## Why-Hango 40 | 41 | As a hign performance gateway, hango can provide load balancing, rate-limiting, circuit-breaker, logging, downgrade, and more through plugins. Using hango, you will not implement the common module in your businness software. 42 | 43 | **Why Hango?** 44 | 45 | * **Technical route**: Build on leading edge/middle/service proxy **Envoy**, with abundant functions, excellent performance and complete observability. 46 | 47 | * **Extensibility**: Enhanced Lua **Rider** extensible plugin; multi-language extensible plugin base on **WebAssembly** (Alpha, follow-up to provide) 48 | 49 | * **Multi-scenario**: Used as API Gateway, Kubernetes Ingress, L7 Load balencer, Serveless gateway in the complex scenarios. 50 | 51 | * **Cloud Native**: Worked as implements of Kubernetes Ingress or Service Mesh Gateway with natural compatibility. 52 | 53 | * **API ecology & integration**: API ecology governance and hundreds of industrial protocol integration. 54 | 55 | * **Control usability**: Easy-to-use control console to manage gateways, services, routes, etc. 56 | 57 | ## Features 58 | 59 | * Enable HTTP, gRPC, Websocket and other multi-protocol proxy 60 | 61 | * Support Kubernetes, virtual services and other forms of service discovery 62 | 63 | * L7 traffic proxy, connection pool configuration 64 | 65 | * Dynamic routing based on request parameters, active and passive health check strategies, and rich load balancing algorithms 66 | 67 | * Multi-scenario flow management functions such as current limiting, fusing, downgrade, and retry 68 | 69 | * Security protection functions such as black and white list control, authentication and authentication 70 | 71 | * Visual console for gateway configuration management 72 | 73 | * Thanks to Envoy's excellent performance, single instance performance can reach more than 10w TPS 74 | 75 | * Custom plug-in framework, support users to develop custom plug-ins in multiple languages. Refer to [Rider User Guide](./example/rider_user_guide.md) 76 | 77 | ## Architecture 78 | 79 | Hango is built based on the concept of cloud native, the data plane is extended based on Envoy, the plug-in chain is enhanced, and the Rider module is provided for custom plug-in extensions; the control plane components include Slime, Istio, API Plane and Portal modules. 80 | 81 | Thanks to slime module, you can choose the latest stable istio as the xds-server to data-plane. 82 | 83 | ![architecture](images/architecture.png) 84 | 85 | ## Projects 86 | 87 | Hango Gateway is a cloud-native architecture solution, we have six micro-service projects. 88 | This package is a meta-package aggregating the following projects: 89 | 90 | * [Envoy Proxy](https://github.com/hango-io/envoy-proxy) 91 | * [Slime](https://github.com/slime-io/slime) 92 | * [Istio](https://github.com/istio/istio) 93 | * [Hango API Plane](https://github.com/hango-io/api-plane) 94 | * [Hango Portal](https://github.com/hango-io/portal) 95 | * [Hango UI](https://github.com/hango-io/ui) 96 | 97 | For more details about each projects, please reference the link. 98 | Any contributing should commit to the original repository. 99 | 100 | ## Installation 101 | 102 | Hango Gateway can be installed on a Kubernetes cluster by using a Helm Chart.The following document will take you through the process of either Installation, verification, and remove the resource if necessary. 103 | 104 | * [Hango Gateway Installation Guide](./install/README.md) 105 | 106 | ## Usage 107 | 108 | We have provide user guide on UI, you can follow the guide to use Hango Gateway step by step. 109 | 110 | ![hango-ui](images/hango-ui.png) 111 | 112 | Also, you can call the api privided by hango-portal. See [Expose api to Hango From API](./example/expose_api.md) 113 | 114 | ## Community 115 | 116 | Hango Gateway is an open-source project, and welcomes any and all contributors. To get started: 117 | 118 | * Mail List: Mail to hango.io@gmail.com, follow the reply to subscribe to the mailing list. 119 | * QQ Group 914823850 120 | * (Suggest) WeChat Group:Scan QR 121 | * Check out the Hango documentation 122 | * Read the [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) files. 123 | 124 | If you're interested in contributing, here are some ways: 125 | 126 | * Write a blog post for our blog 127 | * Investigate an open issue 128 | * Add more tests 129 | * Contribute to the Docs 130 | 131 | ## License 132 | 133 | [Apache-2.0](https://choosealicense.com/licenses/apache-2.0/) 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [//]: # "README" 2 | 3 | # Hango 4 | 5 | ![hango](images/logo.jpg) 6 | 7 | [English version](README.EN.md) 8 | 9 | Hango 是一个基于 **Envoy** 构建的高性能、可扩展、功能丰富的云原生API网关。 10 | 11 | Hango 提供请求代理、动态路由、负载均衡、限流、熔断、健康检查、安全防护等功能,可用于微服务网关、七层负载均衡、Kubernetes Ingress、Serverless网关等应用场景。 12 | 13 | 通过[Hango Rider](https://github.com/hango-io/rider)模块,用户可以自定义多语言插件进行能力扩展。 14 | 15 | ## 文档 16 | 17 | [指引文档](https://hango-io.github.io): 介绍功能、版本、配置、实践等内容的各类文档 18 | 19 | [博客](https://hango-io.github.io/blog): 介绍Hango相关动态 20 | 21 | ## 为什么选择Hango 22 | 23 | * **技术路线**:基于领先的网络代理组件 **Envoy** 构建,具备丰富的功能、优异的性能与可观测性 24 | 25 | * **扩展性**:可用于生产的增强级 Lua 扩展框架 Rider;基于 WebAssembly 的多语言扩展插件能力(Alpha,后续提供) 26 | 27 | * **多场景**:具备支撑微服务网关、七层负载均衡、Kubernetes Ingress、Serverless网关等多种场景能力 28 | 29 | * **云原生**:以云原生标准数据面组件 **Envoy** 作为核心引擎,天然亲和云原生;可作为 Kubernetes、**Service Mesh**、Serverless 的 Ingress、Gateway 实现 30 | 31 | * **API生态与集成**:以 API 为中心的生态管理,提供数百种工业级协议快速集成能力(后续提供) 32 | 33 | * **控制平面**:易用的控制台进行网关、服务、路由等多维度管理,简化使用者操作 34 | 35 | ## 提要 36 | 37 | [特性](#features) 38 | 39 | [架构](#archi) 40 | 41 | [工程](#pro) 42 | 43 | [安装](#install) 44 | 45 | [使用](#usage) 46 | 47 | [交流](#community) 48 | 49 | [License](#license) 50 | 51 | ## 特性 52 | 53 | 54 | * HTTP、gRPC、Websocket 等多协议代理 55 | 56 | * 支持 Kubernetes 等注册中心服务发现 57 | 58 | * L7 流量代理、连接池配置 59 | 60 | * 基于请求参数的动态路由、主动被动健康检查策略、丰富的负载均衡算法 61 | 62 | * 多场景限流、熔断、降级、重试等流量治理功能 63 | 64 | * IP黑白名单控制、认证鉴权等安全防护功能 65 | 66 | * 自定义Header黑白名单,内置UA、Refer黑白名单 67 | 68 | * 可视化控制台进行网关配置管理 69 | 70 | * 得益于 Envoy 优异的性能,单实例性能可达10w TPS以上 71 | 72 | * 自定义插件框架,支持用户用多种语言开发自定义插件,参考[Hango自定义插件使用手册](./example/rider_user_guide.zh_CN.md) 73 | 74 | ## 架构 75 | 76 | Hango 基于云原生理念构建,数据面基于 Envoy 进行扩展,增强插件链,提供 Rider 模块用于自定义插件扩展;控制面组件包括 Slime,Istio,API Plane 以及 Portal 模块。 77 | 78 | 得益于 [Slime](https://github.com/slime-io/slime) 良好的扩展性与兼容性,用户可以直接选择社区 [Istio](https://github.com/istio/istio) 作为控制面进行 Hango 构建。 79 | 80 | ![architecture](images/architecture.png) 81 | 82 | ## 工程 83 | 84 | Hango 是一个云原生架构下的网关项目,聚合了以下工程: 85 | 86 | * [Envoy Proxy](https://github.com/hango-io/envoy-proxy) - 数据面组件,南北流量入口 87 | * [Slime](https://github.com/slime-io/slime) - 将Slime CRD转换为Istio CRD 88 | * [Istio](https://github.com/istio/istio) - 核心控制面,生成对应的xDS配置,下发至Envoy 89 | * [API Plane](https://github.com/hango-io/api-plane) - 用于生成Istio CRD以及Slime CRD 90 | * [Gateway Portal](https://github.com/hango-io/portal) - Hango 控制台Portal 91 | * [Gateway UI](https://github.com/hango-io/ui) - Hango 控制台UI 92 | 93 | 可以点击链接详细了解每个项目模块。 94 | 95 | ## 安装 96 | 97 | 目前,安装Hango需要具备Kubernetes环境,目前支持1.17及以上 Kubernetes。 98 | 通过Helm,可以一键部署Hango。具体部署可以参考[Hango部署手册](./install/README.zh_CN.md) 99 | 100 | ## 使用 101 | 102 | Hango UI提供了用户使用指南,通过使用指南用户可以方面上手 Hango,可以参考[通过Hango UI配置Hango路由](./example/expose_api_with_ui.zh_CN.md) 103 | 104 | ![hango-ui](images/hango-ui.png) 105 | 106 | 同时,也可以通过API调用的方式进行配置,可以参考[通过OpenAPI配置Hango路由](./example/expose_api.zh_CN.md) 107 | 108 | ## 交流 109 | 110 | 真诚的欢迎各位和我们进行交流. 我们提供以下方式: 111 | 112 | * 邮件:hango.io@gmail.com 113 | * qq群:Hango 交流群 914823850 114 | * (推荐)微信群:扫码加入 - Hango 开源交流群 115 | * 参考[CONTRIBUTING.md](CONTRIBUTING.md) 和 [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) 文件 116 | 117 | 同时,也可以通过以下方式进行项目贡献: 118 | 119 | * 博客 120 | * Issue 121 | * 测试 122 | * 文档完善等 123 | 124 | ## 致谢 125 | Hango 的建设离不开社区成员有价值的工作,这里特别感谢 [Envoy](https://www.envoyproxy.io/) 与 [Istio](https://github.com/istio/istio) 126 | 127 | 128 | ## License 129 | 130 | [Apache-2.0](https://choosealicense.com/licenses/apache-2.0/) 131 | -------------------------------------------------------------------------------- /changelog/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/changelog/Readme.md -------------------------------------------------------------------------------- /changelog/RoadMap 2022.md: -------------------------------------------------------------------------------- 1 | ## 介绍 2 | 3 | 本文可以作为Hango用户和贡献者了解项目方向的参考 4 | 5 | ## 如何加入RoadMap 6 | 7 | * 可以通过issue提Feature的形式与我们进行讨论,如果功能被接受,我们会将对应的issue加入后续的规划 8 | * 如果对我们的规划有计划,可以通过issue进行评论,我们会将对应的issue分配给您 9 | 10 | ## Hango 迭代版本计划 11 | 12 | ### Hango 1.0.0(已发布) 13 | 14 | * 【治理】支持多维度黑白名单,提供UA黑白名单、Refer黑白名单、Header黑白名单、URI黑白名单配置 15 | * 【治理】支持错误码、慢响应路由级熔断 16 | * 【治理】支持服务维度主动、被动健康检查 17 | * 【治理】支持静态降级、动态降级 18 | * 【治理】支持版本分流,支持upstream维度的灰度发布 19 | * 【可观测】对接Prometheus,支持服务、路由指标监控 20 | * 【可观测】对接skywalking链路追踪 21 | * 【易用性】控制台支持连接超时,重试,空闲超时配置 22 | 23 | ### Hango 1.1.0(已发布) 24 | 25 | * 【服务发现】支持eureka、nacos注册中心服务发现 26 | * 【治理】支持流量染色 27 | * 【治理】支持WAF防护 28 | 29 | ### Hango 1.2.0(已发布) 30 | 31 | * 【多协议】支持基于dubbo bridge的dubbo协议转换能力 32 | * 【易用性】支持插件的部分常规输入校验 33 | * 【治理】集成smartlimit,统一集群限流,本地限流实现 34 | 35 | ### Hango 1.3.0(发布中) 36 | 37 | * 【高可用】支持基于多集群的两地三中心高可用部署 38 | * 【高可用】支持基于Region、Zone、Sub-zone的区域路由优先能力 39 | * 【多场景】支持通用网关能力,纳管负载均衡,apigw流量 40 | * 【多场景】支持基于权重,优先权的负载均衡算法 41 | * 【多场景】支持证书管理,SSL卸载 42 | -------------------------------------------------------------------------------- /changelog/RoadMap 2023.md: -------------------------------------------------------------------------------- 1 | # RoadMap 2 | 3 | ## 介绍 4 | 5 | 本文可以作为Hango用户和贡献者了解项目方向的参考 6 | 7 | ## 如何加入RoadMap 8 | 9 | * 可以通过issue提Feature的形式与我们进行讨论,如果功能被接受,我们会将对应的issue加入后续的规划 10 | * 如果对我们的规划有计划,可以通过issue进行评论,我们会将对应的issue分配给您 11 | 12 | ## Hango 迭代版本计划 13 | 14 | ### v1.3.0(融合网关) 15 | > 已发布 16 | 17 | * 支持虚拟网关形态,基于不同功能需求创建不同类型虚拟网关 18 | * 支持纳管预览用户Gateway API,支持多类插件增强 19 | 20 | ### v1.4.0(模型变更) 21 | > 已发布 22 | 23 | * 模型优化,取消服务路由元数据 24 | * 新增域名管理界面,用于集中式管理虚拟网关域名 25 | * 新增TLS证书管理 26 | * 支持单向HTTPS 27 | 28 | ### v1.5.0(Ingress) 29 | > 已发布 30 | 31 | * 支持K8S Ingress流量治理 32 | 33 | ### v1.6.0(插件市场) 34 | > 已发布 35 | 36 | * 支持插件市场能力 37 | * 支持Lua语言自定义插件接入插件市场 38 | 39 | ### v1.6.1(7层负载功能) 40 | > 已发布 41 | 42 | * 支持网关向upstream传客户端IP 43 | * 支持服务温暖上线 44 | * 支持基于Cookie会话保持方式 -------------------------------------------------------------------------------- /changelog/announcing-v1.0.0.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版V1.0的发布。在去年11月发布的基础上进行了架构升级,适配了Istio1.12+的版本,推出EnvoyPlugin以及PluginManagers两个新的Slime CRD,从功能以及扩展度上都进行了整体的升级。 3 | 4 | ### 新功能 5 | 6 | - 支持服务维度的负载均衡配置,包括轮询、最小连接、一致性Hash 7 | 8 | - 支持版本分流 9 | 10 | - 支持服务维度主动/被动健康检查 11 | 12 | - 支持TCP/HTTP连接池配置 13 | 14 | - 支持空闲超时 15 | 16 | - 支持路由维度重试 17 | 18 | - 支持动态降级、静态降级配置 19 | 20 | - 支持根据错误码以及慢响应的熔断配置 21 | 22 | - 支持本地限流 23 | 24 | - 支持多维度黑白名单配置,包括UA黑白名单,IP黑白名单,Refer黑白名单以及自定义Header黑白名单 25 | 26 | - 支持服务/路由维度指标监控 27 | 28 | - 对接skywalking、prometheus的链路追踪及指标能力 29 | 30 | 31 | ### 工程增强 32 | 33 | - 一键helm部署及初始化,脱离istioctl,直接采用helm部署,部署完成后,自动进行初始化 34 | 35 | - 采用Istio1.12+版本,升级Rider模块,支持异步获取请求body 36 | 37 | - 优化rider lua FFI,lua扩展性能进一步提升 -------------------------------------------------------------------------------- /changelog/announcing-v1.1.0.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版v1.1.0的发布。基于v1.0.0版本集成了eureka、nacos注册中心支持、waf插件、流量染色等特性 3 | 4 | ### 新功能 5 | 6 | - [支持对接eureka和nacos注册中心发现服务](https://github.com/hango-io/portal/pull/9) 7 | 8 | - [支持k8s服务流量染色功能](https://github.com/hango-io/hango-gateway/pull/45) 9 | 10 | - [支持waf插件](https://github.com/hango-io/hango-gateway/pull/45) 11 | 12 | 13 | ### 工程增强 14 | 15 | - [Slime模块聚合服务发现功能,CRD支持k8s 1.22+版本](https://github.com/hango-io/hango-gateway/pull/40) 16 | 17 | - [istiod CRD支持k8s 1.22+版本](https://github.com/hango-io/hango-gateway/pull/43) 18 | 19 | - [hango-portal 与 hango-api-plane SpringBoot升级至2.5.14版本](https://github.com/hango-io/api-plane/pull/11) -------------------------------------------------------------------------------- /changelog/announcing-v1.2.0.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版v1.2.0的发布。基于v1.1.0版本集成了dubbo bridge、基于SmartLimiter的自适应本地限流等功能 3 | 4 | ### 新功能 5 | 6 | - [支持dubbo服务发现](https://github.com/hango-io/api-plane/pull/13) 7 | 8 | - [支持SmartLimiter的本地限流](https://github.com/hango-io/hango-gateway/pull/47) 9 | 10 | 11 | ### 工程增强 12 | 13 | - [增加部分插件校验](https://github.com/hango-io/hango-gateway/pull/47) -------------------------------------------------------------------------------- /changelog/announcing-v1.3.0.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版v1.3.0的发布。基于v1.2.0版本更新了融合网关能力,支持k8s的Gateway API纳管等能力 3 | 4 | ### 新功能 5 | 6 | - [支持虚拟网关形态,基于不同功能需求创建不同类型虚拟网关](https://github.com/hango-io/portal/commit/eb61aa8d097fe59cee407f9e7afe1ca388853c60) 7 | 8 | - [支持纳管预览用户Gateway API,支持多类插件增强](https://github.com/hango-io/api-plane/commit/c53574e9dbfc89ae0e4c8f50da366a8de5af9451) 9 | 10 | 11 | ### 工程增强 12 | 13 | - [portal模块分为`common-infra`和`envoy-infra`,基于切面形式进行增强回调](https://github.com/hango-io/portal/commit/eb61aa8d097fe59cee407f9e7afe1ca388853c60) -------------------------------------------------------------------------------- /changelog/announcing-v1.4.0.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版v1.4.0的发布。 3 | 4 | 1、本次更新将上一版本的模型做了优化,取消服务路由元数据 5 | 6 | 2、新增加域名称管理界面,用于集中式管理虚拟网关域名称 7 | 8 | 3、新增加TLS证书管理以及单向HTTPS的能力 9 | ### 新功能 10 | 11 | - [SSL证书管理](https://hango-io.github.io/user-guide/best-practices/domain-certificate/certificate/) 12 | 13 | - [域名管理](https://hango-io.github.io/user-guide/best-practices/domain-certificate/domin/) 14 | 15 | - [虚拟网关支持单向TLS](https://hango-io.github.io/user-guide/best-practices/domain-certificate/tls/) 16 | 17 | ### 工程增强 18 | 19 | - 模型优化,合并服务路由元数据 -------------------------------------------------------------------------------- /changelog/announcing-v1.5.0.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版v1.5.0的发布。 3 | 4 | 1、本次新增了网关对Kubernetes Ingress的纳管 5 | ### 新功能 6 | 7 | - [Kubernetes Ingress纳管](http://localhost:8000/user-guide/best-practices/virtual-gateway/kubernetes-ingress/) 8 | 9 | ### 工程增强 10 | 11 | - 模型优化,合并服务路由元数据 -------------------------------------------------------------------------------- /changelog/announcing-v1.6.0.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版v1.6.0的发布。 3 | 4 | 本次新增了网关对插件市场功能支持 5 | 6 | ### 新功能 7 | 8 | - [支持插件市场](https://hango-io.github.io/user-guide/extension/plugin-market/) 9 | 10 | - [支持Lua语言接入插件市场](https://hango-io.github.io/user-guide/extension/plugin-market/#1lua) 11 | 12 | ### 工程修复 13 | 14 | - [修复安装刷屏问题](https://github.com/hango-io/hango-gateway/pull/64) -------------------------------------------------------------------------------- /changelog/announcing-v1.6.1.md: -------------------------------------------------------------------------------- 1 | ### 描述 2 | 本次更新是Hango正式版v1.6.1的发布。 3 | 4 | 本次新增了网关服务预热和会话保持功能的支持 5 | 6 | ### 新功能 7 | 8 | - [支持服务预热](https://hango-io.github.io/user-guide/best-practices/traffic-manage/service-warmup/) 9 | 10 | - [支持负载均衡网关会话保持](https://hango-io.github.io/user-guide/best-practices/traffic-manage/stateful-session/) 11 | 12 | ### 优化 13 | 14 | - 优化前端插件选择框大小 15 | 16 | - 优化前端服务和路由详情字体显示 -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Hango 文档 2 | 3 | 仅罗列部分插件文档,更多文档请参考[Hango website](https://hango-io.github.io/) 4 | 5 | ## 插件 6 | 7 | * [插件界面配置引导](plugin/plugin-configuring-guide.md) 8 | * [percent-limit](plugin/percent-limit.md) 9 | * [local-limiting](plugin/local-limiting.md) 10 | * [static-downgrade](plugin/static-downgrade.md) 11 | * [circuit-breaker](plugin/circuit-breaker.md) 12 | * [response-header-rewrite](plugin/response-header-rewrite.md) 13 | * [ua-restriction](plugin/ua-restriction.md) 14 | * [header-restriction](plugin/header-restriction.md) 15 | * [referer-restriction](plugin/referer-restriction.md) 16 | * [ip-restriction](plugin/ip-restriction.md) 17 | * [uri-restriction](plugin/uri-restriction.md) 18 | 19 | ## 问题定位 20 | 21 | * [问题定位引导](troubleshooting/troubleshooting.md) -------------------------------------------------------------------------------- /docs/curl commands/Update Gateway.md: -------------------------------------------------------------------------------- 1 | # Update Gateway By CURL Commands 2 | 3 | ### Update API-Plane and Envoy proxy address. 4 | ```shell 5 | curl -v -H "Content-Type:application/json" -d '{ 6 | "Gwid":1, 7 | "ApiPlaneAddr": "http://api-plane-sm.qa-ci.service.163.org", 8 | "Description": "Hango gateway test.", 9 | "GatewayConfigInfo": { 10 | "AuthAddr": "", 11 | "EnvId": "prod", 12 | "AuditDatasourceSwitch": "", 13 | "AuditDbConfig": "" 14 | }, 15 | "GwAddr": "http://gateway-proxy.qa-ci.service.163.org", 16 | "GwClusterName": "prod-gateway", 17 | "GwName": "hango_envoy_gateway", 18 | "GwType": "envoy", 19 | "ProjectIds": [ 20 | 0, 21 | 1, 22 | 3 23 | ] 24 | }' http://apigw-gportal-envoy.qa-ci.service.163.org/gdashboard?Action=UpdateGateway&Version=2018-08-09 25 | ``` -------------------------------------------------------------------------------- /docs/plugin/circuit-breaker.md: -------------------------------------------------------------------------------- 1 | # 熔断 2 | 3 | ## 描述 4 | 5 | `circuit-breaker`插件可以对网关流量基于请求错误率或时间窗进行熔断 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |----------------------------------|----------|-----|-------------------------------------------------|-------------------------------------------------------------------------------| 11 | | kind | string | 是 | circuit-breaker | 插件类型(值固定) | 12 | | response.headers[].key | string | 否 | length <= 200 | 熔断后请求响应头名称 | 13 | | response.headers[].value | string | 否 | length <= 200 | 熔断后请求响应头值 | 14 | | response.code | integer | 是 | [200, 599] | 熔断后请求响应码 | 15 | | response.body | string | 否 | - | 熔断后请求响应body | 16 | | config.average_response_time | float | 否 | (0, 1000.0] (s) | 慢响应时间阈值 | 17 | | config.error_percent_threshold | float | 否 | (0, 100.0] | 错误百分比阈值 | 18 | | config.consecutive_slow_requests | integer | 否 | [1, 10000] | 连续慢响应次数 | 19 | | config.breakType | []string | 是 | ErrorPercentCircuitbreaker
RTCircuitbreaker | 熔断触发条件类型
ErrorPercentCircuitbreaker: 错误率触发熔断
RTCircuitbreaker: RT触发熔断 | 20 | | config.min_request_amount | integer | 否 | [1, 1000000] | 最小请求次数 | 21 | | config.lookback_duration | integer | 是 | [1, 120] (s) | 最小请求次数 | 22 | | config.break_duration | integer | 是 | [1, 7200] (s) | 惩罚时间 | 23 | 24 | 25 | ## 前置条件 26 | 27 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 28 | 29 | ## 创建 30 | 31 | ```shell 32 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 33 | "BindingObjectId": {{ 路由ID }}, 34 | "BindingObjectType": "routeRule", 35 | "GwId": {{ 网关ID }}, 36 | "PluginConfiguration": "{\"kind\":\"circuit-breaker\",\"response\":{\"headers\":[{\"key\":\"breakHeader\",\"value\":\"breakHeaderValue\"}],\"code\":\"510\",\"body\":\"breakBody\"},\"config\":{\"average_response_time\":\"60\",\"error_percent_threshold\":\"90.0\",\"consecutive_slow_requests\":\"5\",\"breakType\":[\"ErrorPercentCircuitbreaker\",\"RTCircuitbreaker\"],\"min_request_amount\":\"20\",\"lookback_duration\":\"60\",\"break_duration\":\"10\"}}", 37 | "PluginType": "circuit-breaker" 38 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 39 | ``` 40 | 41 | ## 测试 42 | 43 | ```shell 44 | ## 通过改造如下基础curl命令,创造插件中配置数量的错误次数,根据时间窗或错误请求次数验证插件是否造成熔断 45 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" 46 | ``` 47 | 48 | ## 删除 49 | 50 | ```shell 51 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 52 | ``` 53 | 54 | ## 界面配置方法 55 | 56 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/header-restriction.md: -------------------------------------------------------------------------------- 1 | # Header黑白名单 2 | 3 | ## 描述 4 | 5 | `header-restriction`插件可以针对来携带不同请求头的请求进行黑名单或白名单限制 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |-------------------|---------|-----|---------------------------------------------------|------------------------------| 11 | | kind | string | 是 | header-restriction | 插件类型(值固定) | 12 | | type | integer | 是 | [0, 1] | Header黑白名单策略
0:黑名单;1:白名单 | 13 | | list[].header | string | 是 | length <= 200 | Header名 | 14 | | list[].match_type | string | 是 | exact_match
prefix_match
safe_regex_match | Header黑白名单策略 | 15 | | list[].value | string | 是 | length <= 200 | Header值 | 16 | 17 | ## 前置条件 18 | 19 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 20 | 21 | ## 创建 22 | 23 | ```shell 24 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 25 | "BindingObjectId": {{ 路由ID }}, 26 | "BindingObjectType": "routeRule", 27 | "GwId": {{ 网关ID }}, 28 | "PluginConfiguration": "{\"type\":\"0\",\"list\":[{\"header\":\"blackHeader\",\"match_type\":\"exact_match\",\"value\":[\"blackHeaderValue\"]}],\"kind\":\"header-restriction\"}", 29 | "PluginType": "header-restriction" 30 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 31 | ``` 32 | 33 | ## 测试 34 | 35 | ```shell 36 | ## 修改如下请求的Header参数,与插件配置的一致,测试Header黑白名单效果 37 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" -H "blackHeader:blackHeaderValue" 38 | ``` 39 | 40 | ## 删除 41 | 42 | ```shell 43 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 44 | ``` 45 | 46 | ## 界面配置方法 47 | 48 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/img/plugin_readme_entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/docs/plugin/img/plugin_readme_entry.png -------------------------------------------------------------------------------- /docs/plugin/img/plugin_readme_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/docs/plugin/img/plugin_readme_example.png -------------------------------------------------------------------------------- /docs/plugin/img/plugin_readme_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/docs/plugin/img/plugin_readme_list.png -------------------------------------------------------------------------------- /docs/plugin/img/plugin_readme_route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/docs/plugin/img/plugin_readme_route.png -------------------------------------------------------------------------------- /docs/plugin/img/plugin_readme_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/docs/plugin/img/plugin_readme_success.png -------------------------------------------------------------------------------- /docs/plugin/ip-restriction.md: -------------------------------------------------------------------------------- 1 | # IP黑白名单 2 | 3 | ## 描述 4 | 5 | `ip-restriction`插件可以针对来源于不同User-Agent(用户代理)的请求进行黑名单或白名单限制 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |------|----------|-----|----------------|--------------------------| 11 | | kind | string | 是 | ip-restriction | 插件类型(值固定) | 12 | | type | integer | 是 | [0, 1] | IP黑白名单策略
0:黑名单;1:白名单 | 13 | | list | []string | 是 | IP格式 | IP值 | 14 | 15 | 16 | ## 前置条件 17 | 18 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 19 | 20 | ## 创建 21 | 22 | ```shell 23 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 24 | "BindingObjectId": {{ 路由ID }}, 25 | "BindingObjectType": "routeRule", 26 | "GwId": {{ 网关ID }}, 27 | "PluginConfiguration": "{\"type\":\"0\",\"list\":[\"192.168.2.101\",\"192.168.2.102\"],\"kind\":\"ip-restriction\"}", 28 | "PluginType": "ip-restriction" 29 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 30 | ``` 31 | 32 | ## 测试 33 | 34 | ```shell 35 | ## 基于如下请求,基于不同IP(携带请求头X-Forwarded-For)来源请求网关测试IP黑白名单插件 36 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" 37 | ``` 38 | 39 | ## 删除 40 | 41 | ```shell 42 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 43 | ``` 44 | 45 | ## 界面配置方法 46 | 47 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/local-limiting.md: -------------------------------------------------------------------------------- 1 | # 本地限流 2 | 3 | ## 描述 4 | 5 | `local-limiting`插件可以实现基于网关实例级别的多维度流量 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |--------------------------------------|---------|-----|---------------------------------------------------|----------------| 11 | | kind | string | 是 | local-limiting | 插件类型(值固定) | 12 | | limit_by_list[].headers[].headerKey | string | 否 | length <= 200 | 限流匹配Header名 | 13 | | limit_by_list[].headers[].match_type | string | 是 | exact_match
prefix_match
safe_regex_match | 限流请求Header匹配方式 | 14 | | limit_by_list[].headers[].value | string | 是 | length <= 200 | 限流匹配Header值 | 15 | | limit_by_list[].day | integer | 是 | \> 0 | 天维度允许通过的请求数量 | 16 | | limit_by_list[].hour | integer | 是 | \> 0 | 时维度允许通过的请求数量 | 17 | | limit_by_list[].minute | integer | 是 | \> 0 | 分维度允许通过的请求数量 | 18 | | limit_by_list[].second | integer | 是 | \> 0 | 秒维度允许通过的请求数量 | 19 | 20 | ## 前置条件 21 | 22 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 23 | 24 | ## 创建 25 | 26 | ```shell 27 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 28 | "BindingObjectId": {{ 路由ID }}, 29 | "BindingObjectType": "routeRule", 30 | "GwId": {{ 网关ID }}, 31 | "PluginConfiguration": "{\"limit_by_list\":[{\"headers\":[{\"headerKey\":\"limitHeader\",\"match_type\":\"exact_match\",\"value\":\"limitHeaderValue\"}],\"day\":4321,\"hour\":321,\"minute\":21,\"second\":1}],\"kind\":\"local-limiting\",\"name\":\"local-limiting\"}", 32 | "PluginType": "local-limiting" 33 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 34 | ``` 35 | 36 | ## 测试 37 | 38 | ```shell 39 | ## 如下命令展示了用命令调用3次请求的案例,可修改for中的请求次数,进行限流次数测试;可以为请求添加header进行限流请头求匹配测试 40 | for((i=0;i<3;i++));do curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" -H "blackHeader:blackHeaderValue";done 41 | ``` 42 | 43 | ## 删除 44 | 45 | ```shell 46 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 47 | ``` 48 | 49 | ## 界面配置方法 50 | 51 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/percent-limit.md: -------------------------------------------------------------------------------- 1 | # 百分比限流 2 | 3 | ## 描述 4 | 5 | `percent-limit`插件可以对网关流量基于百分比粒度进行限流 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |---------------|---------|-----|---------------|------------| 11 | | kind | string | 是 | percent-limit | 插件类型(值固定) | 12 | | limit_percent | integer | 是 | [0, 100] | 允许通过流量的百分比 | 13 | 14 | 15 | ## 前置条件 16 | 17 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 18 | 19 | ## 创建 20 | 21 | ```shell 22 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 23 | "BindingObjectId": {{ 路由ID }}, 24 | "BindingObjectType": "routeRule", 25 | "GwId": {{ 网关ID }}, 26 | "PluginConfiguration": "{\"limit_percent\":\"50\",\"kind\":\"percent-limit\"}", 27 | "PluginType": "percent-limit" 28 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 29 | ``` 30 | 31 | ## 测试 32 | 33 | ```shell 34 | ## 通过脚本多次调用以下curl命令,测试网关百分比限流效果 35 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" 36 | ``` 37 | 38 | ## 删除 39 | 40 | ```shell 41 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 42 | ``` 43 | 44 | ## 界面配置方法 45 | 46 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/plugin-configuring-guide.md: -------------------------------------------------------------------------------- 1 | # 插件配置方法 2 | 3 | 1.通过Hango主页左侧Tab栏中的`插件管理`进入插件配置主页 4 | 5 | ![plugin_entry](img/plugin_readme_entry.png) 6 | 7 | 2.点击`+`符号添加插件,选择指定的路由为其配置某款插件 8 | 9 | ![plugin_route.png](img/plugin_readme_route.png) 10 | 11 | 3.选择路由后界面将展示可配置的插件列表 12 | 13 | ![plugin_list](img/plugin_readme_list.png) 14 | 15 | 4.选择需要配置的插件后将展示该插件的具体配置页面(案例为百分比限流插件),正确配置后点击`确认`按钮即可完成插件配置 16 | 17 | ![plugin_example.png](img/plugin_readme_example.png) 18 | 19 | 5.完成插件配置后,插件界面将展示插件信息及其相关操作,后续可以通过`操作栏`对该插件进行`更新`或`删除` 20 | 21 | ![plugin_success.png](img/plugin_readme_success.png) -------------------------------------------------------------------------------- /docs/plugin/referer-restriction.md: -------------------------------------------------------------------------------- 1 | # Referer黑白名单 2 | 3 | ## 描述 4 | 5 | `referer-restriction`插件可以基于请头头Referer来针对来源的请求进行黑名单或白名单限制 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |-------------------|---------|-----|---------------------------------------------------|--------------------------| 11 | | kind | string | 是 | referer-restriction | 插件类型(值固定) | 12 | | type | integer | 是 | [0, 1] | Referer黑白名单策略
0:黑名单;1:白名单 | 13 | | list[].match_type | string | 是 | exact_match
prefix_match
safe_regex_match | Referer黑白名单策略 | 14 | | list[].value | string | 是 | length <= 200 | Referer值 | 15 | 16 | 17 | ## 前置条件 18 | 19 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 20 | 21 | ## 创建 22 | 23 | ```shell 24 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 25 | "BindingObjectId": {{ 路由ID }}, 26 | "BindingObjectType": "routeRule", 27 | "GwId": {{ 网关ID }}, 28 | "PluginConfiguration": "{\"type\":\"0\",\"list\":[{\"match_type\":\"exact_match\",\"value\":[\"deny\"]}],\"kind\":\"referer-restriction\"}", 29 | "PluginType": "referer-restriction" 30 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 31 | ``` 32 | 33 | ## 测试 34 | 35 | ```shell 36 | ## 修改如下请求的Referer参数,与插件配置的Referer值一致,测试黑白名单效果 37 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" -H "Referer:xxx" 38 | ``` 39 | 40 | ## 删除 41 | 42 | ```shell 43 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 44 | ``` 45 | 46 | ## 界面配置方法 47 | 48 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/response-header-rewrite.md: -------------------------------------------------------------------------------- 1 | # 响应头部重写 2 | 3 | ## 描述 4 | 5 | `response-header-rewrite`插件对请求的响应头进行变更,包括新增、删除和修改操作 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 默认值 | 范围 | 描述 | 10 | |----------------------|--------|-----|--------|------------------------------|--------------| 11 | | header[].headerKey | string | 是 | - | length <= 200 | 需要操作的响应头名称 | 12 | | header[].operation | string | 是 | create | create
update
delete | 对响应的的操作类型 | 13 | | header[].headerValue | string | 是 | - | length <= 200 | 对于响应头新增或修改的值 | 14 | 15 | 16 | ## 前置条件 17 | 18 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 19 | 20 | ## 创建 21 | 22 | ```shell 23 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 24 | "BindingObjectId": {{ 路由ID }}, 25 | "BindingObjectType": "routeRule", 26 | "GwId": {{ 网关ID }}, 27 | "PluginConfiguration": "{\"header\":[\"headerKey\": \"testHeader\",\"operation\": \"update\",\"headerValue\": \"testHeaderValue\"]}", 28 | "PluginType": "response-header-rewrite" 29 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 30 | ``` 31 | 32 | ## 测试 33 | 34 | ```shell 35 | ## 基于如下基础curl命令,根据后端服务要求将请求具体化,观察响应中的头变化是否符合插件配置的预期(响应头是否新增、被修改或删除) 36 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" 37 | ``` 38 | 39 | ## 删除 40 | 41 | ```shell 42 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 43 | ``` 44 | 45 | ## 界面配置方法 46 | 47 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/static-downgrade.md: -------------------------------------------------------------------------------- 1 | # 静态降级 2 | 3 | ## 描述 4 | 5 | `static-downgrade`插件可匹配指定的请求进行降级,返回指定的响应内容 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |-----------------------------------------|----------|-----|--------------------------------------------------------------------------------------|--------------| 11 | | kind | string | 是 | static-downgrade | 插件类型(值固定) | 12 | | condition.request.requestSwitch | boolean | 是 | - | 是否使用请求进行匹配 | 13 | | condition.request.method | []string | 否 | GET
POST
PUT
DELETE
OPTIONS
HEAD
TRACE
CONNECT
PATCH | HTTP的请求方法类型 | 14 | | condition.request.path.match_type | string | 否 | exact_match
safe_regex_match | 请求路径匹配方式 | 15 | | condition.request.path.value | string | 否 | - | 请求路径匹配内容 | 16 | | condition.request.host.match_type | string | 否 | exact_match
safe_regex_match | 请求域名匹配方式 | 17 | | condition.request.host.value | string | 否 | - | 请求域名匹配内容 | 18 | | condition.request.headers[].headerKey | string | 否 | - | 请求头匹配名称 | 19 | | condition.request.headers[].match_type | string | 否 | exact_match
safe_regex_match | 请求头匹配匹配方式 | 20 | | condition.request.headers[].value | string | 否 | - | 请求头匹配匹配内容 | 21 | | condition.response.code.match_type | string | 是 | exact_match
safe_regex_match | 响应状态码匹配方式 | 22 | | condition.response.code.value | integer | 是 | [200, 599] | 响应状态码匹配内容 | 23 | | condition.response.headers[].headerKey | string | 否 | - | 响应头匹配名称 | 24 | | condition.response.headers[].match_type | string | 否 | exact_match
safe_regex_match | 响应头匹配方式 | 25 | | condition.response.headers[].value | string | 否 | - | 响应头匹配内容 | 26 | | response.code | integer | 是 | [200, 599] | 降级后返回的状态码 | 27 | | response.headers[key] | string | 是 | - | 降级后返回的响应头 | 28 | | response.headers[value] | string | 是 | - | 降级后返回的响应头对应值 | 29 | | response.body | string | 否 | - | 降级后返回的body内容 | 30 | 31 | 32 | ## 前置条件 33 | 34 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 35 | 36 | ## 创建 37 | 38 | ```shell 39 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 40 | "BindingObjectId": {{ 路由ID }}, 41 | "BindingObjectType": "routeRule", 42 | "GwId": {{ 网关ID }}, 43 | "PluginConfiguration": "{\"condition\":{\"request\":{\"requestSwitch\":true,\"method\":[\"GET\",\"POST\"],\"path\":{\"match_type\":\"exact_match\",\"value\":\"/rootpath/subpath\"},\"headers\":[{\"headerKey\":\"reqHeader\",\"match_type\":\"exact_match\",\"value\":\"reqHeaderValue\"}]},\"response\":{\"code\":{\"match_type\":\"safe_regex_match\",\"value\":\"503\"},\"headers\":[{\"headerKey\":\"rspHeader\",\"match_type\":\"exact_match\",\"value\":\"rspHeaderValue\"}]}},\"kind\":\"static-downgrade\",\"response\":{\"headers\":{\"downgradeHeader\":\"downgradeHeaderValue\"},\"code\":\"200\",\"body\":\"Test Response Context\"}}", 44 | "PluginType": "static-downgrade" 45 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 46 | ``` 47 | 48 | ## 测试 49 | 50 | ```shell 51 | ## 基于如下基本的curl命令,添加插件中配置的请求头、响应头等降级条件,测试是否返回配置的响应内容(响应码、响应头和响应体) 52 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" 53 | 54 | ## 例如,插件中配置了降级条件配置了一个响应头为"reqHeader: reqHeaderValue",则需要构造如下请求进行测试 55 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" -H "reqHeader:reqHeaderValue" 56 | ``` 57 | 58 | ## 删除 59 | 60 | ```shell 61 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 62 | ``` 63 | 64 | ## 界面配置方法 65 | 66 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/ua-restriction.md: -------------------------------------------------------------------------------- 1 | # UA黑白名单 2 | 3 | ## 描述 4 | 5 | `ua-restriction`插件可以针对来源于不同User-Agent(用户代理)的请求进行黑名单或白名单限制 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |-------------------|---------|-----|---------------------------------------------------|--------------------------| 11 | | kind | string | 是 | ua-restriction | 插件类型(值固定) | 12 | | type | integer | 是 | [0, 1] | UA黑白名单策略
0:黑名单;1:白名单 | 13 | | list[].match_type | string | 是 | exact_match
prefix_match
safe_regex_match | UA黑白名单策略 | 14 | | list[].value | string | 是 | length <= 200 | User-Agent值 | 15 | 16 | 17 | ## 前置条件 18 | 19 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 20 | 21 | ## 创建 22 | 23 | ```shell 24 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 25 | "BindingObjectId": {{ 路由ID }}, 26 | "BindingObjectType": "routeRule", 27 | "GwId": {{ 网关ID }}, 28 | "PluginConfiguration": "{\"type\":\"0\",\"list\":[{\"match_type\":\"exact_match\",\"value\":[\"testUA\"]}],\"kind\":\"ua-restriction\"}", 29 | "PluginType": "ua-restriction" 30 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 31 | ``` 32 | 33 | ## 测试 34 | 35 | ```shell 36 | ## 修改如下请求的User-Agent参数,与插件配置的UA值一致,测试黑白名单效果 37 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" -H "User-Agent:xxx" 38 | ``` 39 | 40 | ## 删除 41 | 42 | ```shell 43 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 44 | ``` 45 | 46 | ## 界面配置方法 47 | 48 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/plugin/uri-restriction.md: -------------------------------------------------------------------------------- 1 | # URI黑白名单 2 | 3 | ## 描述 4 | 5 | `uri-restriction`是hango的一款rider插件(用户可基于hango的rider开发手册开发自己的rider插件),该插件可以基于请求的path进行黑白名单限制 6 | 7 | ## 属性 8 | 9 | | 名称 | 类型 | 必选项 | 范围 | 描述 | 10 | |------------------|----------|-----|-----------------|-------------| 11 | | kind | string | 是 | uri-restriction | 插件类型(值固定) | 12 | | type | string | 是 | lua | 插件技术实现(值固定) | 13 | | config.allowlist | []string | 否 | length <= 200 | 白名单path | 14 | | config.denylist | []string | 否 | length <= 200 | 黑名单path | 15 | 16 | 17 | ## 前置条件 18 | 19 | 以下curl命令中存在变量,使用前需要替换为真实环境数据,变量以`{{}}`符号包裹,例如`{{ 网关ID }}`需要根据网关的实际ID进行替换;创建插件命令中`PluginConfiguration`(插件配置)需要根据实际需要进行配置 20 | 21 | ## 创建 22 | 23 | ```shell 24 | curl -XPOST -v -H "Content-Type:application/json" -d '{ 25 | "BindingObjectId": {{ 路由ID }}, 26 | "BindingObjectType": "routeRule", 27 | "GwId": {{ 网关ID }}, 28 | "PluginConfiguration": "{\"kind\":\"uri-restriction\",\"type\":\"lua\",\"config\":{\"allowlist\":[\"/test/blank\"],\"denylist\":[\"/test/black\"]}}", 29 | "PluginType": "uri-restriction" 30 | }' http://{{ hango-portal ip:port }}/gdashboard?Action=BindingPlugin&Version=2019-09-01 31 | ``` 32 | 33 | ## 测试 34 | 35 | ```shell 36 | ## 修改如下请求的{{ 路由path }},配置为插件中的黑名单或白名单,观察请求被拦截或放行 37 | curl -v "http://{{ 网关IP }}/{{ 路由path }}" -H "host:{{ 网关关联域名 }}" 38 | ``` 39 | 40 | ## 删除 41 | 42 | ```shell 43 | curl -v -H "Content-Type:application/json" http://{{ hango-portal ip:port }}/gdashboard?PluginBindingInfoId={{ 插件ID }}&Action=UnbindingPlugin&Version=2019-09-01 44 | ``` 45 | 46 | ## 界面配置方法 47 | 48 | [插件界面配置方法引导](plugin-configuring-guide.md) -------------------------------------------------------------------------------- /docs/troubleshooting/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting Guide -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | [//]:#(TODO) 2 | # Example -------------------------------------------------------------------------------- /example/expose_api.md: -------------------------------------------------------------------------------- 1 | # Expose route to hango 2 | 3 | For the purpose of this example, you'll create service and route to e2e. Then, publish service and route to hango gateway. 4 | Use hango gateway route to e2e service. 5 | 6 | ## Add Service 7 | 8 | Hango Gateway exposes hango-gateway-portal to users. You can use hango-gateway-portal api to add a service. For example, add a service which name is hango-test. 9 | 10 | ```shell 11 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=CreateService&Version=2018-08-09" \ 12 | -H 'Content-Type: application/json' \ 13 | -d '{ 14 | "ServiceType":"http", 15 | "ServiceName":"hango-test", 16 | "ServiceTag":"hango-test", 17 | "Contacts":"admin" 18 | }' 19 | ``` 20 | 21 | ## Add Route 22 | 23 | You can use hango-gateway-portal api to add a route. For example, add a route named hango-route-test, and the uri is prefix: /hango/unit 24 | 25 | ```shell 26 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=CreateRouteRule&Version=2019-09-01" \ 27 | -H 'Content-Type: application/json' \ 28 | -d '{ 29 | "RouteRuleName":"hango-route-test", 30 | "Uri":{ 31 | "Type":"prefix", 32 | "Value":[ 33 | "/hango/unit" 34 | ] 35 | }, 36 | "ServiceId": service_id 37 | }' 38 | ``` 39 | 40 | ## Publish Service 41 | 42 | You can use hango-gateway-portal api to publish service. You need to declare registry-center-type and backend application. For example, publish hango-test service to istio-e2e-app.hango-system.svc.cluster.local in kubernetes registry. 43 | 44 | ```shell 45 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=PublishService&Version=2019-09-01" \ 46 | -H 'Content-Type: application/json' \ 47 | -d '{ 48 | "GwId": gw_id, 49 | "ServiceId":service_id, 50 | "PublishType":"DYNAMIC", 51 | "BackendService": "istio-e2e-app.hango-system.svc.cluster.local", 52 | "PublishProtocol":"http", 53 | "RegistryCenterType":"Kubernetes", 54 | }' 55 | ``` 56 | 57 | ## Publish Route 58 | 59 | You can use hango-gateway-portal api to publish route to hango gateway. Once publish route, you can call the e2e api through hango gateway. You should declare service port for publishing. For example, publish route with 80 port. 60 | 61 | ```shell 62 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=PublishRouteRule&Version=2019-09-01" \ 63 | -H 'Content-Type: application/json' \ 64 | -d '{ 65 | "GwId": gw_id, 66 | "RouteRuleId": route_id, 67 | "DestinationServices":[ 68 | { 69 | "Port":"80", 70 | "Weight":100, 71 | "ServiceId":service_id 72 | } 73 | ], 74 | }' 75 | ``` 76 | 77 | ## Verify the Route 78 | 79 | You can use curl to verify the route. For example, 80 | 81 | ```shell 82 | curl "http://hango.io.proxy/hango/unit" -H "host:istio.com" 83 | ``` 84 | 85 | response 86 | 87 | ```shell 88 | HTTP/1.1 200 OK 89 | date: Thu, 15 Apr 2021 08:53:20 GMT 90 | content-length: 719 91 | content-type: text/plain; charset=utf-8 92 | x-envoy-upstream-service-time: 0 93 | server: istio-envoy 94 | 95 | ServiceVersion=v1 96 | ServicePort=80 97 | Host=istio.com 98 | Method=GET 99 | URL=/hango/unit 100 | Proto=HTTP/1.1 101 | ........ 102 | ``` 103 | 104 | ## Offline and Delete Route 105 | 106 | You can use hango-gateway-portal api to offline or delete route. For example, 107 | 108 | ```shell 109 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeletePublishedRouteRule&Version=2019-09-01&RouteRuleId={route_id}&GwId={gw_id}" 110 | 111 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeleteRouteRule&Version=2019-09-01&RouteRuleId={route_id}" 112 | ``` 113 | 114 | ## Offline and Delete Service 115 | 116 | You can use hango-gateway-portal api to offline or delete service. For example, 117 | 118 | ```shell 119 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeleteServiceProxy&Version=2019-09-01&ServiceId={service_id}&GwId={gw_id}" 120 | 121 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeleteService&Version=2018-08-09&ServiceId={service_id}" 122 | ``` 123 | -------------------------------------------------------------------------------- /example/expose_api.zh_CN.md: -------------------------------------------------------------------------------- 1 | # Hango 网关路由 2 | 3 | 通过接口创建服务,路由,同时进行服务和路由发布,便捷使用Hango网关。 4 | 5 | ## 创建服务 6 | 7 | 通过创建服务接口,创建服务,例如,创建一个名为hango-test的服务。 8 | 9 | ```shell 10 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=CreateService&Version=2018-08-09" \ 11 | -H 'Content-Type: application/json' \ 12 | -d '{ 13 | "ServiceType":"http", 14 | "ServiceName":"hango-test", 15 | "ServiceTag":"hango-test", 16 | "Contacts":"admin" 17 | }' 18 | ``` 19 | 20 | ## 创建路由 21 | 22 | 通过api创建路由,路由从属于服务;例如创建一个前缀为/hango/unit的路由,hango-route-test。 23 | 24 | ```shell 25 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=CreateRouteRule&Version=2019-09-01" \ 26 | -H 'Content-Type: application/json' \ 27 | -d '{ 28 | "RouteRuleName":"hango-route-test", 29 | "Uri":{ 30 | "Type":"prefix", 31 | "Value":[ 32 | "/hango/unit" 33 | ] 34 | }, 35 | "ServiceId": service_id 36 | }' 37 | ``` 38 | 39 | ## 发布服务 40 | 41 | 声明注册类型以及后端应用进行服务发布,例如,在k8s注册中心中发布服务至应用istio-e2e-app.hango-system.svc.cluster.local。 42 | 43 | ```shell 44 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=PublishService&Version=2019-09-01" \ 45 | -H 'Content-Type: application/json' \ 46 | -d '{ 47 | "GwId": gw_id, 48 | "ServiceId":service_id, 49 | "PublishType":"DYNAMIC", 50 | "BackendService": "istio-e2e-app.hango-system.svc.cluster.local", 51 | "PublishProtocol":"http", 52 | "RegistryCenterType":"Kubernetes", 53 | }' 54 | ``` 55 | 56 | ## 发布路由 57 | 58 | 通过声明服务端口进行路由发布,一旦路由发布成功,就可以通过hango网关调用路由。例如,发布路由至服务80端口。 59 | 60 | ```shell 61 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=PublishRouteRule&Version=2019-09-01" \ 62 | -H 'Content-Type: application/json' \ 63 | -d '{ 64 | "GwId": gw_id, 65 | "RouteRuleId": route_id, 66 | "DestinationServices":[ 67 | { 68 | "Port":"80", 69 | "Weight":100, 70 | "ServiceId":service_id 71 | } 72 | ], 73 | }' 74 | ``` 75 | 76 | ## 验证路由 77 | 78 | 可以通过curl指令验证路由是否成功。 79 | 80 | ```shell 81 | curl "http://hango.io.proxy/hango/unit" -H "host:istio.com" 82 | ``` 83 | 84 | 返回 85 | 86 | ```shell 87 | HTTP/1.1 200 OK 88 | date: Thu, 15 Apr 2021 08:53:20 GMT 89 | content-length: 719 90 | content-type: text/plain; charset=utf-8 91 | x-envoy-upstream-service-time: 0 92 | server: istio-envoy 93 | 94 | ServiceVersion=v1 95 | ServicePort=80 96 | Host=istio.com 97 | Method=GET 98 | URL=/hango/unit 99 | Proto=HTTP/1.1 100 | ........ 101 | ``` 102 | 103 | ## 下线、删除路由 104 | 105 | 调用api进行路由下线及删除,例如: 106 | 107 | ```shell 108 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeletePublishedRouteRule&Version=2019-09-01&RouteRuleId={route_id}&GwId={gw_id}" 109 | 110 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeleteRouteRule&Version=2019-09-01&RouteRuleId={route_id}" 111 | ``` 112 | 113 | ## 下线、删除服务 114 | 115 | 调用api进行服务下线及删除,例如: 116 | 117 | ```shell 118 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeleteServiceProxy&Version=2019-09-01&ServiceId={service_id}&GwId={gw_id}" 119 | 120 | curl "http://hango.io.portal.org/gdashboard/envoy?Action=DeleteService&Version=2018-08-09&ServiceId={service_id}" 121 | ``` 122 | -------------------------------------------------------------------------------- /example/expose_api_with_ui.zh_CN.md: -------------------------------------------------------------------------------- 1 | # 界面化管理Hango 网关路由 2 | 3 | 通过`Hango UI`创建服务和路由,同时进行服务和路由发布,便捷使用Hango网关。 4 | 5 | ## 获取Hango UI 访问地址 6 | 通过[Hango部署手册](../install/README.zh_CN.md)完成部署,可以查看hango相关Kubernetes service信息: 7 | 8 | ```shell 9 | > kubectl get svc -n hango-system 10 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 11 | gateway-proxy NodePort 10.106.46.59 15021:32318/TCP,80:30591/TCP,443:32522/TCP 23h 12 | hango-api-plane ClusterIP 10.111.150.106 10880/TCP 23h 13 | hango-portal NodePort 10.107.179.97 80:30621/TCP 23h 14 | hango-ui NodePort 10.100.82.153 8789:30829/TCP 23h 15 | istio-e2e-app ClusterIP 10.100.15.26 80/TCP,8080/TCP,90/TCP,9090/TCP,70/TCP,7070/TCP 23h 16 | istiod ClusterIP 10.109.241.243 15010/TCP,15012/TCP,443/TCP,15014/TCP 23h 17 | plugin ClusterIP 10.96.91.4 80/TCP 23h 18 | slime-metrics ClusterIP 10.102.87.122 8383/TCP,8686/TCP 23h 19 | ``` 20 | 21 | 其中`hango-ui`是我们的目标服务,它是NodePort类型,可以通过主机IP地址+端口访问,可以在浏览器中输入如下地址,即可访问`Hango UI`: 22 | ```shell 23 | http://{{所在k8s集群的任一主机IP}}:{{NodePort端口,这里是30829}} 24 | ``` 25 | 26 | ## 创建网关 27 | 28 | 由于发布服务和路由必须先要有网关,创建网关是第一步。官方提供了一个[网关初始化脚本](../install/init-hango/init.sh),可以直接使用。通过`网关管理`页面创建网关,示例如下所示: 29 | 30 | ![hango-ui-create-gateway-form](../images/hango-ui-create-gateway-form.png) 31 | 32 | 其中: 33 | - 网关名称,即`GwName`,可自行填写,如`“hango_envoy_gateway”`; 34 | - 网关地址,即`GwAddr`,指`gateway proxy`组件的访问地址,可以填写上文的`gateway-proxy`的k8s服务地址,端口不用填默认80; 35 | - ApiPlane地址,即`ApiPlaneAddr`,指`api plane`组件的访问地址,可以填写上文的`hango-api-plane`的k8s服务地址和端口; 36 | - 网关集群名称,即`GwClusterName`,如`“demo-istio”`; 37 | - 域名列表,即`HostList`,如`“istio.com”`; 38 | - 备注信息,即`Description`,可自行填写; 39 | 40 | ## 创建服务 41 | 42 | 通过`服务管理`页面创建服务,例如,创建一个名为hango-test的服务。 43 | 44 | 1. 点击 `+`,创建一个新的服务: 45 | 46 | ![hango-ui-create-svc-click](../images/hango-ui-create-svc-click.png) 47 | 48 | 2. 输入`"服务名称"`、`"服务标识"`等信息,点击创建: 49 | 50 | ![hango-ui-create-svc-form](../images/hango-ui-create-svc-form.png) 51 | 52 | ## 创建路由 53 | 54 | 通过`路由管理`页面创建路由,路由从属于服务;例如创建一个前缀为/hango/unit的路由,hango-route-test。 55 | 56 | 1. 点击 `+`,创建一个新的路由,选择`"所属服务"`、填写`“路由名称”`,默认使用`Path`作为路由条件,输入单个或多个`"条件取值"`,点击创建: 57 | 58 | ![hango-ui-create-route-form1](../images/hango-ui-create-route-form1.png) 59 | 60 | 2. 除了默认的`Path`路由分发方式,还提供基于`Host`、`Method`、`Header`、`Query`多种方式,应对不同场景,灵活性高。 61 | 62 | ![hango-ui-create-route-form2](../images/hango-ui-create-route-form2.png) 63 | 64 | 65 | ## 发布服务 66 | 67 | 新建服务需要通过发布后,才能被访问,例如,发布刚创建的hango-test服务。 68 | 69 | 1. 通过`服务管理`页面的`发布`按钮,进行服务发布操作: 70 | 71 | ![hango-ui-publish-svc-click](../images/hango-ui-publish-svc-click.png) 72 | 73 | 2. 选择已有的`"目标网关"`,选择`"从注册中心同步"`作为发布方式,选择`"K8S注册中心"`作为注册中心,选择`"istio-e2e-app.hango-system.svc.cluster.local"`作为服务地址,点击确认: 74 | 75 | ![hango-ui-publish-svc-form](../images/hango-ui-publish-svc-form.png) 76 | 77 | 3. 服务发布成功后,可以在`"已发布服务管理"`页面查看: 78 | 79 | ![hango-ui-publish-svc-done](../images/hango-ui-publish-svc-done.png) 80 | 81 | ## 发布路由 82 | 83 | 通过声明服务端口进行路由发布,一旦路由发布成功,就可以通过hango网关调用路由。例如,发布路由至服务80端口。 84 | 85 | 1. 与服务发布类似,通过`路由管理`页面的`发布`按钮,进行路由发布操作。选择已有的`"目标网关"`后,即可自动填充相关字段,可调整端口和超时时间: 86 | 87 | ![hango-ui-publish-route-form](../images/hango-ui-publish-route-form.png) 88 | 89 | ## 验证路由 90 | 91 | 可以通过调用`gateway proxy`组件,配合路由条件,验证路由是否成功。`gateway proxy`已提供NodePort服务,验证方式如下: 92 | 93 | ```shell 94 | curl "http://{{所在k8s集群的任一主机IP}}:{{NodePort端口,这里是30591}}/hango/unit" -H "host:istio.com" 95 | ``` 96 | 97 | 返回结果: 98 | 99 | ```shell 100 | ServiceVersion=v1 101 | ServicePort=80 102 | Host=istio.com 103 | Method=GET 104 | URL=/hango/unit 105 | Proto=HTTP/1.1 106 | RemoteAddr=10.0.0.192:59042 107 | Method=GET 108 | X-B3-Traceid=6cde016d694758c06f082afb06e746a9 109 | Accept=*/* 110 | X-Request-Id=0c254c7f-cade-46e5-ac98-0d8964198bab 111 | X-Envoy-Decorator-Operation=istio-e2e-app.hango-system.svc.cluster.local:80/hango/unit.* 112 | X-Envoy-Expected-Rq-Timeout-Ms=60000 113 | X-B3-Sampled=0 114 | User-Agent=curl/7.68.0 115 | X-Forwarded-For=xx.xx.xx.xx 116 | X-Envoy-External-Address=xx.xx.xx.xx 117 | Content-Length=0 118 | X-Forwarded-Proto=http 119 | X-Envoy-Attempt-Count=1 120 | X-B3-Spanid=6f082afb06e746a9 121 | Hostname=istio-e2e-app-85bb49bf75-crlhm 122 | ``` 123 | 124 | -------------------------------------------------------------------------------- /example/plugin_template_support_guide.md: -------------------------------------------------------------------------------- 1 | # 插件模板配置说明 2 | 可以通过修改配置文件控制插件的展示 3 | 4 | ## 控制插件开关 5 | 在名为hango-api-plane-config的ConfigMap中找到 ```pluginmanager-template.json```配置,该配置是插件的模板来源,可以通过```enable```调整插件的开关。例如: 6 | ```yaml 7 | { 8 | "enable": "true", 9 | "name": "envoy.filters.http.fault" 10 | } 11 | ``` 12 | 名为```envoy.filters.http.fault```的插件将会被开启。 13 | 目前支持的插件有如下: 14 | * proxy.filters.http.metadatahub:插件元数据 15 | * envoy.filters.http.fault:百分比限流 16 | * envoy.filters.http.local_ratelimit:本地限流 17 | * proxy.filters.http.iprestriction:IP黑白名单 18 | * proxy.filters.http.ua_restriction:UA黑白名单 19 | * proxy.filters.http.referer_restriction:Restriction黑白名单 20 | * proxy.filters.http.header_restriction:Header黑白名单 21 | * proxy.filters.http.header_rewrite:响应头重写 22 | * proxy.filters.http.staticdowngrade:静态降级 23 | * proxy.filters.http.circuitbreaker:熔断 24 | * proxy.filters.http.waf:Web应用程序防火墙 25 | * proxy.filters.http.rider:lua扩展 26 | ## 控制插件显示 27 | 在名为hango-api-plane-config的ConfigMap中找到```plugin-support-config.json```配置,其功能是配置不同类型的虚拟网关所支持的插件列表展示。```display```设置为```false```的插件将不会再前端页面展示。 -------------------------------------------------------------------------------- /example/rider_user_guide.md: -------------------------------------------------------------------------------- 1 | # Hango Gateway Custom Plug-in Use Tutorial 2 | 3 | ## 一、Requirement 4 | 5 | Implement an uri black and white list plug-in. Support console configuration uri blacklist/whitelist. 6 | 7 | ## 二、Write plug-ins and debug them 8 | 9 | ### 2.1 The development of rider 10 | 11 | Rider is an open source custom plug-in package of the hango team. It dynamically expands custom plug-ins through the combination of rider and envoy's hot-loading capabilities. 12 | 13 | (1)2.1.1 Set up the plugins/uri-restriction.lua file under the Rider root to store the plug-in code 14 | 15 | Create plugins/uri-restriction.lua and add the following code. 16 | 17 | It consists of two parts: plug-in schema configuration and plug-in execution logic configuration; Schema configuration can be divided into base_json_schema global configuration and route_json_schema routing configuration. Global configuration is used to configure the common configuration of the plug-in, such as the global configuration of external authentication services; Routing configuration is the core configuration of the plug-in, and most scenarios only need to write route_json_schema. 18 | 19 | The plug-in executes logic and relies on the SDK encapsulated by Rider to develop the corresponding plug-in link. If the characters in the request URI match the black-and-white list rule, the request is allowed. If the characters in the request URI do not match the black-and-white list rule and match the black-and-white list rule, the 403 error code and the corresponding "Forbidden" is returned 20 | 21 | ```lua 22 | --[[ 23 | V2 Rider version was introduced; 24 | Compared with V1, v2 divides request and response into header and body parts to improve plugin performance in different scenarios 25 | -- ]] 26 | require('rider.v2') 27 | 28 | -- Defining local variables 29 | local envoy = envoy 30 | local request = envoy.req 31 | local respond = envoy.respond 32 | 33 | -- Define local constants 34 | local NO_MATCH = 0 35 | local MATCH_WHITELIST = 1 36 | local MATCH_BLACKLIST = 2 37 | local BAD_REQUEST = 400 38 | local FORBIDDEN = 403 39 | 40 | local uriRestrictionHandler = {} 41 | 42 | uriRestrictionHandler.version = 'v2' 43 | 44 | local json_validator = require('rider.json_validator') 45 | 46 | -- Define the global configuration 47 | local base_json_schema = { 48 | type = 'object', 49 | properties = {} 50 | } 51 | 52 | -- Define the route configuration 53 | local route_json_schema = { 54 | type = 'object', 55 | properties = { 56 | allowlist = { 57 | type = 'array', 58 | items = { 59 | type = 'string' 60 | } 61 | }, 62 | denylist = { 63 | type = 'array', 64 | items = { 65 | type = 'string' 66 | } 67 | } 68 | } 69 | } 70 | 71 | json_validator.register_validator(base_json_schema, route_json_schema) 72 | 73 | -- Define the local validation URI white-and-black list method 74 | local function checkUriPath(uriPath, allowlist, denylist) 75 | if allowlist then 76 | for _, rule in ipairs(allowlist) do 77 | envoy.logDebug('allowist: compare ' .. rule .. ' and ' .. uriPath) 78 | if string.find(uriPath, rule) then 79 | return MATCH_WHITELIST 80 | end 81 | end 82 | end 83 | 84 | if denylist then 85 | for _, rule in ipairs(denylist) do 86 | envoy.logDebug('denylist: compare ' .. rule .. ' and ' .. uriPath) 87 | if string.find(uriPath, rule) then 88 | return MATCH_BLACKLIST 89 | end 90 | end 91 | end 92 | 93 | return NO_MATCH 94 | end 95 | 96 | -- Define the header stage handler for the request 97 | function uriRestrictionHandler:on_request_header() 98 | local uriPath = request.get_header(':path') 99 | local config = envoy.get_route_config() 100 | 101 | envoy.logInfo('start lua uriRestriction') 102 | if uriPath == nil then 103 | envoy.logErr('no uri path!') 104 | return 105 | end 106 | 107 | -- 'nil' indicates that the route configuration does not exist (route plugin is not configured) 108 | if config == nil then 109 | return 110 | end 111 | 112 | local match = checkUriPath(uriPath, config.allowlist, config.denylist) 113 | 114 | envoy.logDebug('on_request_header, uri path: ' .. uriPath .. ', match result: ' .. match) 115 | 116 | if match > 1 then 117 | envoy.logDebug('path is now allowed: ' .. uriPath) 118 | return respond({[':status'] = FORBIDDEN}, 'Forbidden') 119 | end 120 | end 121 | 122 | return uriRestrictionHandler 123 | ``` 124 | 125 | ### 2.2 The debugging of rider 126 | 127 | Update the script/dev/envoy.yaml file to add the corresponding http_filter configuration as follows; 128 | 129 | ```yaml 130 | - name: proxy.filters.http.rider 131 | typed_config: 132 | "@type": type.googleapis.com/proxy.filters.http.rider.v3alpha1.FilterConfig 133 | plugin: 134 | vm_config: 135 | package_path: "/usr/local/lib/rider/?/init.lua;/usr/local/lib/rider/?.lua;" 136 | code: 137 | local: 138 | filename: /usr/local/lib/rider/plugins/uri-restriction.lua 139 | name: uri-restriction.lua 140 | config: {} 141 | ``` 142 | 143 | Add the corresponding Route configuration, as follows; 144 | 145 | ```yaml 146 | typed_per_filter_config: 147 | proxy.filters.http.rider: 148 | "@type": type.googleapis.com/proxy.filters.http.rider.v3alpha1.RouteFilterConfig 149 | plugins: 150 | - name: uri-restriction 151 | config: 152 | allowlist: 153 | - a1 154 | denylist: 155 | - d1 156 | ``` 157 | 158 | Execute './scripts/dev/local-up.sh 'to start hango-gateway and a simple HTTP service. 159 | 160 | `curl -v http://localhost:8002/static-to-header` 161 | 162 | ![image-20210416173118827](../images/rider_uri_restriction_test_ok.png) 163 | 164 | response: `403 Foebidden` 165 | 166 | ### 2.3 The development of console schem 167 | 168 | Developing the corresponding plug-in schema, the plug-in can be exposed to the gateway console for easy user configuration. 169 | 170 | Expose the corresponding uri-restriction plug-in to the Hango console by writing a JSON schema. 171 | 172 | According to the requirements, the development of uri-restriction front-end schema is as follows; 173 | 174 | ```json 175 | { 176 | "formatter": { 177 | "kind": "uri-restriction", 178 | "type": "lua", 179 | "config": { 180 | "allowlist": "&allowlist", 181 | "denylist": "&denylist" 182 | } 183 | }, 184 | "layouts": [ 185 | { 186 | "key": "allowlist", 187 | "alias": "白名单", 188 | "help": "URI优先匹配白名单,命中之后直接放行,支持正则", 189 | "type": "multi_input", 190 | "rules": [ 191 | ] 192 | }, 193 | { 194 | "key": "denylist", 195 | "alias": "黑名单", 196 | "help": "URI优先匹配白名单,没有命中,继续匹配黑名单,命中之后直接禁止,支持正则", 197 | "type": "multi_input", 198 | "rules": [ 199 | ] 200 | } 201 | ] 202 | } 203 | ``` 204 | 205 | ## 三、Integrate plug-ins into Hango 206 | 207 | ### 3.1 Integrate plug-in to hango-envoy 208 | 209 | (1)In the rider directory, execute 210 | 211 | ```yaml 212 | kubectl create configmap hango-rider-plugin --from-file=plugins/ -n hango-system 213 | ``` 214 | 215 | (2)Wait for about 10 seconds, and load the corresponding plugins into hango-gateway 216 | 217 | ### 3.2 Integrate plug-in to api-palne 218 | 219 | (1)Clarify the level of the plugin 220 | 221 | The hango gateway custom plug-in supports two levels: the global level and the routing level; the global level is the entire gateway level, and the effective order is the priority routing level plug-in to take effect. 222 | 223 | The global configuration entry is: [Plugin Management] -> [Add Global Plug-in]. After configuring a global plug-in, all routes of the gateway are effective. 224 | 225 | The routing level configuration entry is: [Released information] -> [Released routing] -> [Plugins] -> [Add global plugins]. After configuring a route-level plug-in, it will only take effect for the current route. 226 | 227 | (2)Update the plugin-config.json in the api-plane project /plugin/route directory to add the corresponding plug-in declaration 228 | 229 | ```json 230 | { 231 | "name": "uri-restriction", 232 | "displayName": "URI黑白名单", 233 | "schema": "plugin/route/uri-restriction.json", 234 | "description": "URI黑白名单插件", 235 | "processor": "AggregateGatewayPluginProcessor", 236 | "author": "system", 237 | "createTime": "1655279630000", 238 | "updateTime": "1655279630000", 239 | "pluginScope": "global,routeRule", 240 | "pluginPriority": "3000", 241 | "instructionForUse": "URI黑白名单插件", 242 | "categoryKey": "security", 243 | "categoryName": "安全" 244 | } 245 | ``` 246 | 247 | (3) Add the uri-restriction.json schema file in the /plugin/route directory 248 | 249 | ```json 250 | ---uri-restriction.json 251 | { 252 | "formatter": { 253 | "kind": "uri-restriction", 254 | "type": "lua", 255 | "config": { 256 | "allowlist": "&allowlist", 257 | "denylist": "&denylist" 258 | } 259 | }, 260 | "layouts": [ 261 | { 262 | "key": "allowlist", 263 | "alias": "白名单", 264 | "help": "URI优先匹配白名单,命中之后直接放行,支持正则", 265 | "type": "multi_input", 266 | "rules": [ 267 | ] 268 | }, 269 | { 270 | "key": "denylist", 271 | "alias": "黑名单", 272 | "help": "URI优先匹配白名单,没有命中,继续匹配黑名单,命中之后直接禁止,支持正则", 273 | "type": "multi_input", 274 | "rules": [ 275 | ] 276 | } 277 | ] 278 | } 279 | ``` 280 | 281 | (4) Execute the following instructions to generate the corresponding plug-in configmap. 282 | 283 | ```shell 284 | kubectl create configmap hango-plugin --from-file=plugin/route/ -n hango-system 285 | ``` 286 | 287 | (5) Wait for about 10s, after the configmap is loaded successfully, you can use the custom plug-in. 288 | -------------------------------------------------------------------------------- /example/rider_user_guide.zh_CN.md: -------------------------------------------------------------------------------- 1 | # Hango网关自定义插件使用教程 2 | 3 | ## 一、插件需求 4 | 5 | 实现一个URI黑白名单插件。支持控制台配置URI黑名单/白名单。 6 | 7 | ## 二、编写lua插件、调试 8 | 9 | ### 2.1 rider开发 10 | 11 | rider是hango团队开源的自定义插件包,通过rider结合envoy热加载能力,动态扩展自定义插件。 12 | 13 | (1)2.1.1 在rider根目录下,建立plugins/uri-restriction.lua 目录用于存放插件代码 14 | 15 | 创建plugins/uri-restriction.lua,添加如下代码 16 | 17 | 包括两部分:插件schema配置以及插件执行逻辑配置;schema配置又可以分为base_json_schema全局配置以及route_json_schema路由配置。全局配置用于配置插件的公共配置,例如外部认证服务等全局配置;路由配置为插件的核心配置,大多数场景只需要编写route_json_schema即可。 18 | 19 | 插件执行逻辑,依赖rider封装的sdk,进行对应的插件链路开发。我们的例子便是,对请求URI进行黑白名单控制;当请求URI中的字符符合白名单规则,优先放行;若请求URI中的字符未匹配白名单规则且匹配黑名单规则,则请求返回403错误码,并相应Forbidden字符串 20 | 21 | ```lua 22 | --[[ 23 | 引入v2 rider版本 24 | v2版本相对v1版本将request和response分为header和body部分处理,提升不同场景的插件性能 25 | -- ]] 26 | require('rider.v2') 27 | 28 | -- 定义本地变量 29 | local envoy = envoy 30 | local request = envoy.req 31 | local respond = envoy.respond 32 | 33 | -- 定义本地常量 34 | local NO_MATCH = 0 35 | local MATCH_WHITELIST = 1 36 | local MATCH_BLACKLIST = 2 37 | local BAD_REQUEST = 400 38 | local FORBIDDEN = 403 39 | 40 | local uriRestrictionHandler = {} 41 | 42 | uriRestrictionHandler.version = 'v2' 43 | 44 | local json_validator = require('rider.json_validator') 45 | 46 | -- 定义全局配置 47 | local base_json_schema = { 48 | type = 'object', 49 | properties = {} 50 | } 51 | 52 | -- 定义路由级配置 53 | local route_json_schema = { 54 | type = 'object', 55 | properties = { 56 | allowlist = { 57 | type = 'array', 58 | items = { 59 | type = 'string' 60 | } 61 | }, 62 | denylist = { 63 | type = 'array', 64 | items = { 65 | type = 'string' 66 | } 67 | } 68 | } 69 | } 70 | 71 | json_validator.register_validator(base_json_schema, route_json_schema) 72 | 73 | -- 定义本地校验uri黑白名单方法 74 | local function checkUriPath(uriPath, allowlist, denylist) 75 | if allowlist then 76 | for _, rule in ipairs(allowlist) do 77 | envoy.logDebug('allowist: compare ' .. rule .. ' and ' .. uriPath) 78 | if string.find(uriPath, rule) then 79 | return MATCH_WHITELIST 80 | end 81 | end 82 | end 83 | 84 | if denylist then 85 | for _, rule in ipairs(denylist) do 86 | envoy.logDebug('denylist: compare ' .. rule .. ' and ' .. uriPath) 87 | if string.find(uriPath, rule) then 88 | return MATCH_BLACKLIST 89 | end 90 | end 91 | end 92 | 93 | return NO_MATCH 94 | end 95 | 96 | -- 定义request的header阶段处理函数 97 | function uriRestrictionHandler:on_request_header() 98 | local uriPath = request.get_header(':path') 99 | local config = envoy.get_route_config() 100 | 101 | envoy.logInfo('start lua uriRestriction') 102 | if uriPath == nil then 103 | envoy.logErr('no uri path!') 104 | return 105 | end 106 | 107 | -- 配置为nil代表路由级别配置不存在(未配置路由级插件) 108 | if config == nil then 109 | return 110 | end 111 | 112 | local match = checkUriPath(uriPath, config.allowlist, config.denylist) 113 | 114 | envoy.logDebug('on_request_header, uri path: ' .. uriPath .. ', match result: ' .. match) 115 | 116 | if match > 1 then 117 | envoy.logDebug('path is now allowed: ' .. uriPath) 118 | return respond({[':status'] = FORBIDDEN}, 'Forbidden') 119 | end 120 | end 121 | 122 | return uriRestrictionHandler 123 | ``` 124 | 125 | ### 2.2 rider 调试 126 | 127 | 修改script/dev/envoy.yaml文件,增加对应的http_filter配置,具体如下: 128 | 129 | ```yaml 130 | - name: proxy.filters.http.rider 131 | typed_config: 132 | "@type": type.googleapis.com/proxy.filters.http.rider.v3alpha1.FilterConfig 133 | plugin: 134 | vm_config: 135 | package_path: "/usr/local/lib/rider/?/init.lua;/usr/local/lib/rider/?.lua;" 136 | code: 137 | local: 138 | filename: /usr/local/lib/rider/plugins/uri-restriction.lua 139 | name: uri-restriction.lua 140 | config: {} 141 | ``` 142 | 143 | 增加对应route配置,具体配置如下: 144 | 145 | ```yaml 146 | typed_per_filter_config: 147 | proxy.filters.http.rider: 148 | "@type": type.googleapis.com/proxy.filters.http.rider.v3alpha1.RouteFilterConfig 149 | plugins: 150 | - name: uri-restriction 151 | config: 152 | allowlist: 153 | - a1 154 | denylist: 155 | - d1 156 | ``` 157 | 158 | 执行`./scripts/dev/local-up.sh` 启动 hango-gateway和一个简单的 HTTP 服务。 159 | 160 | 通过`curl -v http://localhost:8002/static-to-header` 161 | 162 | ![image-20210416173118827](../images/rider_uri_restriction_test_ok.png) 163 | 164 | response: `403 Foebidden` 165 | 166 | ### 2.3 控制台schema开发 167 | 168 | 通过开发对应的插件schema,可以将插件暴露至网关控制台,便于用户进行配置。 169 | 170 | 通过编写json schema,将对应的uri-restriction插件暴露在hango控制台。前端schema开发可以参考[schema开发手册.md](schema_guide.md)。 171 | 172 | 根据需求,开发uri-restriction 前端schema如下: 173 | 174 | ```json 175 | { 176 | "formatter": { 177 | "kind": "uri-restriction", 178 | "type": "lua", 179 | "config": { 180 | "allowlist": "&allowlist", 181 | "denylist": "&denylist" 182 | } 183 | }, 184 | "layouts": [ 185 | { 186 | "key": "allowlist", 187 | "alias": "白名单", 188 | "help": "URI优先匹配白名单,命中之后直接放行,支持正则", 189 | "type": "multi_input", 190 | "rules": [ 191 | ] 192 | }, 193 | { 194 | "key": "denylist", 195 | "alias": "黑名单", 196 | "help": "URI优先匹配白名单,没有命中,继续匹配黑名单,命中之后直接禁止,支持正则", 197 | "type": "multi_input", 198 | "rules": [ 199 | ] 200 | } 201 | ] 202 | } 203 | ``` 204 | 205 | ## 三、集成插件至hango 206 | 207 | ### 3.1 集成插件至hango-envoy 208 | 209 | (1)在rider目录下,执行 210 | 211 | ```yaml 212 | kubectl create configmap hango-rider-plugin --from-file=plugins/ -n hango-system 213 | ``` 214 | 215 | (2)等待10s左右,即将对应的plugins加载至hango-gateway中 216 | 217 | ### 3.2 集成插件至api-palne 218 | 219 | (1)明确插件的级别 220 | 221 | hango网关自定义插件支持两种级别:全局级别和路由级别;全局级别即整个网关级别,生效顺序是优先路由级插件生效。 222 | 223 | 全局配置入口为:【插件管理】-> 【添加全局插件】。配置一个全局插件后,该网关的所有路由均生效 224 | 225 | 路由级别配置入口为:【已发布信息】-> 【已发布路由】-> 【插件】-> 【添加全局插件】。配置一个路由级插件后,仅对当前路由生效。 226 | 227 | (2)修改api-plane工程 /plugin/route 目录下的plugin-config.json增加对应的插件声明 228 | 229 | ```json 230 | { 231 | "name": "uri-restriction", 232 | "displayName": "URI黑白名单", 233 | "schema": "plugin/route/uri-restriction.json", 234 | "description": "URI黑白名单插件", 235 | "processor": "AggregateGatewayPluginProcessor", 236 | "author": "system", 237 | "createTime": "1655279630000", 238 | "updateTime": "1655279630000", 239 | "pluginScope": "global,routeRule", 240 | "pluginPriority": "3000", 241 | "instructionForUse": "URI黑白名单插件", 242 | "categoryKey": "security", 243 | "categoryName": "安全" 244 | } 245 | ``` 246 | 247 | (3) 在/plugin/route目录下增加uri-restriction.json schema文件 248 | 249 | ```json 250 | ---uri-restriction.json 251 | { 252 | "formatter": { 253 | "kind": "uri-restriction", 254 | "type": "lua", 255 | "config": { 256 | "allowlist": "&allowlist", 257 | "denylist": "&denylist" 258 | } 259 | }, 260 | "layouts": [ 261 | { 262 | "key": "allowlist", 263 | "alias": "白名单", 264 | "help": "URI优先匹配白名单,命中之后直接放行,支持正则", 265 | "type": "multi_input", 266 | "rules": [ 267 | ] 268 | }, 269 | { 270 | "key": "denylist", 271 | "alias": "黑名单", 272 | "help": "URI优先匹配白名单,没有命中,继续匹配黑名单,命中之后直接禁止,支持正则", 273 | "type": "multi_input", 274 | "rules": [ 275 | ] 276 | } 277 | ] 278 | } 279 | ``` 280 | 281 | (4) 执行以下指令,生成对应的插件configmap 282 | 283 | ```shell 284 | kubectl create configmap hango-plugin --from-file=plugin/route/ -n hango-system 285 | ``` 286 | 287 | (5) 等待大约10s,待configmap加载成功即可以使用自定义插件。 288 | -------------------------------------------------------------------------------- /example/schema_guide.md: -------------------------------------------------------------------------------- 1 | # 结构 2 | 3 | ```json 4 | { 5 | "version": "版本", 6 | "inject": {}, // 需要在最终特殊注入的参数,不会展示 7 | "formatter": { // 重定义最终参数字段,不定义时候,按照layouts结构返回 8 | }, 9 | "layouts": [ 10 | { 11 | "key": "后端接口 key", 12 | "alias": "前端字段显示的 label", 13 | "help": "label 旁边的 ❓ hover 提示", 14 | "type": "支持的类型", // 下表详细提供 15 | "default": "默认值", 16 | "options": [ // 可选字段,支持 string 或 object 17 | "普通字符串", 18 | { // or Object 19 | "text": "前端展示的文字", 20 | "value": "后端映射的值" 21 | } 22 | ], 23 | "layouts": [ 24 | ... // 嵌套循环字段 25 | ], 26 | 27 | // 以下功能为增强型功能 28 | "rules": [ // 规则校验参数,支持 string 29 | "Required" // 必须填写 30 | ], 31 | "disabled": false, // 是否禁用 32 | "visible": { // 条件显示 33 | [key]: "等于某个值时起作用" 34 | }, 35 | "invisible": { // 条件隐藏 36 | [key]: "等于某个值时起作用" 37 | }, 38 | 39 | // 以下为保留字段 40 | "role": "角色", 41 | "style": {}, // 自定义样式,暂不支持 42 | } 43 | ] 44 | } 45 | ``` 46 | 47 | # 配置 48 | 49 | ## 特殊参数 50 | 51 | | 字段 | 类型 | 备注 | 默认值 | 52 | | --------- | ------ | ------------------------------------------------ | ------ | 53 | | inject | Object | 需要在最终特殊注入的参数,不会展示 | N | 54 | | version | String | 版本控制预留字段 | N | 55 | | formatter | Object | 格式化提交结果,如果配置了,则覆盖原 schema 格式 | N | 56 | | | | | | 57 | 58 | ## 基本参数 59 | 60 | | 字段 | 类型 | 备注 | 默认值 | 61 | | ------------------- | ------------------------ | -------------------------------------------------------- | ------ | 62 | | layouts | Array`` | 布局,_嵌套循环字段_(数组嵌套时,需要配合`type=array`) | Y | 63 | | key | String | 后端接口 key | Y | 64 | | alias | String | 前端字段显示的 label | Y | 65 | | help | String | label 旁边的 ❓ hover 提示 | N | 66 | | description | String | 描述提示信息 | N | 67 | | placeholder | String | 输入框内提示信息 | N | 68 | | [type](#Type) | String | 支持的类型,参考表 [Type](#Type) | Y | 69 | | default | | 字段默认值。(返回值必要时,请填写) | N | 70 | | [options](#Options) | Array`` | 根据不同`type` 进行配合使用,参考表 [Options](#Options) | N | 71 | | | | | | 72 | | | | | | 73 | 74 | ### Type 75 | 76 | | 字段 | 备注 | 77 | | ------------ | ------------------------------------------------- | 78 | | text | 文本格式 | 79 | | input | 输入框 | 80 | | string | 同 `input` | 81 | | multi_input | 多值输入框,返回数组 | 82 | | multi_string | 同 `multi_input` | 83 | | number | 数字输入框 | 84 | | select | 下拉选择框,需配合 `options` 参数 | 85 | | array | 同 `select` | 86 | | multi_select | 下拉多选择框,需配合 `options` 参数 | 87 | | multi_array | 同 `multi_select` | 88 | | radio | 单选组,需配合 `options` 参数 | 89 | | checkbox | 多选组,需配合 `options` 参数 | 90 | | switch | Boolean 值切换 | 91 | | boolean | 同 `switch` | 92 | | json | json格式文本输入 | 93 | | | | 94 | | button | 按钮(保留字段,暂不支持),需配合 `options` 参数 | 95 | | | | 96 | 97 | ### Options 98 | 99 | | 字段 | 备注 | 100 | | -------- | ------------------ | 101 | | text | 前端展示的文字 | 102 | | value | 后端映射的值 | 103 | | disabled | 是否禁用当前选项 | 104 | | | | 105 | | color | 保留字段,暂不支持 | 106 | | event | 保留字段,暂不支持 | 107 | | | | 108 | 109 | ## 增强参数 110 | 111 | | 字段 | 类型 | 备注 | 是否必需 | 112 | | --------- | ----------------- | -------------------------------- | -------- | 113 | | rules | Array`` | 校验规则,参考表 [Rules](#Rules) | N | 114 | | disabled | Boolean | 是否禁用 | N | 115 | | visible | Boolean \| Object | 条件显示 | N | 116 | | invisible | Boolean \| Object | 条件隐藏 | N | 117 | | | | | | 118 | 119 | ### Rules 120 | 121 | `rules` 中,未在下表中声明的内置规则,都是按照正则表达式进行解析。 122 | 123 | | 字段 | 备注 | 124 | | -------------- | -------------------------------------- | 125 | | Required | 必须填写 | 126 | | Number | 有效的正整数 | 127 | | Name | 由字母、中文、数字、下划线或中划线组成 | 128 | | MaxLength(200) | 最大长度 200 位 | 129 | | MinLength(100) | 最小长度 100 位 | 130 | | MaxNumber(999) | 最大数字 999 | 131 | | MinNumber(1) | 最小数字 1 | 132 | | Unique | 数组类型时,可检测是否重复 | 133 | | ArrayMaxLength(10) | 数组类型时,最大 10 组 | 134 | | ArrayMinLength(1) | 数组类型时,最小 1 组 | 135 | | | | 136 | 137 | ### 自定义正则 138 | 139 | ```js 140 | "rules": [ 141 | "Required", 142 | { 143 | "pattern": "^\\d+$", 144 | "flags": "", // 正则表达式修饰符: i 执行对大小写不敏感的匹配。g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。m 执行多行匹配。 145 | "message": "自定义提示,必须是数字", 146 | } 147 | ] 148 | ``` 149 | 150 | 正则表达式修饰符: 151 | 152 | ![image.png](http://pfp.ps.netease.com/kmspvt/file/612df4966158bc85425e8523ViyrJGmZ01?sign=Qj8Ok88lN_diq8__i5hXOlxYlXc=&expire=1660574063) 153 | 154 | ## 保留参数 155 | 156 | | 字段 | 类型 | 备注 | 是否必需 | 157 | | ----- | ------ | ---------------------------------- | -------- | 158 | | role | String | 内置角色行为(保留字段,暂不支持) | N | 159 | | style | Object | 保留字段,暂不支持 | N | 160 | | | | | | 161 | | | | | | 162 | | | | | | 163 | 164 | 165 | 166 | ## 特殊字段解释 167 | 168 | ### inject 169 | 170 | `inject` 参数是用来定义一些特殊的不再前端展示的内容,最终会合并到主结构体一起提交。 171 | 172 | 例如: 173 | 174 | schema 定义如下 175 | 176 | ```json 177 | { 178 | "layouts": [ 179 | { 180 | "key": "a", 181 | "alias": "a", 182 | "layouts": [ 183 | { 184 | "key": "b", 185 | "alias": "b", 186 | "type": "input", 187 | } 188 | ] 189 | }, 190 | { 191 | "key": "c", 192 | "alias": "c", 193 | "type": "input", 194 | } 195 | ] 196 | } 197 | ``` 198 | 199 | 正常返回时的结构为: 200 | 201 | ```json 202 | { 203 | "a": { 204 | "b": "", 205 | }, 206 | "c": "", 207 | } 208 | ```` 209 | 210 | 如果我们定义了 `inject` 参数,如: 211 | 212 | ```json 213 | { 214 | "inject": { 215 | "kind": "abc", 216 | "a": { 217 | "d": "ddd", 218 | } 219 | }, 220 | "layouts": [ 221 | ... 222 | ] 223 | } 224 | ``` 225 | 226 | 则返回的最终结果将是如下: 227 | 228 | ```json 229 | { 230 | "kind": "abc", 231 | "a": { 232 | "b": "", 233 | "d": "ddd", 234 | }, 235 | "c": "", 236 | } 237 | ``` 238 | 239 | ### formatter 240 | 241 | `formatter` 更强大的自定义返回结构体,最总格式将按照 `formatter` 定义的结构进行重构,如下: 242 | 243 | 例如: 244 | 245 | schema 定义如下 246 | 247 | ```json 248 | { 249 | "layouts": [ 250 | { 251 | "key": "a", 252 | "alias": "a", 253 | "layouts": [ 254 | { 255 | "key": "b", 256 | "alias": "b", 257 | "type": "input", 258 | } 259 | ] 260 | }, 261 | { 262 | "key": "c", 263 | "alias": "c", 264 | "type": "input", 265 | } 266 | ] 267 | } 268 | ``` 269 | 270 | 正常返回时的结构为: 271 | 272 | ```json 273 | { 274 | "a": { 275 | "b": "bbb", 276 | }, 277 | "c": "ccc", 278 | } 279 | ```` 280 | 281 | 如果我们定义了 `formatter` 参数(其中 `+` 为内置连接符号),如: 282 | 283 | 连接符号为:+ 284 | 取值为:&, key和value都要 & 开头取值,否则为字符串 285 | @号开头的 value 数组,会拉平为 map。数组种必须要有 { key: '', value: '' } 两个字段' 286 | 287 | **注意**: 如果使用了上述的符号,请把原 layouts 定义字段结构映射到 formatter 的原始位置上。否则更新取值无法实现! 288 | 289 | ```json 290 | { 291 | "formatter": { 292 | "Result": "&a.b+c" 293 | }, 294 | "layouts": [ 295 | ... 296 | ] 297 | } 298 | ``` 299 | 300 | 则返回的最终结果将是如下: 301 | 302 | ```json 303 | { 304 | "Result": "bbbccc", 305 | } 306 | ``` 307 | 308 | 309 | # 例子 (可不看) 310 | 311 | ```json 312 | { 313 | "inject": { 314 | "name": "ianus-rate-limiting", 315 | "kind": "ianus-rate-limiting", 316 | "limit_by_list": { 317 | "kind": "abc" 318 | } 319 | }, 320 | "layouts": [{ 321 | "key": "type_text", 322 | "description": "text 类型的 Demo", 323 | "default": "我是文本", 324 | "alias": "text", 325 | "type": "text" 326 | }, 327 | { 328 | "key": "type_switch", 329 | "description": "switch 类型的 Demo", 330 | "alias": "switch", 331 | "type": "switch" 332 | }, 333 | { 334 | "key": "type_input", 335 | "description": "input 类型的 Demo", 336 | "alias": "input", 337 | "type": "input" 338 | }, 339 | { 340 | "key": "type_multi_input", 341 | "description": "multi_input 类型的 Demo", 342 | "alias": "multi_input", 343 | "type": "multi_input" 344 | }, 345 | { 346 | "key": "type_number", 347 | "description": "number 类型的 Demo", 348 | "alias": "number", 349 | "type": "number" 350 | }, 351 | { 352 | "key": "type_select", 353 | "description": "select 类型的 Demo", 354 | "alias": "select", 355 | "type": "select", 356 | "options": ["A", "B"] 357 | }, 358 | { 359 | "key": "type_multi_select", 360 | "description": "multi_select 类型的 Demo", 361 | "alias": "multi_select", 362 | "type": "multi_select", 363 | "options": ["A", "B"] 364 | }, 365 | { 366 | "key": "type_radio", 367 | "description": "radio 类型的 Demo", 368 | "alias": "radio", 369 | "type": "radio", 370 | "options": ["A", "B"] 371 | }, 372 | { 373 | "key": "type_checkbox", 374 | "description": "checkbox 类型的 Demo", 375 | "alias": "checkbox", 376 | "type": "checkbox", 377 | "options": ["A", "B"] 378 | }, 379 | { 380 | "key": "type_json", 381 | "description": "json 类型的 Demo", 382 | "alias": "json", 383 | "type": "json", 384 | "default": { "info": "我是默认值" } 385 | }, 386 | { 387 | "key": "limit_by_list", 388 | "help": "1.频率限制是指限制带同一标识请求在给定时间段内可处理的次数;\n2.user-开头的是指用户在某维度的参数, 不以user-开头的是指下游服务器的参数;\n3.使用user-xxx参数的前提是\"请求转换插件\"已经将xxx参数转换为user-xxx.;\n4.当前版本计数方式限制为local, 所以实际频控限制=配置的限制*集群节点数量", 389 | "alias": "复杂类型", 390 | "type": "array", 391 | "layouts": [{ 392 | "key": "identifier_extractor", 393 | "help": "用于计算请求标识,以供计数使用;例如,Ip, Header[User-Agent]", 394 | "alias": "标识提取策略", 395 | "type": "string" 396 | }, 397 | { 398 | "key": "pre_condition", 399 | "help": "满足前置条件的请求才会进入频控流程. 左变量为identifier_extractor提取的值", 400 | "alias": "频控前置条件", 401 | "type": "array", 402 | "layouts": [{ 403 | "key": "right_value", 404 | "alias": "right_value", 405 | "type": "string" 406 | }, 407 | { 408 | "key": "operator", 409 | "alias": "operator", 410 | "type": "select", 411 | "default": "=", 412 | "options": ["≈", "!≈", "=", "!="] 413 | } 414 | ] 415 | }, 416 | { 417 | "key": "key", 418 | "alias": "KEY", 419 | "type": "input" 420 | }, 421 | { 422 | "key": "value", 423 | "alias": "VALUE", 424 | "type": "input" 425 | }, 426 | { 427 | "key": "day", 428 | "alias": "每天请求数", 429 | "type": "number" 430 | }, 431 | { 432 | "key": "minute", 433 | "alias": "每分钟请求数", 434 | "type": "number" 435 | }, 436 | { 437 | "key": "second", 438 | "alias": "每秒请求数", 439 | "type": "number" 440 | }, 441 | { 442 | "key": "limit_by_list", 443 | "help": "1.频率限制是指限制带同一标识请求在给定时间段内可处理的次数;\n2.user-开头的是指用户在某维度的参数, 不以user-开头的是指下游服务器的参数;\n3.使用user-xxx参数的前提是\"请求转换插件\"已经将xxx参数转换为user-xxx.;\n4.当前版本计数方式限制为local, 所以实际频控限制=配置的限制*集群节点数量", 444 | "alias": "限制标识列表3", 445 | "layouts": [{ 446 | "visible": { 447 | "true": ["this", "month"] 448 | }, 449 | "key": "identifier_extractor", 450 | "help": "用于计算请求标识,以供计数使用;例如,Ip, Header[User-Agent]", 451 | "alias": "标识提取策略", 452 | "type": "string" 453 | }, 454 | { 455 | "key": "month", 456 | "alias": "每月请求数", 457 | "type": "switch" 458 | }, 459 | { 460 | "key": "hour", 461 | "alias": "每小时请求数", 462 | "type": "number" 463 | } 464 | ] 465 | } 466 | ] 467 | }, 468 | { 469 | "key": "rules", 470 | "description": "rules 校验的 Demo, 必须填写,且只能输入数字", 471 | "alias": "rules", 472 | "type": "input", 473 | "rules": [ 474 | "Required", 475 | "^\\d+$" 476 | ] 477 | } 478 | ] 479 | } 480 | ``` 481 | -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/.DS_Store -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/architecture.png -------------------------------------------------------------------------------- /images/hango-ui-create-gateway-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-create-gateway-form.png -------------------------------------------------------------------------------- /images/hango-ui-create-route-form1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-create-route-form1.png -------------------------------------------------------------------------------- /images/hango-ui-create-route-form2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-create-route-form2.png -------------------------------------------------------------------------------- /images/hango-ui-create-svc-click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-create-svc-click.png -------------------------------------------------------------------------------- /images/hango-ui-create-svc-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-create-svc-form.png -------------------------------------------------------------------------------- /images/hango-ui-publish-route-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-publish-route-form.png -------------------------------------------------------------------------------- /images/hango-ui-publish-svc-click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-publish-svc-click.png -------------------------------------------------------------------------------- /images/hango-ui-publish-svc-done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-publish-svc-done.png -------------------------------------------------------------------------------- /images/hango-ui-publish-svc-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui-publish-svc-form.png -------------------------------------------------------------------------------- /images/hango-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-ui.png -------------------------------------------------------------------------------- /images/hango-wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango-wechat.png -------------------------------------------------------------------------------- /images/hango_route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/hango_route.png -------------------------------------------------------------------------------- /images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/logo.jpg -------------------------------------------------------------------------------- /images/pod_status_ok.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/pod_status_ok.PNG -------------------------------------------------------------------------------- /images/rider_ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/rider_ok.png -------------------------------------------------------------------------------- /images/rider_uri_restriction_test_ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hango-io/hango-gateway/18cbd10ee8c19a67276a02c71fe4ba891e45cd5a/images/rider_uri_restriction_test_ok.png -------------------------------------------------------------------------------- /install/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Installing on Kubernetes 4 | 5 | We use helm to install gateway on kubernetes. If you do not have a kubernetes, you can start with [minikube start](https://minikube.sigs.k8s.io/docs/start/) 6 | 7 | 1.22 > Kubernetes Version >=1.17 8 | 9 | ### Install with Shell 10 | 11 | 1. Go to github hango-gateway's [releases page](https://github.com/hango-io/hango-gateway/releases) to download the latest version: [release-v1.0.0](https://github.com/hango-io/hango-gateway/releases/download/v1.0.0/hango-gateway-v1.0.0.zip), then decompress the zip file to a local directory 12 | 13 | 2. Go to the "hango-gateway/install" directory. The directory structure tree is as follows 14 | ```xml 15 | install 16 | install 17 | ├─common 18 | ├─crds 19 | ├─helm 20 | ├─init-hango 21 | ├─install.sh 22 | ├─check.sh 23 | └─uninstall.sh 24 | ``` 25 | 3. You will see three scripts for install (install.sh), check status (check.sh), and uninstall (uninstall.sh) respectively. You can directly execute the command 26 | 27 | Note: Make sure you have sufficient permissions before executing the script 28 | ```shell 29 | sh install.sh 30 | ``` 31 | 4. After the script is executed, run the following command to verify the running status of the Hango gateway 32 | ```shell 33 | sh check.sh 34 | ``` 35 | The normal running status is as follows. If the container is not ready now, wait for a while and check it again 36 | ```shell 37 | [install-check][14:50:49] 38 | ========= pods in namespace[hango-system] show below ========= 39 | NAME READY STATUS RESTARTS AGE 40 | gateway-proxy-55887cb579-mv9xh 1/1 Running 0 87s 41 | hango-api-plane-6c4554cfc4-ndnx5 1/1 Running 0 101s 42 | hango-portal-597bb489d6-45b2r 1/1 Running 0 101s 43 | hango-ui-75458cc7dc-b4x6b 1/1 Running 0 101s 44 | istio-e2e-app-85bb49bf75-t7slt 1/1 Running 0 101s 45 | hango-istiod-697b5c4456-67l92 1/1 Running 0 95s 46 | slime-75fcb44f68-w9x4x 1/1 Running 0 94s 47 | ``` 48 | 49 | ### The other way to install Hango gateway 50 | 1. Please configure K8S resources of Hango gateway by referring to the script content 51 | 52 | ### Uninstall with Shell 53 | 1. Go to "hango-gateway/install" directory 54 | 2. Run the script to uninstall hango gateway 55 | 56 | Note: Make sure you have sufficient permissions before executing the script 57 | ```shell 58 | sh uninstall.sh 59 | ``` 60 | 3. After the script is executed, run the following command to check the running status of the Hango gateway 61 | ```shell 62 | sh check.sh 63 | ``` 64 | After the uninstallation is complete, the namespaces and all containers under them will be deleted. If k8s resources still exist, you can try uninstall.sh script again or manually delete the resources 65 | ```shell 66 | [install-check][14:56:29] 67 | ========= pods in namespace[hango-system] show below ========= 68 | No resources found in hango-system namespace. 69 | ``` 70 | 71 | ## Installing on Docker 72 | 73 | Planing... 74 | 75 | ## Installing on VMs 76 | 77 | Planing... 78 | -------------------------------------------------------------------------------- /install/README.zh_CN.md: -------------------------------------------------------------------------------- 1 | # 安装 2 | 3 | ## 前置条件 4 | 5 | 1.目前版本支持基于Kubernetes进行安装,如果没有Kubernetes环境,可以采用[minikube](https://minikube.sigs.k8s.io/docs/start/) 进行安装。对于Kubernetes的版本,我们要求版本至少是1.17 版本,低于1.22 版本。\ 6 | 2.请确保已安装helm。 7 | 8 | ### 安装hango网关 9 | 10 | 1、前往github hango-gateway的[releases界面](https://github.com/hango-io/hango-gateway/releases)下载最新的[release-v1.0.0版本](https://github.com/hango-io/hango-gateway/releases/download/v1.0.0/hango-gateway-v1.0.0.zip),将压缩包解压为本地目录 11 | 12 | 2、进入"hango-gateway/install"目录下,目录结构树如下 13 | ```xml 14 | install 15 | ├─common 16 | ├─crds 17 | ├─helm 18 | ├─init-hango 19 | ├─install.sh 20 | ├─check.sh 21 | └─uninstall.sh 22 | ``` 23 | 3、您将看到3个脚本分别用于安装(install.sh)、检查状态(check.sh)、卸载(uninstall.sh),可直接执行命令\ 24 | 注意:在脚本执行前请确保权限足够 25 | ```shell 26 | sh install.sh 27 | ``` 28 | 4、等待脚本执行完毕后,可以通过执行下面的命令查看hango网关的运行状态 29 | ```shell 30 | sh check.sh 31 | ``` 32 | 正常的运行状态如下,若容器未就绪,请再耐心等待一段时间再检查 33 | ```shell 34 | 35 | [install-check][14:50:49] 36 | ========= pods in namespace[hango-system] show below ========= 37 | NAME READY STATUS RESTARTS AGE 38 | gateway-proxy-55887cb579-mv9xh 1/1 Running 0 87s 39 | hango-api-plane-6c4554cfc4-ndnx5 1/1 Running 0 101s 40 | hango-portal-597bb489d6-45b2r 1/1 Running 0 101s 41 | hango-ui-75458cc7dc-b4x6b 1/1 Running 0 101s 42 | istio-e2e-app-85bb49bf75-t7slt 1/1 Running 0 101s 43 | hango-istiod-697b5c4456-67l92 1/1 Running 0 95s 44 | slime-75fcb44f68-w9x4x 1/1 Running 0 94s 45 | ``` 46 | 47 | ### 其他方式安装hango网关 48 | 49 | 1、请参考脚本内容配置hango的k8s资源 50 | 51 | ### 卸载hango网关 52 | 53 | 1、进入"hango-gateway/install"目录下\ 54 | 2、执行命令运行脚本卸载hango网关\ 55 | 注意:在脚本执行前请确保权限足够 56 | ```shell 57 | sh uninstall.sh 58 | ``` 59 | 3、等待脚本执行完毕后,可以通过执行下面的命令查看hango网关的运行状态 60 | ```shell 61 | sh check.sh 62 | ``` 63 | 卸载完成后,命名空间和其下的容器将全部删除,正常状态如下,若仍然存于未删除资源,您可以再次执行uninstall.sh脚本或手动删除资源 64 | ```shell 65 | [install-check][14:56:29] 66 | ========= pods in namespace[hango-system] show below ========= 67 | No resources found in hango-system namespace. 68 | ``` -------------------------------------------------------------------------------- /install/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## container status check script for "Hango-Gateway" 4 | 5 | work_dir=$(cd $(dirname $0); pwd) 6 | 7 | # import common functions (log) 8 | source "${work_dir}"/common/common.sh 9 | 10 | LOG_PREFIX="install-check" 11 | DATA_FORMAT="+%H:%M:%S" 12 | HANGO_SYSTEM_NAMESPACE="hango-system" 13 | 14 | echo -e "\nPlease wait for all pods status running and ready. If it persists for long time, manually check it.\n" 15 | echo "" 16 | log "\n========= pods in namespace[\033[44;37;25m${HANGO_SYSTEM_NAMESPACE}\033[0m] show below =========" 17 | kubectl -n "${HANGO_SYSTEM_NAMESPACE}" get pods -------------------------------------------------------------------------------- /install/common/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # you can override variables below by yours 4 | LOG_DEST_CONSOLE="console" 5 | LOG_DEST_FILE="file" 6 | DATA_FORMAT="+%Y-%m-%d %H:%M:%S" 7 | LOG_FILE="/root/install_hango.log" 8 | LOG_PREFIX="hango-install" 9 | log_dest="${LOG_DEST_CONSOLE}" 10 | 11 | # log for installing 12 | function log() { 13 | tmp_dest="${log_dest}" 14 | log_time=$(date "${DATA_FORMAT}") 15 | 16 | # temporary choice for log output destination 17 | if [ $# -gt 1 ]; then 18 | if [[ "$1" = "${LOG_DEST_CONSOLE}" ]]; then 19 | log_dest="${LOG_DEST_CONSOLE}" 20 | elif [[ "$1" = "${LOG_DEST_FILE}" ]]; then 21 | log_dest="${LOG_DEST_FILE}" 22 | fi 23 | fi 24 | 25 | # output the log by destination 26 | if [[ "${log_dest}" = "${LOG_DEST_CONSOLE}" ]]; then 27 | echo -e "[${LOG_PREFIX}][${log_time}]" "$*" 28 | elif [[ "${log_dest}" = "${LOG_DEST_FILE}" ]]; then 29 | echo -e "[${LOG_PREFIX}][${log_time}]" "$*" >>"${LOG_FILE}" 30 | else 31 | echo "Please choose right destination for log output." 32 | fi 33 | # restore with original destination 34 | log_dest="${tmp_dest}" 35 | } 36 | -------------------------------------------------------------------------------- /install/crds/crd-11.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: CustomResourceDefinition 3 | apiVersion: apiextensions.k8s.io/v1 4 | metadata: 5 | name: cloudwatches.config.istio.io 6 | labels: 7 | app: mixer 8 | package: cloudwatch 9 | istio: mixer-adapter 10 | annotations: 11 | "helm.sh/resource-policy": keep 12 | spec: 13 | group: config.istio.io 14 | names: 15 | kind: cloudwatch 16 | plural: cloudwatches 17 | singular: cloudwatch 18 | categories: 19 | - istio-io 20 | - policy-istio-io 21 | scope: Namespaced 22 | versions: 23 | - name: v1alpha2 24 | served: true 25 | storage: true 26 | schema: 27 | openAPIV3Schema: 28 | type: object 29 | x-kubernetes-preserve-unknown-fields: true 30 | --- 31 | kind: CustomResourceDefinition 32 | apiVersion: apiextensions.k8s.io/v1 33 | metadata: 34 | name: dogstatsds.config.istio.io 35 | labels: 36 | app: mixer 37 | package: dogstatsd 38 | istio: mixer-adapter 39 | annotations: 40 | "helm.sh/resource-policy": keep 41 | spec: 42 | group: config.istio.io 43 | names: 44 | kind: dogstatsd 45 | plural: dogstatsds 46 | singular: dogstatsd 47 | categories: 48 | - istio-io 49 | - policy-istio-io 50 | scope: Namespaced 51 | versions: 52 | - name: v1alpha2 53 | served: true 54 | storage: true 55 | schema: 56 | openAPIV3Schema: 57 | type: object 58 | x-kubernetes-preserve-unknown-fields: true 59 | --- 60 | apiVersion: apiextensions.k8s.io/v1 61 | kind: CustomResourceDefinition 62 | metadata: 63 | name: sidecars.networking.istio.io 64 | labels: 65 | app: istio-pilot 66 | chart: istio 67 | heritage: Tiller 68 | release: istio 69 | annotations: 70 | "helm.sh/resource-policy": keep 71 | spec: 72 | group: networking.istio.io 73 | names: 74 | kind: Sidecar 75 | plural: sidecars 76 | singular: sidecar 77 | categories: 78 | - istio-io 79 | - networking-istio-io 80 | scope: Namespaced 81 | versions: 82 | - name: v1alpha3 83 | served: true 84 | storage: true 85 | schema: 86 | openAPIV3Schema: 87 | type: object 88 | x-kubernetes-preserve-unknown-fields: true 89 | --- 90 | kind: CustomResourceDefinition 91 | apiVersion: apiextensions.k8s.io/v1 92 | metadata: 93 | name: zipkins.config.istio.io 94 | labels: 95 | app: mixer 96 | package: zipkin 97 | istio: mixer-adapter 98 | annotations: 99 | "helm.sh/resource-policy": keep 100 | spec: 101 | group: config.istio.io 102 | names: 103 | kind: zipkin 104 | plural: zipkins 105 | singular: zipkin 106 | categories: 107 | - istio-io 108 | - policy-istio-io 109 | scope: Namespaced 110 | versions: 111 | - name: v1alpha2 112 | served: true 113 | storage: true 114 | schema: 115 | openAPIV3Schema: 116 | type: object 117 | x-kubernetes-preserve-unknown-fields: true 118 | --- 119 | -------------------------------------------------------------------------------- /install/crds/crd-17.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | "helm.sh/resource-policy": keep 7 | labels: 8 | app: istio-pilot 9 | chart: istio 10 | heritage: Tiller 11 | istio: security 12 | release: istio 13 | name: peerauthentications.security.istio.io 14 | spec: 15 | group: security.istio.io 16 | names: 17 | categories: 18 | - istio-io 19 | - security-istio-io 20 | kind: PeerAuthentication 21 | listKind: PeerAuthenticationList 22 | plural: peerauthentications 23 | shortNames: 24 | - pa 25 | singular: peerauthentication 26 | preserveUnknownFields: false 27 | scope: Namespaced 28 | versions: 29 | - name: v1beta1 30 | served: true 31 | storage: true 32 | subresources: 33 | status: {} 34 | schema: 35 | openAPIV3Schema: 36 | type: object 37 | x-kubernetes-preserve-unknown-fields: true 38 | additionalPrinterColumns: 39 | - jsonPath: .spec.mtls.mode 40 | description: Defines the mTLS mode used for peer authentication. 41 | name: Mode 42 | type: string 43 | - jsonPath: .metadata.creationTimestamp 44 | description: 'CreationTimestamp is a timestamp representing the server time when 45 | this object was created. It is not guaranteed to be set in happens-before order 46 | across separate operations. Clients may not set this value. It is represented 47 | in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for 48 | lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' 49 | name: Age 50 | type: date 51 | 52 | --- 53 | apiVersion: apiextensions.k8s.io/v1 54 | kind: CustomResourceDefinition 55 | metadata: 56 | annotations: 57 | "helm.sh/resource-policy": keep 58 | labels: 59 | app: istio-pilot 60 | chart: istio 61 | heritage: Tiller 62 | istio: security 63 | release: istio 64 | name: requestauthentications.security.istio.io 65 | spec: 66 | group: security.istio.io 67 | names: 68 | categories: 69 | - istio-io 70 | - security-istio-io 71 | kind: RequestAuthentication 72 | listKind: RequestAuthenticationList 73 | plural: requestauthentications 74 | shortNames: 75 | - ra 76 | singular: requestauthentication 77 | preserveUnknownFields: false 78 | scope: Namespaced 79 | versions: 80 | - name: v1beta1 81 | served: true 82 | storage: true 83 | subresources: 84 | status: {} 85 | schema: 86 | openAPIV3Schema: 87 | type: object 88 | x-kubernetes-preserve-unknown-fields: true 89 | 90 | --- 91 | -------------------------------------------------------------------------------- /install/crds/crd-slime.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: pluginmanagers.microservice.slime.io 5 | spec: 6 | group: microservice.slime.io 7 | names: 8 | shortNames: 9 | - plm 10 | kind: PluginManager 11 | listKind: PluginManagerList 12 | plural: pluginmanagers 13 | singular: pluginmanager 14 | scope: Namespaced 15 | versions: 16 | - name: v1alpha1 17 | schema: 18 | openAPIV3Schema: 19 | properties: 20 | apiVersion: 21 | description: 'APIVersion defines the versioned schema of this representation 22 | of an object. Servers should convert recognized schemas to the latest 23 | internal value, and may reject unrecognized values' 24 | type: string 25 | kind: 26 | description: 'Kind is a string value representing the REST resource this 27 | object represents. Servers may infer this from the endpoint the client 28 | submits requests to. Cannot be updated. In CamelCase' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | description: 'pluginmanager spec' 34 | type: object 35 | properties: 36 | gateway: 37 | description: which gateway should use this plugin setting 38 | items: 39 | type: string 40 | type: array 41 | plugin: 42 | items: 43 | oneOf: 44 | - not: 45 | anyOf: 46 | - required: 47 | - wasm 48 | - required: 49 | - inline 50 | - required: 51 | - rider 52 | - required: 53 | - wasm 54 | - required: 55 | - inline 56 | - required: 57 | - rider 58 | properties: 59 | enable: 60 | type: boolean 61 | listenerType: 62 | type: string 63 | enum: 64 | - Outbound 65 | - Inbound 66 | - Gateway 67 | name: 68 | type: string 69 | port: 70 | format: int32 71 | type: integer 72 | settings: 73 | description: Deprecated 74 | properties: 75 | fields: 76 | additionalProperties: 77 | description: "`Value` represents a dynamically typed value 78 | which can be either null, a number, a string, a boolean, 79 | a recursive struct value, or a list of values. A producer 80 | of value is expected to set one of that variants, absence 81 | of any variant indicates an error. \n The JSON representation 82 | for `Value` is JSON value." 83 | type: object 84 | description: Unordered map of dynamically typed values. 85 | type: object 86 | type: object 87 | typeUrl: 88 | type: string 89 | rider: 90 | type: object 91 | properties: 92 | url: 93 | type: string 94 | pluginName: 95 | type: string 96 | sha256: 97 | type: string 98 | settings: 99 | type: object 100 | x-kubernetes-preserve-unknown-fields: true 101 | image_pull_secret: 102 | type: object 103 | properties: 104 | imagePullSecretName: 105 | type: string 106 | imagePullSecretContent: 107 | type: string 108 | oneOf: 109 | - required: 110 | - imagePullSecretName 111 | - required: 112 | - imagePullSecretContent 113 | - not: 114 | anyOf: 115 | - required: 116 | - imagePullSecretName 117 | - required: 118 | - imagePullSecretContent 119 | wasm: 120 | type: object 121 | oneOf: 122 | - required: 123 | - imagePullSecretName 124 | - required: 125 | - imagePullSecretContent 126 | - not: 127 | anyOf: 128 | - required: 129 | - imagePullSecretName 130 | - required: 131 | - imagePullSecretContent 132 | properties: 133 | url: 134 | type: string 135 | pluginName: 136 | type: string 137 | sha256: 138 | type: string 139 | settings: 140 | type: object 141 | x-kubernetes-preserve-unknown-fields: true 142 | imagePullSecretName: 143 | type: string 144 | imagePullSecretContent: 145 | type: string 146 | inline: 147 | type: object 148 | properties: 149 | settings: 150 | type: object 151 | x-kubernetes-preserve-unknown-fields: true 152 | directPatch: 153 | type: boolean 154 | fieldPatchTo: 155 | type: string 156 | type: object 157 | type: array 158 | workloadLabels: 159 | description: '`WorkloadSelector` specifies the criteria used to determine 160 | if the `Gateway`, `Sidecar`, or `EnvoyFilter` or `ServiceEntry` configuration 161 | can be applied to a proxy. The matching criteria includes the metadata 162 | associated with a proxy, workload instance info such as labels attached 163 | to the pod/VM, or any other info that the proxy provides to Istio during 164 | the initial handshake. If multiple conditions are specified, all conditions 165 | need to match in order for the workload instance to be selected. Currently, 166 | only label based selection mechanism is supported.' 167 | additionalProperties: 168 | type: string 169 | description: workload selector , it should not be nil in Gateway Scenarios 170 | type: object 171 | status: 172 | type: object 173 | x-kubernetes-preserve-unknown-fields: true 174 | required: 175 | - metadata 176 | - spec 177 | type: object 178 | served: true 179 | storage: true 180 | subresources: 181 | status: {} 182 | 183 | 184 | 185 | --- 186 | apiVersion: apiextensions.k8s.io/v1 187 | kind: CustomResourceDefinition 188 | metadata: 189 | name: envoyplugins.microservice.slime.io 190 | spec: 191 | group: microservice.slime.io 192 | names: 193 | shortNames: 194 | - evp 195 | kind: EnvoyPlugin 196 | listKind: EnvoyPluginList 197 | plural: envoyplugins 198 | singular: envoyplugin 199 | scope: Namespaced 200 | versions: 201 | - name: v1alpha1 202 | served: true 203 | storage: true 204 | subresources: 205 | status: {} 206 | schema: 207 | openAPIV3Schema: 208 | type: object 209 | x-kubernetes-preserve-unknown-fields: true 210 | 211 | --- 212 | 213 | apiVersion: apiextensions.k8s.io/v1 214 | kind: CustomResourceDefinition 215 | metadata: 216 | name: smartlimiters.microservice.slime.io 217 | spec: 218 | group: microservice.slime.io 219 | names: 220 | shortNames: 221 | - sml 222 | kind: SmartLimiter 223 | listKind: SmartLimiterList 224 | plural: smartlimiters 225 | singular: smartlimiter 226 | scope: Namespaced 227 | versions: 228 | - name: v1alpha2 229 | schema: 230 | openAPIV3Schema: 231 | description: SmartLimiter is the Schema for the smartlimiters API 232 | properties: 233 | apiVersion: 234 | description: 'APIVersion defines the versioned schema of this representation 235 | of an object. Servers should convert recognized schemas to the latest 236 | internal value, and may reject unrecognized values' 237 | type: string 238 | kind: 239 | description: 'Kind is a string value representing the REST resource this 240 | object represents. Servers may infer this from the endpoint the client 241 | submits requests to. Cannot be updated. In CamelCase' 242 | type: string 243 | metadata: 244 | type: object 245 | spec: 246 | properties: 247 | gateway: 248 | description: is gateway 249 | type: boolean 250 | host: 251 | description: hostname specify svc host 252 | type: string 253 | rls: 254 | description: deprecated, mv to limiter_module.proto 255 | type: string 256 | sets: 257 | additionalProperties: 258 | properties: 259 | descriptor: 260 | description: Description of current rate-limit 261 | items: 262 | properties: 263 | action: 264 | properties: 265 | fill_interval: 266 | properties: 267 | nanos: 268 | description: Signed fractions of a second at nanosecond 269 | resolution of the span of time. Durations less 270 | than one second are represented with a 0 `seconds` 271 | field and a positive or negative `nanos` field. 272 | For durations of one second or more, a non-zero 273 | value for the `nanos` field must be of the same 274 | sign as the `seconds` field. Must be from -999,999,999 275 | to +999,999,999 inclusive. 276 | format: int32 277 | type: integer 278 | seconds: 279 | description: 'Signed seconds of the span of time. 280 | Must be from -315,576,000,000 to +315,576,000,000 281 | inclusive. Note: these bounds are computed from: 282 | 60 sec/min * 60 min/hr * 24 hr/day * 365.25 283 | days/year * 10000 years' 284 | format: int64 285 | type: integer 286 | type: object 287 | quota: 288 | type: string 289 | strategy: 290 | type: string 291 | type: object 292 | condition: 293 | type: string 294 | custom_key: 295 | type: string 296 | custom_value: 297 | type: string 298 | match: 299 | items: 300 | properties: 301 | exact_match: 302 | description: If specified, header match will be 303 | performed based on the value of the header. 304 | type: string 305 | invert_match: 306 | description: If specified, the match result will 307 | be inverted before checking. Defaults to false. 308 | * The regex ``\d{3}`` does not match the value 309 | *1234*, so it will match when inverted. 310 | type: boolean 311 | is_exact_match_empty: 312 | description: if specified, the exact match the value 313 | "" 314 | type: boolean 315 | name: 316 | type: string 317 | prefix_match: 318 | description: '* The prefix *abcd* matches the value 319 | *abcdxyz*, but not for *abcxyz*.' 320 | type: string 321 | present_match: 322 | description: If specified as true, header match 323 | will be performed based on whether the header 324 | is in the request. If specified as false, header 325 | match will be performed based on whether the header 326 | is absent. 327 | type: boolean 328 | present_match_separate: 329 | description: similar to present_match, the difference 330 | is that the different values have separate token 331 | while present_match shares token it only works 332 | in envoy.filters.http.ratelimit (global) 333 | type: boolean 334 | regex_match: 335 | description: If specified, this regex string is 336 | a regular expression rule which implies the entire 337 | request header value must match the regex. The 338 | rule will not match if only a subsequence of the 339 | request header value matches the regex. 340 | type: string 341 | suffix_match: 342 | description: '* The suffix *abcd* matches the value 343 | *xyzabcd*, but not for *xyzbcd*.' 344 | type: string 345 | type: object 346 | type: array 347 | target: 348 | properties: 349 | direction: 350 | type: string 351 | host: 352 | items: 353 | type: string 354 | type: array 355 | port: 356 | format: int32 357 | type: integer 358 | route: 359 | items: 360 | type: string 361 | type: array 362 | type: object 363 | type: object 364 | type: array 365 | type: object 366 | description: subset rate-limit,the key is subset name. 367 | type: object 368 | target: 369 | description: rate limit target 370 | properties: 371 | direction: 372 | type: string 373 | host: 374 | items: 375 | type: string 376 | type: array 377 | port: 378 | format: int32 379 | type: integer 380 | route: 381 | items: 382 | type: string 383 | type: array 384 | type: object 385 | workloadSelector: 386 | additionalProperties: 387 | type: string 388 | description: workload selector , it should not be nil in Gateway Scenarios 389 | type: object 390 | type: object 391 | status: 392 | x-kubernetes-preserve-unknown-fields: true 393 | type: object 394 | type: object 395 | served: true 396 | storage: true 397 | subresources: 398 | status: {} 399 | -------------------------------------------------------------------------------- /install/helm/README.md: -------------------------------------------------------------------------------- 1 | # Hango Helm chart 2 | 3 | --Tree 4 | |- -------------------------------------------------------------------------------- /install/helm/hango-gateway/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: hango-gateway 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 0.1.0 24 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/apigw-demo/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: apigw-gateway 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | version: v1.20201029.6 18 | 19 | # This is the version number of the application being deployed. This version number should be 20 | # incremented each time you make changes to the application. 21 | appVersion: v1.20201029 22 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/apigw-demo/templates/apigw-demo-deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: istio-e2e-app 6 | namespace: {{ .Values.demo_namespace }} 7 | spec: 8 | progressDeadlineSeconds: 600 9 | replicas: 1 10 | revisionHistoryLimit: 10 11 | selector: 12 | matchLabels: 13 | app: istio-e2e-app 14 | name: istio-e2e-app 15 | version: v1 16 | template: 17 | metadata: 18 | creationTimestamp: null 19 | labels: 20 | app: istio-e2e-app 21 | name: istio-e2e-app 22 | security.istio.io/tlsMode: istio 23 | version: v1 24 | spec: 25 | containers: 26 | - args: 27 | - --port 28 | - "80" 29 | - --port 30 | - "8080" 31 | - --port 32 | - "90" 33 | - --port 34 | - "9090" 35 | - --grpc 36 | - "70" 37 | - --grpc 38 | - "7070" 39 | - --port 40 | - "3333" 41 | - --version 42 | - v1 43 | image: "{{ .Values.images.e2e_image }}" 44 | imagePullPolicy: IfNotPresent 45 | livenessProbe: 46 | failureThreshold: 10 47 | httpGet: 48 | path: /healthz 49 | port: 3333 50 | scheme: HTTP 51 | initialDelaySeconds: 10 52 | periodSeconds: 10 53 | successThreshold: 1 54 | timeoutSeconds: 1 55 | name: app 56 | ports: 57 | - containerPort: 3333 58 | name: tcp-health-port 59 | protocol: TCP 60 | readinessProbe: 61 | failureThreshold: 10 62 | initialDelaySeconds: 10 63 | periodSeconds: 10 64 | successThreshold: 1 65 | tcpSocket: 66 | port: tcp-health-port 67 | timeoutSeconds: 1 68 | resources: {} 69 | terminationMessagePath: /dev/termination-log 70 | terminationMessagePolicy: File 71 | dnsPolicy: ClusterFirst 72 | restartPolicy: Always 73 | schedulerName: default-scheduler 74 | securityContext: {} 75 | terminationGracePeriodSeconds: 30 -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/apigw-demo/templates/apigw-demo-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: istio-e2e-app 6 | name: istio-e2e-app 7 | namespace: {{ .Values.demo_namespace }} 8 | spec: 9 | ports: 10 | - name: http 11 | port: 80 12 | protocol: TCP 13 | targetPort: 80 14 | - name: http-two 15 | port: 8080 16 | protocol: TCP 17 | targetPort: 8080 18 | - name: tcp 19 | port: 90 20 | protocol: TCP 21 | targetPort: 90 22 | - name: tcp-two 23 | port: 9090 24 | protocol: TCP 25 | targetPort: 9090 26 | - name: http2-example 27 | port: 70 28 | protocol: TCP 29 | targetPort: 70 30 | - name: grpc 31 | port: 7070 32 | protocol: TCP 33 | targetPort: 7070 34 | selector: 35 | app: istio-e2e-app 36 | sessionAffinity: None 37 | type: ClusterIP 38 | status: 39 | loadBalancer: {} -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/apigw-demo/values.yaml: -------------------------------------------------------------------------------- 1 | images: 2 | e2e_image: docker.io/hangoio/istio_e2e_app:e2e-multi 3 | 4 | 5 | demo_namespace: hango-system 6 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/hango-gateway/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v3 2 | name: hango-gateway 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | version: v1.0 18 | 19 | # This is the version number of the application being deployed. This version number should be 20 | # incremented each time you make changes to the application. 21 | appVersion: v1.0 22 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/hango-gateway/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "apigw-gateway.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "apigw-gateway.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "apigw-gateway.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "apigw-gateway.labels" -}} 38 | helm.sh/chart: {{ include "apigw-gateway.chart" . }} 39 | {{ include "apigw-gateway.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end -}} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "apigw-gateway.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "apigw-gateway.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end -}} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "apigw-gateway.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create -}} 59 | {{ default (include "apigw-gateway.fullname" .) .Values.serviceAccount.name }} 60 | {{- else -}} 61 | {{ default "default" .Values.serviceAccount.name }} 62 | {{- end -}} 63 | {{- end -}} 64 | 65 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/hango-gateway/templates/base/hango-gateway/hango-gateway-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: hango-api-plane 6 | namespace: {{ .Values.namespace }} 7 | labels: 8 | app: hango-api-plane 9 | spec: 10 | type: ClusterIP 11 | ports: 12 | - port: 10880 13 | targetPort: 10880 14 | name: http 15 | selector: 16 | api-plane-container: hango-api-plane 17 | 18 | --- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: hango-portal 23 | namespace: {{ .Values.namespace }} 24 | labels: 25 | app: hango-portal 26 | spec: 27 | type: NodePort 28 | ports: 29 | - port: 80 30 | targetPort: 11113 31 | selector: 32 | portal-container: hango-portal 33 | 34 | --- 35 | apiVersion: v1 36 | kind: Service 37 | metadata: 38 | name: hango-ui 39 | namespace: {{ .Values.namespace }} 40 | labels: 41 | app: hango-ui 42 | spec: 43 | type: NodePort 44 | ports: 45 | - port: 8789 46 | targetPort: 8789 47 | protocol: TCP 48 | selector: 49 | app: hango-ui 50 | 51 | --- 52 | apiVersion: v1 53 | kind: Service 54 | metadata: 55 | name: istiod 56 | namespace: {{ .Values.namespace }} 57 | labels: 58 | app: istiod 59 | istio: pilot 60 | istio.io/rev: {{ .Values.istio_rev }} 61 | spec: 62 | ports: 63 | - port: 15010 64 | name: grpc-xds # plaintext 65 | - port: 15012 66 | name: https-dns # mTLS with k8s-signed cert 67 | - port: 443 68 | name: https-webhook # validation and injection 69 | targetPort: 15017 70 | - port: 15014 71 | name: http-monitoring # prometheus stats 72 | - port: 8080 73 | name: http-legacy-discovery 74 | selector: 75 | app: istiod 76 | istio.io/rev: {{ .Values.istio_rev }} 77 | 78 | --- 79 | apiVersion: v1 80 | kind: Service 81 | metadata: 82 | name: slime-hango 83 | namespace: {{ .Values.namespace }} 84 | labels: 85 | app: slime-hango 86 | spec: 87 | type: ClusterIP 88 | ports: 89 | - port: 80 90 | targetPort: http 91 | protocol: TCP 92 | name: http 93 | - port: 8081 94 | targetPort: aux-port 95 | protocol: TCP 96 | name: aux-port 97 | - name: mcp-over-xds 98 | port: 16010 99 | protocol: TCP 100 | targetPort: 16010 101 | selector: 102 | app: slime-hango 103 | 104 | --- 105 | --- 106 | apiVersion: v1 107 | kind: Service 108 | metadata: 109 | labels: 110 | app: hango-proxy 111 | name: hango-proxy 112 | namespace: {{ .Values.namespace }} 113 | spec: 114 | ports: 115 | - port: 80 116 | targetPort: 80 117 | protocol: TCP 118 | name: http 119 | - port: 443 120 | targetPort: 443 121 | protocol: TCP 122 | name: https 123 | - port: 8301 124 | targetPort: 8301 125 | protocol: TCP 126 | name: admin 127 | - port: 19000 128 | targetPort: 19000 129 | protocol: TCP 130 | name: stats 131 | selector: 132 | app: hango-proxy 133 | type: NodePort 134 | 135 | 136 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/hango-gateway/templates/base/hango-gateway/hango-gateway-serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: hango-apiplane 5 | namespace: {{ .Values.namespace }} 6 | 7 | --- 8 | apiVersion: v1 9 | kind: ServiceAccount 10 | metadata: 11 | name: istiod-service-account 12 | namespace: {{ .Values.namespace }} 13 | labels: 14 | app: istiod 15 | 16 | --- 17 | apiVersion: v1 18 | kind: ServiceAccount 19 | metadata: 20 | name: slime-hango 21 | namespace: {{ .Values.namespace }} 22 | labels: 23 | app: slime-hango 24 | 25 | 26 | --- 27 | apiVersion: rbac.authorization.k8s.io/v1 28 | kind: ClusterRoleBinding 29 | metadata: 30 | name: hango-apiplane 31 | roleRef: 32 | apiGroup: rbac.authorization.k8s.io 33 | kind: ClusterRole 34 | name: cluster-admin 35 | subjects: 36 | - kind: ServiceAccount 37 | name: hango-apiplane 38 | namespace: {{ .Values.namespace }} 39 | 40 | --- 41 | apiVersion: rbac.authorization.k8s.io/v1 42 | kind: ClusterRoleBinding 43 | metadata: 44 | name: slime-hango 45 | subjects: 46 | - kind: ServiceAccount 47 | name: slime-hango 48 | namespace: {{ .Values.namespace }} 49 | roleRef: 50 | kind: ClusterRole 51 | name: cluster-admin 52 | apiGroup: rbac.authorization.k8s.io 53 | 54 | --- 55 | apiVersion: rbac.authorization.k8s.io/v1 56 | kind: ClusterRoleBinding 57 | metadata: 58 | name: hango-istiod 59 | roleRef: 60 | apiGroup: rbac.authorization.k8s.io 61 | kind: ClusterRole 62 | name: cluster-admin 63 | subjects: 64 | - kind: ServiceAccount 65 | name: istiod-service-account 66 | namespace: {{ .Values.namespace }} 67 | 68 | --- 69 | apiVersion: security.istio.io/v1beta1 70 | kind: PeerAuthentication 71 | metadata: 72 | labels: 73 | istio.io/rev: {{ .Values.istio_rev }} 74 | name: istiod 75 | namespace: {{ .Values.namespace }} 76 | spec: 77 | mtls: 78 | mode: DISABLE 79 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/charts/hango-gateway/values.yaml: -------------------------------------------------------------------------------- 1 | data_dir: /data 2 | cluster_dns_domain: cluster.local 3 | 4 | images: 5 | hango_apiplane_image: hangoio/api-plane:1.6.1 6 | hango_portal_image: hangoio/hango-portal:1.6.0 7 | hango_ui_image: hangoio/hango-ui:v1.6.1-08432576 8 | istiod_image: docker.io/slimeio/pilot:hango-1.6.0-rc1 9 | slime_image: docker.io/slimeio/slime-bundle-hango:hango-v1.6.0 10 | hango_proxy_image: hangoio/envoy-proxy:hango-v1.6.0-rc1-b3c2851-unstripped 11 | 12 | namespace: hango-system 13 | 14 | replicas: 1 15 | istio_rev: gw-1.12 16 | 17 | gateway_xds_service_address: istiod.hango-system.svc.cluster.local 18 | gateway_xds_service_security_port: 15012 19 | gateway_xds_service_port: 15010 20 | gateway_cluster: hango-demo-gateway 21 | 22 | slime: 23 | cfg: 24 | global: 25 | log: 26 | klogLevel: 5 27 | logLevel: info 28 | misc: 29 | seLabelSelectorKeys: projectName 30 | 31 | registry: 32 | nacos: 33 | ## nacos注册中心功能开关(true 或 false) 34 | enable: false 35 | ## 注册中心实例地址;格式:整体以英文单引号包裹,单个地址以英文双引号包裹,多个地址用英文逗号分隔 36 | address: '"http://127.0.0.1:8848"' 37 | ## nacos客户端服务所在分组 38 | service_group: hango_demo 39 | eureka: 40 | ## eureka注册中心功能开关(true 或 false) 41 | enable: false 42 | ## 刷新eureka服务缓存的时间周期,默认15s,格式为: [正整数]s 43 | refresh_period: 15s 44 | ## 注册中心实例地址;格式:整体以英文单引号包裹,单个地址以英文双引号包裹,多个地址用英文逗号分隔 45 | address: '"http://127.0.0.1:8761/eureka"' 46 | zk: 47 | ## zookeeper注册中心功能开关(true 或 false) 48 | enable: false 49 | ## 刷新zookeeper服务缓存的时间周期,默认15s,格式为: [正整数]s 50 | refresh_period: 15s 51 | ## 注册中心实例地址;格式:整体以英文单引号包裹,单个地址以英文双引号包裹,多个地址用英文逗号分隔 52 | address: '"zookeeper.apigw-demo.svc.cluster.local:2181"' 53 | -------------------------------------------------------------------------------- /install/helm/hango-gateway/values.yaml: -------------------------------------------------------------------------------- 1 | Release: 2 | namepsace: hango-system -------------------------------------------------------------------------------- /install/init-hango/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HANGO_NAMESPACE=hango-system 4 | 5 | function init_hango(){ 6 | HANGO_PORTAL=`kubectl get svc -n $HANGO_NAMESPACE | grep hango-portal | awk '{print $3}'` 7 | HANGO_API_PLANE=`kubectl get svc -n $HANGO_NAMESPACE | grep hango-api-plane | awk '{print $3}'` 8 | HANGO_PROXY=`kubectl get svc -n $HANGO_NAMESPACE | grep hango-proxy | awk '{print $3}'` 9 | GW_CLUSTER_NAME="hango-demo-gateway" 10 | result=$(curl -s -w "%{http_code}" -o /dev/null -X POST "http://${HANGO_PORTAL}:80/gdashboard?Action=CreateGateway&Version=2022-10-30" \ 11 | -H 'Content-Type: application/json' \ 12 | -H "x-auth-accountId:admin" \ 13 | -H "x-auth-tenantId: 1" \ 14 | -H "x-auth-projectId: 1" \ 15 | -d '{ 16 | "Name":"hango_envoy_gateway", 17 | "EnvId":"1", 18 | "SvcType":"NodePort", 19 | "SvcName":"gateway-proxy", 20 | "Type":"envoy", 21 | "ConfAddr":"http://'"$HANGO_API_PLANE"':10880", 22 | "Description":"Hango网关", 23 | "GwClusterName":'\"${GW_CLUSTER_NAME}\"' 24 | }') 25 | if [[ $result -eq 200 ]]; then 26 | echo "Init hango success." 27 | else 28 | echo -e "\033[31mInit error\033[0m, init_hango can be run independently \n" 29 | echo -e "============================== Common mistakes ==============================\n" 30 | echo -e "1.The same gateway has been created, please go to the hango-console to check" 31 | echo -e "2.hango-portal is unhealthy, please check the hango-portal pod status" 32 | exit 1 33 | fi 34 | } 35 | 36 | # start init hango 37 | init_hango -------------------------------------------------------------------------------- /install/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## reentrant installation script for "Hango-Gateway" 4 | 5 | work_dir=$(cd $(dirname $0); pwd) 6 | 7 | # import common functions (log) 8 | source "${work_dir}"/common/common.sh 9 | 10 | helm_version="v0.0.0" 11 | HANGO_NAMESPACE="hango-system" 12 | MESH_OPERATOR_NAMESPACE="mesh-operator" 13 | # install shell home 14 | INIT_SHELL_DIR=$(cd "$(dirname "$0")";pwd) 15 | # crd home 16 | CRD_DIR=${INIT_SHELL_DIR}/crds 17 | 18 | function check_kubectl_ready() { 19 | kubectl version >/dev/null 2>&1 20 | if [[ $? -ne 0 ]]; then 21 | echo "Your k8s and kubectl are both ready? please check manually." 22 | return 1 23 | fi 24 | } 25 | 26 | function get_helm_version() { 27 | helm >/dev/null 2>&1 28 | if [[ $? -ne 0 ]]; then 29 | log "Please install helm first." 30 | return 1 31 | fi 32 | helm_version=$(helm version | awk -F "Version:" '{print $2}' | awk -F '"' '{print $2}') 33 | } 34 | 35 | # Check whether the version of helm is later than V3 36 | function helm_version_judge() { 37 | version_prefix=$(echo "${helm_version}" | awk -F "." '{print $1}') 38 | if [[ "${version_prefix}" = "v3" ]]; then 39 | return 0 40 | elif [[ "${version_prefix}" = "v2" ]]; then 41 | return 1 42 | else 43 | return 2 44 | fi 45 | } 46 | 47 | # prepare crds 48 | function prepare_for_crds() { 49 | for crd in `ls "${CRD_DIR}"`; do 50 | kubectl apply -f ${CRD_DIR}/${crd} 51 | if [ "$?" -ne 0 ]; then 52 | echo "kubectl apply crd failed, crd_name: ${CRD_DIR}/${crd}" 53 | return 1 54 | fi 55 | done 56 | } 57 | 58 | function helm_install_for_hango_component() { 59 | helm_version_judge 60 | if [[ $? -eq 0 ]]; then 61 | # 3.x version above 62 | helm install --namespace "${HANGO_NAMESPACE}" hango-gateway "${work_dir}"/helm/hango-gateway/ & 63 | elif [[ $? -eq 1 ]]; then 64 | # 2.x version above 65 | helm install --namespace "${HANGO_NAMESPACE}" --name hango-gateway "${work_dir}"/helm/hango-gateway/ & 66 | else 67 | log "Your helm version is too old, please update to 3.x version above." 68 | exit 1 69 | fi 70 | } 71 | 72 | function verify_hango_install() { 73 | jq -V > /dev/null 2>&1 74 | if [[ $? -ne 0 ]]; then 75 | log "Unable to find jq command, skipping service readiness check." 76 | return 0 77 | fi 78 | sleep 1 79 | 80 | while true; do 81 | # 获取命名空间中所有的 Deployment 名称 82 | DEPLOYMENTS="$(kubectl get deploy -n ${HANGO_NAMESPACE} -o jsonpath='{.items[*].metadata.name}')" 83 | 84 | # 遍历所有的 Deployment 85 | for DEPLOYMENT_NAME in ${DEPLOYMENTS}; do 86 | # 获取 Deployment 的当前状态 87 | DEPLOYMENT_STATUS="$(kubectl get deployment ${DEPLOYMENT_NAME} -n ${HANGO_NAMESPACE} -o jsonpath='{.status}')" 88 | 89 | # 解析 Deployment 可用 Pod 的数量和总数 90 | AVAILABLE="$(echo ${DEPLOYMENT_STATUS} | jq -r '.availableReplicas')" 91 | DESIRED="$(echo ${DEPLOYMENT_STATUS} | jq -r '.replicas')" 92 | 93 | # 判断 Deployment 是否就绪 94 | if [[ ${AVAILABLE} -eq ${DESIRED} ]]; then 95 | echo "Deployment ${DEPLOYMENT_NAME} is ready." 96 | fi 97 | done 98 | 99 | # 所有的 Deployment 都就绪,退出循环 100 | echo "All deployments have been successfully created and are waiting for the Pods to be ready." 101 | break 102 | 103 | sleep 2 104 | done 105 | } 106 | 107 | function init_for_namespaces() { 108 | kubectl create ns "${HANGO_NAMESPACE}" 109 | } 110 | 111 | 112 | # main entry for this shell script 113 | function main() { 114 | check_kubectl_ready || exit 1 115 | get_helm_version || exit 1 116 | prepare_for_crds || exit 1 117 | log "start to init namespaces." 118 | init_for_namespaces 119 | log "start to init hango components(asynchronously), you are supposed to check their status manually." 120 | helm_install_for_hango_component 121 | log "install finished!" 122 | log "start to verify hango install" 123 | verify_hango_install 124 | sleep 1s 125 | echo "Please create gateway manually (to use shell script install/init-hango/init.sh after the Pod is ready)" 126 | } 127 | 128 | # start installation process 129 | main 130 | -------------------------------------------------------------------------------- /install/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## uninstall script for "Hango-Gateway" 4 | 5 | work_dir=$(cd $(dirname $0); pwd) 6 | 7 | # import common functions (log) 8 | source "${work_dir}"/common/common.sh 9 | 10 | LOG_PREFIX="hango_uninstall" 11 | DATA_FORMAT="+%H:%M:%S" 12 | HANGO_SYSTEM_NAMESPACE="hango-system" 13 | 14 | 15 | log "start to uninstall hango components." 16 | helm status hango-gateway -n hango-system >/dev/null 2>&1 17 | if [[ $? -ne 0 ]]; then 18 | echo "helm component hango-gateway not exists, no need to delete" 19 | else 20 | helm delete hango-gateway -n hango-system 21 | fi 22 | 23 | log "start to uninstall namespace[${HANGO_SYSTEM_NAMESPACE}]" 24 | kubectl get ns "${HANGO_SYSTEM_NAMESPACE}" >/dev/null 2>&1 25 | if [[ $? -eq 0 ]]; then 26 | kubectl delete ns "${HANGO_SYSTEM_NAMESPACE}" 27 | fi 28 | 29 | log "start to delete k8s crd of hango" 30 | kubectl get crd | grep -E "slime|istio" >/dev/null 2>&1 31 | if [[ $? -eq 0 ]]; then 32 | kubectl get crd | grep -E "slime|istio" | awk '{print $1}' | xargs kubectl delete crd 33 | fi 34 | 35 | log "uninstall finished!" -------------------------------------------------------------------------------- /projects/README.md: -------------------------------------------------------------------------------- 1 | [//]:#(TODO) 2 | # Components -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Test 2 | ## Using Python to Test Hango 3 | 4 | * Install python 2.7 5 | * run python hango-test.py 6 | 7 | -------------------------------------------------------------------------------- /test/const.py: -------------------------------------------------------------------------------- 1 | class _const: 2 | class ConstError(TypeError):pass 3 | def __setattr__(self,name,value): 4 | if name in self.__dict__: 5 | raise self.ConstError("Can't rebind const (%s)" %name) 6 | self.__dict__[name]=value -------------------------------------------------------------------------------- /test/hango-test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import requests 3 | import json 4 | import time 5 | import const 6 | import commands 7 | import sys 8 | 9 | # 等待后续版本进行适配 10 | print("Please wait for the test future online...") 11 | sys.exit() 12 | 13 | const.PORTAL = commands.getoutput("kubectl get svc -n hango-system | grep hango-portal | awk '{print $3}'") 14 | const.APP = "istio-e2e-app.hango-system.svc.cluster.local" 15 | const.GW = commands.getoutput("kubectl get svc -n hango-system | grep hango-proxy | awk '{print $3}'") 16 | 17 | def get_gw(): 18 | url = "http://" + const.PORTAL + \ 19 | "/gdashboard?Action=DescribeGatewayList&Version=2018-08-09" 20 | r = requests.get(url) 21 | if(200 == r.status_code): 22 | gws = json.loads(r.text)["GatewayInfos"] 23 | gw_id = gws[0].get("GwId") 24 | return gw_id 25 | 26 | 27 | def create_service(): 28 | url = "http://" + const.PORTAL + \ 29 | "/gdashboard?Action=CreateService&Version=2018-08-09" 30 | data = ''' 31 | { 32 | "ServiceType":"http", 33 | "ServiceName":"hango-test", 34 | "ServiceTag":"hango-test", 35 | "Contacts":"admin" 36 | } 37 | ''' 38 | headers = {'content-type': 'application/json'} 39 | r = requests.post(url, data=data, headers=headers) 40 | if(200 == r.status_code): 41 | print("create service ok") 42 | service_id = json.loads(r.text)["Result"] 43 | print('service_id:' + str(service_id)) 44 | return service_id 45 | else: 46 | print("create service error") 47 | print('error info: ' + r.text) 48 | 49 | 50 | def create_route(service_id): 51 | url = "http://" + const.PORTAL + \ 52 | "/gdashboard/envoy?Action=CreateRouteRule&Version=2019-09-01" 53 | data = { 54 | "RouteRuleName": "hango-route-unit", 55 | "Uri": { 56 | "Type": "prefix", 57 | "Value": [ 58 | "/hango/unit" 59 | ] 60 | }, 61 | "Priority": 50, 62 | "ServiceId": service_id 63 | } 64 | 65 | headers = {'content-type': 'application/json'} 66 | r = requests.post(url, data=json.dumps(data), headers=headers) 67 | if(201 == r.status_code): 68 | print("create route ok") 69 | route_id = json.loads(r.text)["RouteRuleId"] 70 | print('RouteRuleId:' + str(route_id)) 71 | return route_id 72 | else: 73 | print("create route error") 74 | print('error info: ' + r.text) 75 | 76 | 77 | def publish_service(service_id, gw_id): 78 | url = "http://" + const.PORTAL + \ 79 | "/gdashboard/envoy?Action=PublishService&Version=2019-09-01" 80 | data = { 81 | "GwId": gw_id, 82 | "ServiceId": service_id, 83 | "PublishType": "DYNAMIC", 84 | "BackendService": const.APP, 85 | "PublishProtocol": "http", 86 | "RegistryCenterType": "Kubernetes", 87 | } 88 | 89 | headers = {'content-type': 'application/json'} 90 | r = requests.post(url, data=json.dumps(data), headers=headers) 91 | if(200 == r.status_code): 92 | print("publish service ok") 93 | else: 94 | print("publish service error") 95 | print('error info: ' + r.text) 96 | 97 | 98 | def publish_route(route_id, service_id, gw_id): 99 | url = "http://" + const.PORTAL + \ 100 | "/gdashboard/envoy?Action=PublishRouteRule&Version=2019-09-01" 101 | data = { 102 | "GwId": gw_id, 103 | "RouteRuleId": route_id, 104 | "DestinationServices": [ 105 | { 106 | "Port": "80", 107 | "Weight": 100, 108 | "ServiceId": service_id 109 | } 110 | ] 111 | } 112 | # data = data = {"GwId":1,"EnableState":"enable","Timeout":"60000","DestinationServices":[{"BackendService":"wewef","Weight":100,"ServiceId":1}],"ServiceId":1,"RouteRuleId":22} 113 | 114 | headers = {'content-type': 'application/json'} 115 | r = requests.post(url, data=json.dumps(data), headers=headers) 116 | if(200 == r.status_code): 117 | print("publish route ok") 118 | else: 119 | print("publish route error") 120 | print('error info: ' + r.text) 121 | 122 | 123 | def describe_plugin_id(route_id, gw_id, plugin_type): 124 | url = "http://" + const.PORTAL + \ 125 | "/gdashboard/envoy?Action=DescribeBindingPlugins&Version=2019-09-01" 126 | PARAMS = {'BindingObjectId': route_id, 'GwId': gw_id, 'BindingObjectType':'routeRule'} 127 | r = requests.get(url, params=PARAMS) 128 | if(200 == r.status_code): 129 | pls = json.loads(r.text)["PluginBindingList"] 130 | for pl in pls: 131 | if pl.get("PluginType") == plugin_type: 132 | return pl.get("PluginBindingInfoId") 133 | 134 | def offline_plugin(plugin_binding_id, plugin_type): 135 | url = "http://" + const.PORTAL + \ 136 | "/gdashboard/envoy?Action=UnbindingPlugin&Version=2019-09-01" 137 | PARAMS = {'PluginBindingInfoId': plugin_binding_id} 138 | r = requests.get(url, params=PARAMS) 139 | if(200 == r.status_code): 140 | print("offline plugin " + plugin_type +" ok") 141 | 142 | def offline_route(route_id, gw_id): 143 | url = "http://" + const.PORTAL + \ 144 | "/gdashboard/envoy?Action=DeletePublishedRouteRule&Version=2019-09-01" 145 | PARAMS = {'RouteRuleId': route_id, 'GwId': gw_id} 146 | r = requests.get(url, params=PARAMS) 147 | if(200 == r.status_code): 148 | print("offline route ok") 149 | else: 150 | print("offline route error") 151 | print('error info: ' + r.text) 152 | 153 | 154 | def offline_service(service_id, gw_id): 155 | url = "http://" + const.PORTAL + \ 156 | "/gdashboard/envoy?Action=DeleteServiceProxy&Version=2019-09-01" 157 | PARAMS = {'ServiceId': service_id, 'GwId': gw_id} 158 | r = requests.get(url, params=PARAMS) 159 | if(200 == r.status_code): 160 | print("offline service ok") 161 | else: 162 | print("offline service error") 163 | print('error info: ' + r.text) 164 | 165 | 166 | def delete_route(route_id): 167 | url = "http://" + const.PORTAL + \ 168 | "/gdashboard/envoy?Action=DeleteRouteRule&Version=2019-09-01" 169 | PARAMS = {'RouteRuleId': route_id} 170 | r = requests.get(url, params=PARAMS) 171 | if(200 == r.status_code): 172 | print("delete route ok") 173 | else: 174 | print("delete route error") 175 | print('error info: ' + r.text) 176 | 177 | 178 | def delete_service(service_id): 179 | url = "http://" + const.PORTAL + \ 180 | "/gdashboard?Action=DeleteService&Version=2018-08-09" 181 | PARAMS = {'ServiceId': service_id} 182 | r = requests.get(url, params=PARAMS) 183 | if(200 == r.status_code): 184 | print("delete service ok") 185 | else: 186 | print("delete service error") 187 | print('error info: ' + r.text) 188 | 189 | 190 | def bind_plugin(rout_id, gw_id, plugin_type, plugin_conf): 191 | url = "http://" + const.PORTAL + \ 192 | "/gdashboard/envoy?Action=BindingPlugin&Version=2019-09-01" 193 | data = { 194 | "BindingObjectId": rout_id, 195 | "BindingObjectType": "routeRule", 196 | "GwId": gw_id, 197 | "PluginConfiguration": plugin_conf, 198 | "PluginType": plugin_type 199 | } 200 | 201 | headers = {'content-type': 'application/json'} 202 | r = requests.post(url, data=json.dumps(data), headers=headers) 203 | if(200 == r.status_code): 204 | print("bingding plugin " + plugin_type + " -------------ok") 205 | 206 | 207 | def invoke_gw(add_headers=None, add_params=None): 208 | url = "http://" + const.GW + "/hango/unit" 209 | HEADERS = {'host': 'istio.com'} 210 | PARAMS = {} 211 | if add_headers is not None: 212 | HEADERS = HEADERS.copy() 213 | HEADERS.update(add_headers) 214 | if add_params is not None: 215 | PARAMS.update(add_params) 216 | r = requests.get(url, headers=HEADERS, params=PARAMS) 217 | return r.status_code 218 | 219 | def invoke_gw_return_h(add_headers=None): 220 | url = "http://" + const.GW + "/hango/unit" 221 | HEADERS = {'host': 'istio.com'} 222 | if add_headers is not None: 223 | HEADERS = HEADERS.copy() 224 | HEADERS.update(add_headers) 225 | r = requests.get(url, headers=HEADERS) 226 | return r.headers 227 | 228 | 229 | gw_id = get_gw() 230 | 231 | service_id = create_service() 232 | route_id = create_route(service_id) 233 | publish_service(service_id, gw_id) 234 | publish_route(route_id, service_id, gw_id) 235 | 236 | # 首次调用,sleep 5s, 配置加载 237 | time.sleep(5) 238 | if(200 == invoke_gw()): 239 | print("invode_gw OK---------------/hango/unit") 240 | 241 | # ip 黑白名单测试 242 | ip_res = "{\"type\":\"0\",\"list\":[\"127.0.0.1\"],\"kind\":\"ip-restriction\"}" 243 | bind_plugin(route_id, gw_id, "ip-restriction", ip_res) 244 | ip_local = {'x-hango-real-ip': '127.0.0.1'} 245 | time.sleep(2) 246 | if(403 == invoke_gw(ip_local)): 247 | print("invode_gw ip-restriction plugin ok---------------ip-restriction") 248 | 249 | # 本地限流测试,local-limiting 250 | local_limit = "{\"limit_by_list\":[{\"headers\":[],\"minute\":5}],\"kind\":\"local-limiting\",\"name\":\"local-limiting\"}" 251 | bind_plugin(route_id, gw_id, "local-limiting", local_limit) 252 | 253 | for i in range(50): 254 | if(429 == invoke_gw()): 255 | print("invode_gw local-limit plugin ok---------------local-limit") 256 | break 257 | 258 | # offline locallimit 259 | offline_plugin(describe_plugin_id(route_id, gw_id, "local-limiting"), "local-limiting") 260 | time.sleep(2) 261 | 262 | # UA黑白名单,ua-restriction 263 | ua_restriction = "{\"type\": \"0\",\"list\": [{\"match_type\": \"exact_match\",\"value\": [\"bot\"]}],\"kind\": \"ua-restriction\"}" 264 | bind_plugin(route_id, gw_id, "ua-restriction", ua_restriction) 265 | time.sleep(2) 266 | ua_local = {'User-Agent': 'bot'} 267 | if(403 == invoke_gw(ua_local)): 268 | print("invode_gw ua-restriction plugin ok---------------ua-restriction") 269 | 270 | # URI黑白名单,uri-restriction 271 | uri_restriction = "{\"kind\":\"uri-restriction\",\"type\":\"lua\",\"config\":{\"allowlist\":[],\"denylist\":[\"d1\"]}}" 272 | bind_plugin(route_id, gw_id, "uri-restriction", uri_restriction) 273 | time.sleep(2) 274 | uri_params = {'d': 'd1'} 275 | if(403 == invoke_gw(None, uri_params)): 276 | print("invode_gw uri-restriction plugin ok---------------uri-restriction") 277 | 278 | # Header黑白名单,header-restriction 279 | header_restriction = "{\"type\":\"0\",\"list\":[{\"header\":\"header_test\",\"match_type\":\"exact_match\",\"value\":[\"black\"]}],\"kind\":\"header-restriction\"}" 280 | bind_plugin(route_id, gw_id, "header-restriction", header_restriction) 281 | time.sleep(2) 282 | header_local = {'header_test': 'black'} 283 | if(403 == invoke_gw(header_local)): 284 | print("invode_gw header-restriction plugin ok---------------header-restriction") 285 | 286 | # 百分比限流测试,percent-limit 287 | percent_limit = "{\"limit_percent\":50,\"kind\":\"percent-limit\",\"name\":\"percent-limit\"}" 288 | bind_plugin(route_id, gw_id, "percent-limit", percent_limit) 289 | 290 | for i in range(50): 291 | if(429 == invoke_gw()): 292 | print("invode_gw percent-limit plugin ok---------------percent-limit") 293 | break 294 | 295 | # offline percentlimit 296 | offline_plugin(describe_plugin_id(route_id, gw_id, "percent-limit"), "percent-limit") 297 | time.sleep(2) 298 | 299 | 300 | # 本地缓存插件, local-cache 301 | local_cache = "{\"condition\":{\"request\":{\"requestSwitch\":false},\"response\":{\"responseSwitch\":true,\"code\":{\"match_type\":\"exact_match\",\"value\":\"200\"},\"headers\":[]}},\"ttl\":{\"local\":{\"default\":\"30000\",\"custom\":[]}},\"kind\":\"local-cache\",\"keyMaker\":{\"excludeHost\":false,\"ignoreCase\":true,\"queryString\":[],\"headers\":[]}}" 302 | bind_plugin(route_id, gw_id, "local-cache", local_cache) 303 | time.sleep(2) 304 | for i in range(50): 305 | r_headers = invoke_gw_return_h() 306 | if "HIT" == r_headers.get("x-cache-status"): 307 | print("invode_gw local-cache plugin ok---------------local-cache") 308 | break 309 | 310 | offline_route(route_id, gw_id) 311 | offline_service(service_id, gw_id) 312 | delete_route(route_id) 313 | delete_service(service_id) 314 | 315 | -------------------------------------------------------------------------------- /tools/code style/Hango_Java_Code_Style.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | --------------------------------------------------------------------------------