mirror of
https://github.com/alibaba/higress.git
synced 2026-02-25 21:21:01 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a64d89704e | ||
|
|
b2b4f72775 | ||
|
|
7dfc42fd92 | ||
|
|
399dcb1ead | ||
|
|
810ef8f80b | ||
|
|
0dc69d5941 | ||
|
|
51e1804c5c |
135
.cursor/rules/plugin-development.mdc
Normal file
135
.cursor/rules/plugin-development.mdc
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
description: Plugin Development Standards - Applies to all new wasm and golang-filter plugins
|
||||
globs:
|
||||
- "plugins/wasm-go/extensions/*/**"
|
||||
- "plugins/wasm-cpp/extensions/*/**"
|
||||
- "plugins/wasm-rust/extensions/*/**"
|
||||
- "plugins/wasm-assemblyscript/extensions/*/**"
|
||||
- "plugins/golang-filter/*/**"
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Plugin Development Standards
|
||||
|
||||
## Strict Requirements for New Independent Plugins
|
||||
|
||||
When creating **new independent plugins** (e.g., newly implemented wasm plugins or golang-filter plugins), you **MUST** follow these standards:
|
||||
|
||||
### 1. Design Documentation Directory Requirements
|
||||
|
||||
- You **MUST** create a `design/` directory within the plugin directory
|
||||
- Directory structure example:
|
||||
```
|
||||
plugins/wasm-go/extensions/my-new-plugin/
|
||||
├── design/
|
||||
│ ├── design-doc.md # Design document
|
||||
│ ├── architecture.md # Architecture (optional)
|
||||
│ └── requirements.md # Requirements (optional)
|
||||
├── main.go
|
||||
├── go.mod
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### 2. Design Documentation Content Requirements
|
||||
|
||||
The design documentation in the `design/` directory should include:
|
||||
|
||||
- **Plugin Purpose and Use Cases**: Clearly explain what problem the plugin solves
|
||||
- **Core Functionality Design**: Detailed description of main features and implementation approach
|
||||
- **Configuration Parameters**: List all configuration items and their meanings
|
||||
- **Technology Selection and Dependencies**: Explain the technology stack and third-party libraries used
|
||||
- **Boundary Conditions and Limitations**: Define the applicable scope and limitations of the plugin
|
||||
- **Testing Strategy**: How to verify plugin functionality
|
||||
|
||||
### 3. Documentation Provided to AI Coding Tools
|
||||
|
||||
If you are using AI Coding tools (such as Cursor, GitHub Copilot, etc.) to generate code:
|
||||
|
||||
- You **MUST** save the complete design documents, requirement descriptions, and prompts you provided to the AI in the `design/` directory
|
||||
- Recommended file naming:
|
||||
- `ai-prompts.md` - AI prompts record
|
||||
- `design-doc.md` - Complete design document
|
||||
- `requirements.md` - Feature requirements list
|
||||
|
||||
### 4. Files NOT to Commit to Git
|
||||
|
||||
Note: The following files should **NOT** be committed to Git:
|
||||
- AI Coding tool work summary documents (should be placed in PR description)
|
||||
- Temporary feature change summary documents
|
||||
|
||||
Design documents in the `design/` directory **SHOULD** be committed to Git, as they serve as the design basis and technical documentation for the plugin.
|
||||
|
||||
## Examples
|
||||
|
||||
### Good Plugin Directory Structure Example
|
||||
|
||||
```
|
||||
plugins/wasm-go/extensions/ai-security-guard/
|
||||
├── design/
|
||||
│ ├── design-doc.md # ✅ Detailed design document
|
||||
│ ├── ai-prompts.md # ✅ Prompts provided to AI
|
||||
│ └── architecture.png # ✅ Architecture diagram
|
||||
├── main.go
|
||||
├── config.go
|
||||
├── README.md
|
||||
└── go.mod
|
||||
```
|
||||
|
||||
### Design Document Template
|
||||
|
||||
When creating `design/design-doc.md`, you can refer to the following template:
|
||||
|
||||
```markdown
|
||||
# [Plugin Name] Design Document
|
||||
|
||||
## Overview
|
||||
- Plugin purpose
|
||||
- Problem it solves
|
||||
- Target users
|
||||
|
||||
## Functional Design
|
||||
### Core Feature 1
|
||||
- Feature description
|
||||
- Implementation approach
|
||||
- Key code logic
|
||||
|
||||
### Core Feature 2
|
||||
...
|
||||
|
||||
## Configuration Parameters
|
||||
| Parameter | Type | Required | Description | Default |
|
||||
|-----------|------|----------|-------------|---------|
|
||||
| ... | ... | ... | ... | ... |
|
||||
|
||||
## Technical Implementation
|
||||
- Technology selection
|
||||
- Dependencies
|
||||
- Performance considerations
|
||||
|
||||
## Test Plan
|
||||
- Unit tests
|
||||
- Integration tests
|
||||
- Boundary tests
|
||||
|
||||
## Limitations and Notes
|
||||
- Known limitations
|
||||
- Usage recommendations
|
||||
```
|
||||
|
||||
## Execution Checklist
|
||||
|
||||
When creating a new plugin, please confirm:
|
||||
|
||||
- [ ] Created `design/` directory within the plugin directory
|
||||
- [ ] Placed design documentation in the `design/` directory
|
||||
- [ ] If using AI Coding tools, saved prompts/requirement documents in the `design/` directory
|
||||
- [ ] Prepared AI Coding tool work summary (for PR description)
|
||||
- [ ] Design documentation is complete with necessary technical details
|
||||
|
||||
## Tips
|
||||
|
||||
- Design documentation is important technical documentation for the plugin, helpful for:
|
||||
- Understanding design intent during code review
|
||||
- Quickly understanding implementation approach during future maintenance
|
||||
- Learning and reference for other developers
|
||||
- Tracing the reasoning behind design decisions
|
||||
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,17 +1,51 @@
|
||||
<!-- Please make sure you have read and understood the contributing guidelines -->
|
||||
|
||||
### Ⅰ. Describe what this PR did
|
||||
## Ⅰ. Describe what this PR did
|
||||
|
||||
|
||||
### Ⅱ. Does this pull request fix one issue?
|
||||
## Ⅱ. Does this pull request fix one issue?
|
||||
<!-- If that, add "fixes #xxx" below in the next line, for example, fixes #97. -->
|
||||
|
||||
|
||||
### Ⅲ. Why don't you add test cases (unit test/integration test)?
|
||||
## Ⅲ. Why don't you add test cases (unit test/integration test)?
|
||||
|
||||
|
||||
### Ⅳ. Describe how to verify it
|
||||
## Ⅳ. Describe how to verify it
|
||||
|
||||
|
||||
## Ⅴ. Special notes for reviews
|
||||
|
||||
|
||||
## Ⅵ. AI Coding Tool Usage Checklist (if applicable)
|
||||
<!--
|
||||
**IMPORTANT**: If you used AI Coding tools (e.g., Cursor, GitHub Copilot, etc.) to generate this PR, please check the following items.
|
||||
PRs that don't meet these requirements will have **LOWER REVIEW PRIORITY** and we **CANNOT GUARANTEE** timely reviews.
|
||||
|
||||
If you did NOT use AI Coding tools, you can skip this section entirely.
|
||||
-->
|
||||
|
||||
**Please check all applicable items:**
|
||||
|
||||
- [ ] **For new standalone features** (e.g., new wasm plugin or golang-filter plugin):
|
||||
- [ ] I have created a `design/` directory in the plugin folder
|
||||
- [ ] I have added the design document to the `design/` directory
|
||||
- [ ] I have included the AI Coding summary below
|
||||
|
||||
- [ ] **For regular updates/changes** (not new plugins):
|
||||
- [ ] I have provided the prompts/instructions I gave to the AI Coding tool below
|
||||
- [ ] I have included the AI Coding summary below
|
||||
|
||||
### AI Coding Prompts (for regular updates)
|
||||
<!-- Paste the prompts/instructions you provided to the AI Coding tool -->
|
||||
|
||||
|
||||
### AI Coding Summary
|
||||
<!--
|
||||
AI Coding tool should provide a summary after completing the work, including:
|
||||
- Key decisions made
|
||||
- Major changes implemented
|
||||
- Important considerations or limitations
|
||||
-->
|
||||
|
||||
|
||||
### Ⅴ. Special notes for reviews
|
||||
|
||||
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -1,17 +1,17 @@
|
||||
[submodule "istio/api"]
|
||||
path = istio/api
|
||||
url = https://github.com/higress-group/api
|
||||
branch = istio-1.19
|
||||
branch = istio-1.27
|
||||
shallow = true
|
||||
[submodule "istio/istio"]
|
||||
path = istio/istio
|
||||
url = https://github.com/higress-group/istio
|
||||
branch = istio-1.19
|
||||
branch = istio-1.27
|
||||
shallow = true
|
||||
[submodule "istio/client-go"]
|
||||
path = istio/client-go
|
||||
url = https://github.com/higress-group/client-go
|
||||
branch = istio-1.19
|
||||
branch = istio-1.27
|
||||
shallow = true
|
||||
[submodule "istio/pkg"]
|
||||
path = istio/pkg
|
||||
@@ -26,7 +26,7 @@
|
||||
[submodule "envoy/go-control-plane"]
|
||||
path = envoy/go-control-plane
|
||||
url = https://github.com/higress-group/go-control-plane
|
||||
branch = istio-1.19
|
||||
branch = istio-1.27
|
||||
shallow = true
|
||||
[submodule "envoy/envoy"]
|
||||
path = envoy/envoy
|
||||
|
||||
@@ -35,6 +35,7 @@ header:
|
||||
- 'hgctl/pkg/manifests'
|
||||
- 'pkg/ingress/kube/gateway/istio/testdata'
|
||||
- 'release-notes/**'
|
||||
- '.cursor/**'
|
||||
|
||||
comment: on-failure
|
||||
dependency:
|
||||
|
||||
@@ -169,6 +169,31 @@ git config --get user.email
|
||||
|
||||
PR 是更改 Higress 项目文件的唯一方法。为了帮助审查人更好地理解你的目的,PR 描述不能太详细。我们鼓励贡献者遵循 [PR 模板](./.github/PULL_REQUEST_TEMPLATE.md) 来完成拉取请求。
|
||||
|
||||
#### 使用 AI Coding 工具的特殊要求
|
||||
|
||||
如果你使用 AI Coding 工具(如 Cursor、GitHub Copilot 等)来生成 PR,我们有以下**严格要求**:
|
||||
|
||||
**针对新增独立插件的场景**(例如新实现的 wasm 插件或 golang-filter 插件):
|
||||
- 你**必须**在插件目录下创建 `design/` 目录
|
||||
- 将你提供给 AI Coding 工具的设计文档放在 `design/` 目录中
|
||||
- 在 PR 描述中提供 AI Coding 工具生成的工作总结
|
||||
|
||||
**针对日常更新/修改的场景**:
|
||||
- 在 PR 描述中提供你给 AI Coding 工具的提示词/指令
|
||||
- 在 PR 描述中提供 AI Coding 工具生成的工作总结
|
||||
|
||||
**AI Coding 工作总结应包括**:
|
||||
- 做出的关键决策
|
||||
- 实现的主要更改
|
||||
- 重要的注意事项或限制
|
||||
|
||||
**Review 优先级说明**:
|
||||
- 如果你使用了 AI Coding 工具但没有按照上述要求操作,你的 PR review 优先级将会**降低**
|
||||
- 我们**无法保证**对不符合要求的 AI Coding PR 进行及时 review
|
||||
- 如果不是使用 AI Coding 工具完成的 PR,则不需要遵循这些额外要求
|
||||
|
||||
这些要求的目的是确保使用 AI 生成的代码具有充分的文档记录和可追溯性,便于代码审查和后续维护。通过要求提供提示词/设计文档,我们可以更好地理解开发意图和上下文。
|
||||
|
||||
### 开发前准备
|
||||
|
||||
```shell
|
||||
|
||||
@@ -169,6 +169,31 @@ No matter commit message, or commit content, we do take more emphasis on code re
|
||||
|
||||
PR is the only way to make change to Higress project files. To help reviewers better get your purpose, PR description could not be too detailed. We encourage contributors to follow the [PR template](./.github/PULL_REQUEST_TEMPLATE.md) to finish the pull request.
|
||||
|
||||
#### Special Requirements for AI Coding Tool Usage
|
||||
|
||||
If you use AI Coding tools (such as Cursor, GitHub Copilot, etc.) to generate PRs, we have the following **strict requirements**:
|
||||
|
||||
**For new standalone plugin scenarios** (e.g., newly implemented wasm plugins or golang-filter plugins):
|
||||
- You **MUST** create a `design/` directory under the plugin directory
|
||||
- Place the design document you provided to the AI Coding tool in the `design/` directory
|
||||
- Provide an AI Coding summary in the PR description
|
||||
|
||||
**For regular updates/changes scenarios**:
|
||||
- Provide the prompts/instructions you gave to the AI Coding tool in the PR description
|
||||
- Provide an AI Coding summary in the PR description
|
||||
|
||||
**AI Coding Summary should include**:
|
||||
- Key decisions made
|
||||
- Major changes implemented
|
||||
- Important considerations or limitations
|
||||
|
||||
**Review Priority Notice**:
|
||||
- If you use AI Coding tools but do not follow the above requirements, your PR review priority will be **lowered**
|
||||
- We **cannot guarantee** timely reviews for AI Coding PRs that do not meet these requirements
|
||||
- If the PR is not completed using AI Coding tools, these additional requirements do not apply
|
||||
|
||||
The purpose of these requirements is to ensure that AI-generated code is adequately documented and traceable, facilitating code review and subsequent maintenance. By requiring prompts/design documents, we can better understand the development intent and context.
|
||||
|
||||
### Pre-development preparation
|
||||
|
||||
```shell
|
||||
|
||||
@@ -164,6 +164,31 @@ git config --get user.email
|
||||
|
||||
PR は Higress プロジェクトファイルを変更する唯一の方法です。レビュアーが目的をよりよく理解できるようにするために、PR 説明は詳細すぎることはありません。貢献者には、[PR テンプレート](./.github/PULL_REQUEST_TEMPLATE.md) に従ってプルリクエストを完了することを奨励します。
|
||||
|
||||
#### AI Coding ツール使用時の特別な要件
|
||||
|
||||
AI Coding ツール(Cursor、GitHub Copilot など)を使用して PR を生成する場合、以下の**厳格な要件**があります:
|
||||
|
||||
**新規独立プラグインのシナリオ**(新しく実装された wasm プラグインや golang-filter プラグインなど)の場合:
|
||||
- プラグインディレクトリの下に `design/` ディレクトリを作成する**必要があります**
|
||||
- AI Coding ツールに提供した設計ドキュメントを `design/` ディレクトリに配置してください
|
||||
- PR の説明に AI Coding サマリーを提供してください
|
||||
|
||||
**通常の更新/変更のシナリオ**の場合:
|
||||
- PR の説明に AI Coding ツールに与えたプロンプト/指示を提供してください
|
||||
- PR の説明に AI Coding サマリーを提供してください
|
||||
|
||||
**AI Coding サマリーには以下を含める必要があります**:
|
||||
- 行われた重要な決定
|
||||
- 実装された主要な変更
|
||||
- 重要な考慮事項または制限事項
|
||||
|
||||
**レビュー優先度に関する通知**:
|
||||
- AI Coding ツールを使用したが上記の要件に従わなかった場合、PR のレビュー優先度が**低下**します
|
||||
- 要件を満たしていない AI Coding PR に対して、タイムリーなレビューを**保証できません**
|
||||
- AI Coding ツールを使用せずに完了した PR の場合、これらの追加要件は適用されません
|
||||
|
||||
これらの要件の目的は、AI で生成されたコードが十分に文書化され、追跡可能であることを保証し、コードレビューと後続のメンテナンスを容易にすることです。プロンプト/設計ドキュメントを要求することで、開発意図とコンテキストをより良く理解できます。
|
||||
|
||||
### 開発前の準備
|
||||
|
||||
```shell
|
||||
|
||||
@@ -56,8 +56,31 @@ $(OUT):
|
||||
@mkdir -p $@
|
||||
|
||||
submodule:
|
||||
git submodule update --init
|
||||
# git submodule update --remote
|
||||
@echo "Initializing submodules..."
|
||||
@git submodule init || true
|
||||
@git submodule update --init --recursive || true
|
||||
@git submodule foreach -q ' \
|
||||
branch="$$(git config -f $${toplevel}/.gitmodules submodule.$${name}.branch)"; \
|
||||
if [ -n "$$branch" ]; then \
|
||||
echo "Updating $$name to branch $$branch"; \
|
||||
if ! git fetch origin "$$branch" 2>/dev/null; then \
|
||||
echo "Error: Branch $$branch not found in remote for $$name. Make sure the branch exists and is accessible."; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
if git show-ref --verify --quiet "refs/remotes/origin/$$branch" 2>/dev/null; then \
|
||||
remote_ref="origin/$$branch"; \
|
||||
else \
|
||||
remote_ref="FETCH_HEAD"; \
|
||||
fi; \
|
||||
if git show-ref --verify --quiet "refs/heads/$$branch" 2>/dev/null; then \
|
||||
git checkout "$$branch" && git reset --hard "$$remote_ref" || { echo "Error: Failed to update $$name to $$branch"; exit 1; }; \
|
||||
else \
|
||||
git checkout -b "$$branch" "$$remote_ref" || { echo "Error: Failed to checkout branch $$branch for $$name"; exit 1; }; \
|
||||
fi; \
|
||||
git branch --set-upstream-to="origin/$$branch" "$$branch" 2>/dev/null || true; \
|
||||
echo "✓ $$name is now on branch $$branch"; \
|
||||
fi \
|
||||
'
|
||||
|
||||
.PHONY: prebuild
|
||||
prebuild: submodule
|
||||
@@ -201,7 +224,7 @@ install: pre-install
|
||||
|
||||
HIGRESS_LATEST_IMAGE_TAG ?= latest
|
||||
ENVOY_LATEST_IMAGE_TAG ?= cdf0f16bf622102f89a0d0257834f43f502e4b99
|
||||
ISTIO_LATEST_IMAGE_TAG ?= ec099e0a24d25aff9c6530cb45dc0ff86ebb78b9
|
||||
ISTIO_LATEST_IMAGE_TAG ?= 2124b6819c805d16507d4bb0bb394160281169e7
|
||||
|
||||
install-dev: pre-install
|
||||
helm install higress helm/core -n higress-system --create-namespace --set 'controller.tag=$(TAG)' --set 'gateway.replicas=1' --set 'pilot.tag=$(ISTIO_LATEST_IMAGE_TAG)' --set 'gateway.tag=$(ENVOY_LATEST_IMAGE_TAG)' --set 'global.local=true'
|
||||
|
||||
@@ -41,6 +41,56 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Route type for matching rules.
|
||||
// Extended by Higress
|
||||
type RouteType int32
|
||||
|
||||
const (
|
||||
// HTTP route (default)
|
||||
RouteType_HTTP RouteType = 0
|
||||
// GRPC route
|
||||
RouteType_GRPC RouteType = 1
|
||||
)
|
||||
|
||||
// Enum value maps for RouteType.
|
||||
var (
|
||||
RouteType_name = map[int32]string{
|
||||
0: "HTTP",
|
||||
1: "GRPC",
|
||||
}
|
||||
RouteType_value = map[string]int32{
|
||||
"HTTP": 0,
|
||||
"GRPC": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x RouteType) Enum() *RouteType {
|
||||
p := new(RouteType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x RouteType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (RouteType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (RouteType) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x RouteType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RouteType.Descriptor instead.
|
||||
func (RouteType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// The phase in the filter chain where the plugin will be injected.
|
||||
type PluginPhase int32
|
||||
|
||||
@@ -84,11 +134,11 @@ func (x PluginPhase) String() string {
|
||||
}
|
||||
|
||||
func (PluginPhase) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[0].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (PluginPhase) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[0]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x PluginPhase) Number() protoreflect.EnumNumber {
|
||||
@@ -97,7 +147,7 @@ func (x PluginPhase) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use PluginPhase.Descriptor instead.
|
||||
func (PluginPhase) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{0}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
// The pull behaviour to be applied when fetching an OCI image,
|
||||
@@ -146,11 +196,11 @@ func (x PullPolicy) String() string {
|
||||
}
|
||||
|
||||
func (PullPolicy) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[1].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (PullPolicy) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[1]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x PullPolicy) Number() protoreflect.EnumNumber {
|
||||
@@ -159,7 +209,7 @@ func (x PullPolicy) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use PullPolicy.Descriptor instead.
|
||||
func (PullPolicy) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{1}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type EnvValueSource int32
|
||||
@@ -194,11 +244,11 @@ func (x EnvValueSource) String() string {
|
||||
}
|
||||
|
||||
func (EnvValueSource) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[2].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[3].Descriptor()
|
||||
}
|
||||
|
||||
func (EnvValueSource) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[2]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[3]
|
||||
}
|
||||
|
||||
func (x EnvValueSource) Number() protoreflect.EnumNumber {
|
||||
@@ -207,7 +257,7 @@ func (x EnvValueSource) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use EnvValueSource.Descriptor instead.
|
||||
func (EnvValueSource) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{2}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type FailStrategy int32
|
||||
@@ -246,11 +296,11 @@ func (x FailStrategy) String() string {
|
||||
}
|
||||
|
||||
func (FailStrategy) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[3].Descriptor()
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_enumTypes[4].Descriptor()
|
||||
}
|
||||
|
||||
func (FailStrategy) Type() protoreflect.EnumType {
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[3]
|
||||
return &file_extensions_v1alpha1_wasmplugin_proto_enumTypes[4]
|
||||
}
|
||||
|
||||
func (x FailStrategy) Number() protoreflect.EnumNumber {
|
||||
@@ -259,7 +309,7 @@ func (x FailStrategy) Number() protoreflect.EnumNumber {
|
||||
|
||||
// Deprecated: Use FailStrategy.Descriptor instead.
|
||||
func (FailStrategy) EnumDescriptor() ([]byte, []int) {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{3}
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
// <!-- crd generation tags
|
||||
@@ -485,6 +535,8 @@ type MatchRule struct {
|
||||
Config *_struct.Struct `protobuf:"bytes,3,opt,name=config,proto3" json:"config,omitempty"`
|
||||
ConfigDisable *wrappers.BoolValue `protobuf:"bytes,4,opt,name=config_disable,json=configDisable,proto3" json:"config_disable,omitempty"`
|
||||
Service []string `protobuf:"bytes,5,rep,name=service,proto3" json:"service,omitempty"`
|
||||
// Route type for this match rule, defaults to HTTP
|
||||
RouteType RouteType `protobuf:"varint,6,opt,name=route_type,json=routeType,proto3,enum=higress.extensions.v1alpha1.RouteType" json:"route_type,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MatchRule) Reset() {
|
||||
@@ -554,6 +606,13 @@ func (x *MatchRule) GetService() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *MatchRule) GetRouteType() RouteType {
|
||||
if x != nil {
|
||||
return x.RouteType
|
||||
}
|
||||
return RouteType_HTTP
|
||||
}
|
||||
|
||||
// Configuration for a Wasm VM.
|
||||
// more details can be found [here](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/wasm/v3/wasm.proto#extensions-wasm-v3-vmconfig).
|
||||
type VmConfig struct {
|
||||
@@ -736,7 +795,7 @@ var file_extensions_v1alpha1_wasmplugin_proto_rawDesc = []byte{
|
||||
0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f,
|
||||
0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xcb, 0x01,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x92, 0x02,
|
||||
0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69,
|
||||
0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x69, 0x6e,
|
||||
0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18,
|
||||
@@ -749,37 +808,44 @@ var file_extensions_v1alpha1_wasmplugin_proto_rawDesc = []byte{
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x41, 0x0a, 0x08, 0x56,
|
||||
0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65,
|
||||
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x31, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x7e,
|
||||
0x0a, 0x06, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4a, 0x0a, 0x0a,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e,
|
||||
0x32, 0x2b, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45,
|
||||
0x6e, 0x76, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x45,
|
||||
0x0a, 0x0b, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x15, 0x0a,
|
||||
0x11, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x50, 0x48, 0x41,
|
||||
0x53, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x54, 0x48, 0x4e, 0x10, 0x01, 0x12,
|
||||
0x09, 0x0a, 0x05, 0x41, 0x55, 0x54, 0x48, 0x5a, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54,
|
||||
0x41, 0x54, 0x53, 0x10, 0x03, 0x2a, 0x42, 0x0a, 0x0a, 0x50, 0x75, 0x6c, 0x6c, 0x50, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x12, 0x16, 0x0a, 0x12, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
||||
0x45, 0x44, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49,
|
||||
0x66, 0x4e, 0x6f, 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x0a, 0x0a,
|
||||
0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10, 0x02, 0x2a, 0x26, 0x0a, 0x0e, 0x45, 0x6e, 0x76,
|
||||
0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x49,
|
||||
0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53, 0x54, 0x10,
|
||||
0x01, 0x2a, 0x2d, 0x0a, 0x0c, 0x46, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
|
||||
0x79, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x41, 0x49, 0x4c, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10,
|
||||
0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x41, 0x49, 0x4c, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x10, 0x01,
|
||||
0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
|
||||
0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x2f, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31,
|
||||
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x26, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79,
|
||||
0x70, 0x65, 0x22, 0x41, 0x0a, 0x08, 0x56, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35,
|
||||
0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x68, 0x69,
|
||||
0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72,
|
||||
0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x7e, 0x0a, 0x06, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x4a, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x72, 0x6f,
|
||||
0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73,
|
||||
0x73, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x61,
|
||||
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x1f, 0x0a, 0x09, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79,
|
||||
0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04,
|
||||
0x47, 0x52, 0x50, 0x43, 0x10, 0x01, 0x2a, 0x45, 0x0a, 0x0b, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e,
|
||||
0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
|
||||
0x46, 0x49, 0x45, 0x44, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
|
||||
0x41, 0x55, 0x54, 0x48, 0x4e, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x54, 0x48, 0x5a,
|
||||
0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x03, 0x2a, 0x42, 0x0a,
|
||||
0x0a, 0x50, 0x75, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x16, 0x0a, 0x12, 0x55,
|
||||
0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43,
|
||||
0x59, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x50, 0x72, 0x65, 0x73,
|
||||
0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10,
|
||||
0x02, 0x2a, 0x26, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x00, 0x12,
|
||||
0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x2a, 0x2d, 0x0a, 0x0c, 0x46, 0x61, 0x69,
|
||||
0x6c, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x41, 0x49,
|
||||
0x4c, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x41, 0x49,
|
||||
0x4c, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x10, 0x01, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x2f, 0x68,
|
||||
0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x65, 0x78,
|
||||
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
|
||||
0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -794,40 +860,42 @@ func file_extensions_v1alpha1_wasmplugin_proto_rawDescGZIP() []byte {
|
||||
return file_extensions_v1alpha1_wasmplugin_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_goTypes = []interface{}{
|
||||
(PluginPhase)(0), // 0: higress.extensions.v1alpha1.PluginPhase
|
||||
(PullPolicy)(0), // 1: higress.extensions.v1alpha1.PullPolicy
|
||||
(EnvValueSource)(0), // 2: higress.extensions.v1alpha1.EnvValueSource
|
||||
(FailStrategy)(0), // 3: higress.extensions.v1alpha1.FailStrategy
|
||||
(*WasmPlugin)(nil), // 4: higress.extensions.v1alpha1.WasmPlugin
|
||||
(*MatchRule)(nil), // 5: higress.extensions.v1alpha1.MatchRule
|
||||
(*VmConfig)(nil), // 6: higress.extensions.v1alpha1.VmConfig
|
||||
(*EnvVar)(nil), // 7: higress.extensions.v1alpha1.EnvVar
|
||||
(*_struct.Struct)(nil), // 8: google.protobuf.Struct
|
||||
(*wrappers.Int32Value)(nil), // 9: google.protobuf.Int32Value
|
||||
(*wrappers.BoolValue)(nil), // 10: google.protobuf.BoolValue
|
||||
(RouteType)(0), // 0: higress.extensions.v1alpha1.RouteType
|
||||
(PluginPhase)(0), // 1: higress.extensions.v1alpha1.PluginPhase
|
||||
(PullPolicy)(0), // 2: higress.extensions.v1alpha1.PullPolicy
|
||||
(EnvValueSource)(0), // 3: higress.extensions.v1alpha1.EnvValueSource
|
||||
(FailStrategy)(0), // 4: higress.extensions.v1alpha1.FailStrategy
|
||||
(*WasmPlugin)(nil), // 5: higress.extensions.v1alpha1.WasmPlugin
|
||||
(*MatchRule)(nil), // 6: higress.extensions.v1alpha1.MatchRule
|
||||
(*VmConfig)(nil), // 7: higress.extensions.v1alpha1.VmConfig
|
||||
(*EnvVar)(nil), // 8: higress.extensions.v1alpha1.EnvVar
|
||||
(*_struct.Struct)(nil), // 9: google.protobuf.Struct
|
||||
(*wrappers.Int32Value)(nil), // 10: google.protobuf.Int32Value
|
||||
(*wrappers.BoolValue)(nil), // 11: google.protobuf.BoolValue
|
||||
}
|
||||
var file_extensions_v1alpha1_wasmplugin_proto_depIdxs = []int32{
|
||||
1, // 0: higress.extensions.v1alpha1.WasmPlugin.image_pull_policy:type_name -> higress.extensions.v1alpha1.PullPolicy
|
||||
8, // 1: higress.extensions.v1alpha1.WasmPlugin.plugin_config:type_name -> google.protobuf.Struct
|
||||
0, // 2: higress.extensions.v1alpha1.WasmPlugin.phase:type_name -> higress.extensions.v1alpha1.PluginPhase
|
||||
9, // 3: higress.extensions.v1alpha1.WasmPlugin.priority:type_name -> google.protobuf.Int32Value
|
||||
3, // 4: higress.extensions.v1alpha1.WasmPlugin.fail_strategy:type_name -> higress.extensions.v1alpha1.FailStrategy
|
||||
6, // 5: higress.extensions.v1alpha1.WasmPlugin.vm_config:type_name -> higress.extensions.v1alpha1.VmConfig
|
||||
8, // 6: higress.extensions.v1alpha1.WasmPlugin.default_config:type_name -> google.protobuf.Struct
|
||||
5, // 7: higress.extensions.v1alpha1.WasmPlugin.match_rules:type_name -> higress.extensions.v1alpha1.MatchRule
|
||||
10, // 8: higress.extensions.v1alpha1.WasmPlugin.default_config_disable:type_name -> google.protobuf.BoolValue
|
||||
8, // 9: higress.extensions.v1alpha1.MatchRule.config:type_name -> google.protobuf.Struct
|
||||
10, // 10: higress.extensions.v1alpha1.MatchRule.config_disable:type_name -> google.protobuf.BoolValue
|
||||
7, // 11: higress.extensions.v1alpha1.VmConfig.env:type_name -> higress.extensions.v1alpha1.EnvVar
|
||||
2, // 12: higress.extensions.v1alpha1.EnvVar.value_from:type_name -> higress.extensions.v1alpha1.EnvValueSource
|
||||
13, // [13:13] is the sub-list for method output_type
|
||||
13, // [13:13] is the sub-list for method input_type
|
||||
13, // [13:13] is the sub-list for extension type_name
|
||||
13, // [13:13] is the sub-list for extension extendee
|
||||
0, // [0:13] is the sub-list for field type_name
|
||||
2, // 0: higress.extensions.v1alpha1.WasmPlugin.image_pull_policy:type_name -> higress.extensions.v1alpha1.PullPolicy
|
||||
9, // 1: higress.extensions.v1alpha1.WasmPlugin.plugin_config:type_name -> google.protobuf.Struct
|
||||
1, // 2: higress.extensions.v1alpha1.WasmPlugin.phase:type_name -> higress.extensions.v1alpha1.PluginPhase
|
||||
10, // 3: higress.extensions.v1alpha1.WasmPlugin.priority:type_name -> google.protobuf.Int32Value
|
||||
4, // 4: higress.extensions.v1alpha1.WasmPlugin.fail_strategy:type_name -> higress.extensions.v1alpha1.FailStrategy
|
||||
7, // 5: higress.extensions.v1alpha1.WasmPlugin.vm_config:type_name -> higress.extensions.v1alpha1.VmConfig
|
||||
9, // 6: higress.extensions.v1alpha1.WasmPlugin.default_config:type_name -> google.protobuf.Struct
|
||||
6, // 7: higress.extensions.v1alpha1.WasmPlugin.match_rules:type_name -> higress.extensions.v1alpha1.MatchRule
|
||||
11, // 8: higress.extensions.v1alpha1.WasmPlugin.default_config_disable:type_name -> google.protobuf.BoolValue
|
||||
9, // 9: higress.extensions.v1alpha1.MatchRule.config:type_name -> google.protobuf.Struct
|
||||
11, // 10: higress.extensions.v1alpha1.MatchRule.config_disable:type_name -> google.protobuf.BoolValue
|
||||
0, // 11: higress.extensions.v1alpha1.MatchRule.route_type:type_name -> higress.extensions.v1alpha1.RouteType
|
||||
8, // 12: higress.extensions.v1alpha1.VmConfig.env:type_name -> higress.extensions.v1alpha1.EnvVar
|
||||
3, // 13: higress.extensions.v1alpha1.EnvVar.value_from:type_name -> higress.extensions.v1alpha1.EnvValueSource
|
||||
14, // [14:14] is the sub-list for method output_type
|
||||
14, // [14:14] is the sub-list for method input_type
|
||||
14, // [14:14] is the sub-list for extension type_name
|
||||
14, // [14:14] is the sub-list for extension extendee
|
||||
0, // [0:14] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_extensions_v1alpha1_wasmplugin_proto_init() }
|
||||
@@ -890,7 +958,7 @@ func file_extensions_v1alpha1_wasmplugin_proto_init() {
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_extensions_v1alpha1_wasmplugin_proto_rawDesc,
|
||||
NumEnums: 4,
|
||||
NumEnums: 5,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
|
||||
@@ -122,6 +122,18 @@ message MatchRule {
|
||||
google.protobuf.Struct config = 3;
|
||||
google.protobuf.BoolValue config_disable = 4;
|
||||
repeated string service = 5;
|
||||
// Route type for this match rule, defaults to HTTP
|
||||
RouteType route_type = 6;
|
||||
}
|
||||
|
||||
// Route type for matching rules.
|
||||
// Extended by Higress
|
||||
enum RouteType {
|
||||
// HTTP route (default)
|
||||
HTTP = 0;
|
||||
|
||||
// GRPC route
|
||||
GRPC = 1;
|
||||
}
|
||||
|
||||
// The phase in the filter chain where the plugin will be injected.
|
||||
|
||||
@@ -71,6 +71,11 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
routeType:
|
||||
enum:
|
||||
- HTTP
|
||||
- GRPC
|
||||
type: string
|
||||
service:
|
||||
items:
|
||||
type: string
|
||||
|
||||
@@ -504,11 +504,11 @@ var file_networking_v1_http_2_rpc_proto_rawDesc = []byte{
|
||||
0x69, 0x72, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d,
|
||||
0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02,
|
||||
0x52, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x47,
|
||||
0x72, 0x70, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69,
|
||||
0x72, 0x70, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61,
|
||||
0x2f, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6e, 0x65, 0x74,
|
||||
0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
0x2f, 0x68, 0x69, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -749,10 +749,10 @@ var file_networking_v1_mcp_bridge_proto_rawDesc = []byte{
|
||||
0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x2f, 0x68, 0x69, 0x67, 0x72,
|
||||
0x65, 0x73, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69,
|
||||
0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x73, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f,
|
||||
0x72, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
280
go.mod
280
go.mod
@@ -1,8 +1,6 @@
|
||||
module github.com/alibaba/higress/v2
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.7
|
||||
go 1.24.4
|
||||
|
||||
replace github.com/spf13/viper => github.com/istio/viper v1.3.3-0.20190515210538-2789fed3109c
|
||||
|
||||
@@ -22,57 +20,61 @@ require (
|
||||
github.com/caddyserver/certmagic v0.21.3
|
||||
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5
|
||||
github.com/dubbogo/gost v1.13.1
|
||||
github.com/envoyproxy/go-control-plane v0.11.2-0.20230725211550-11bfe846bcd4
|
||||
github.com/go-errors/errors v1.4.2
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0
|
||||
github.com/go-errors/errors v1.5.1
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/hashicorp/consul/api v1.21.0
|
||||
github.com/hashicorp/consul/api v1.31.2
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hudl/fargo v1.4.0
|
||||
github.com/mholt/acmez v1.2.0
|
||||
github.com/nacos-group/nacos-sdk-go v1.0.8
|
||||
github.com/nacos-group/nacos-sdk-go/v2 v2.3.2
|
||||
github.com/onsi/gomega v1.27.10
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.7
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/tidwall/gjson v1.17.0
|
||||
go.uber.org/atomic v1.11.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/net v0.33.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
istio.io/api v1.19.5-0.20231206014255-f55a2b1e931e
|
||||
golang.org/x/net v0.41.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822
|
||||
google.golang.org/grpc v1.73.0
|
||||
google.golang.org/protobuf v1.36.6
|
||||
istio.io/api v1.27.1-0.20250820125923-f5a5d3a605a9
|
||||
istio.io/client-go v1.27.1-0.20250820130622-12f6d11feb40
|
||||
istio.io/istio v0.0.0
|
||||
istio.io/pkg v0.0.0-20231221211216-7635388a563e
|
||||
k8s.io/api v0.28.3
|
||||
k8s.io/apiextensions-apiserver v0.28.3
|
||||
k8s.io/apimachinery v0.28.3
|
||||
k8s.io/cli-runtime v0.28.0
|
||||
k8s.io/client-go v0.28.3
|
||||
istio.io/pkg v0.0.0-20250718200944-0aab346caa39
|
||||
k8s.io/api v0.33.3
|
||||
k8s.io/apiextensions-apiserver v0.33.3
|
||||
k8s.io/apimachinery v0.33.3
|
||||
k8s.io/cli-runtime v0.33.3
|
||||
k8s.io/client-go v0.33.3
|
||||
knative.dev/networking v0.0.0-20220302134042-e8b2eb995165
|
||||
knative.dev/pkg v0.0.0-20220301181942-2fdd5f232e77
|
||||
sigs.k8s.io/controller-runtime v0.16.3
|
||||
sigs.k8s.io/gateway-api v0.8.0
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
sigs.k8s.io/controller-runtime v0.21.0
|
||||
sigs.k8s.io/gateway-api v1.3.0
|
||||
sigs.k8s.io/gateway-api-inference-extension v0.5.0
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0
|
||||
sigs.k8s.io/yaml v1.5.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.8 // indirect
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/logging v1.8.1 // indirect
|
||||
cloud.google.com/go/longrunning v0.5.1 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
cloud.google.com/go v0.115.1 // indirect
|
||||
cloud.google.com/go/auth v0.15.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/logging v1.11.0 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.0 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/alecholmes/xfccparser v0.1.0 // indirect
|
||||
github.com/alecthomas/participle v0.4.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||
github.com/alecholmes/xfccparser v0.4.0 // indirect
|
||||
github.com/alecthomas/participle/v2 v2.1.4 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
|
||||
github.com/alibabacloud-go/darabonba-array v0.1.0 // indirect
|
||||
@@ -94,177 +96,187 @@ require (
|
||||
github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8 // indirect
|
||||
github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5 // indirect
|
||||
github.com/aliyun/credentials-go v1.4.3 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clbanning/mxj v1.8.4 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.5.5 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.6.0 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.14.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deckarep/golang-set v1.7.1 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/docker/cli v24.0.7+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/docker v24.0.7+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.7.0 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
github.com/docker/cli v28.1.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.13.4 // indirect
|
||||
github.com/envoyproxy/go-control-plane/contrib v0.0.0-20251016030003-90eca0228178 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/cel-go v0.16.1 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-containerregistry v0.15.2 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/s2a-go v0.1.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.25.0 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
github.com/google/go-containerregistry v0.20.3 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.5 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.4 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/serf v0.10.1 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/imdario/mergo v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.1 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.3 // indirect
|
||||
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
||||
github.com/lestrrat-go/iter v1.0.2 // indirect
|
||||
github.com/lestrrat-go/jwx v1.2.26 // indirect
|
||||
github.com/lestrrat-go/jwx v1.2.31 // indirect
|
||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f // indirect
|
||||
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
|
||||
github.com/libdns/libdns v0.2.2 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
github.com/miekg/dns v1.1.59 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/miekg/dns v1.1.66 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
github.com/moby/term v0.5.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
|
||||
github.com/openshift/api v0.0.0-20230720094506-afcbe27aec7c // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/openshift/api v0.0.0-20250507150912-7318813e48da // indirect
|
||||
github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240409071808-615f978279ca // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.17.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.45.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/prometheus/prometheus v0.45.0 // indirect
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/prometheus/client_golang v1.22.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.65.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/prometheus/prometheus v0.303.1 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/cast v1.8.0 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/tetratelabs/wazero v1.7.3 // indirect
|
||||
github.com/tetratelabs/wazero v1.9.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect
|
||||
github.com/vbatts/tar-split v0.11.3 // indirect
|
||||
github.com/vbatts/tar-split v0.12.1 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
github.com/yl2chen/cidranger v1.0.2 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel v1.17.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.39.1-0.20230714155235-03b8c47770f2 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.17.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.17.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.3 // indirect
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250717185816-542afb5b7346 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.13.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/api v0.132.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/term v0.33.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
||||
google.golang.org/api v0.224.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/gcfg.v1 v1.2.3 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gotest.tools/v3 v3.5.0 // indirect
|
||||
istio.io/client-go v1.19.5-0.20231206015206-8cdf6a3b3cfd // indirect
|
||||
k8s.io/apiserver v0.28.3 // indirect
|
||||
k8s.io/component-base v0.28.3 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
||||
k8s.io/kubectl v0.28.0 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.3 // indirect
|
||||
sigs.k8s.io/mcs-api v0.1.0 // indirect
|
||||
k8s.io/apiserver v0.33.3 // indirect
|
||||
k8s.io/component-base v0.33.3 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
|
||||
k8s.io/kubectl v0.33.3 // indirect
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.32.1 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.19.0 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
|
||||
sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
)
|
||||
|
||||
replace istio.io/api => ./external/api
|
||||
|
||||
replace github.com/envoyproxy/go-control-plane => ./external/go-control-plane
|
||||
|
||||
replace github.com/envoyproxy/go-control-plane/contrib => ./external/go-control-plane/contrib
|
||||
|
||||
replace github.com/envoyproxy/go-control-plane/envoy => ./external/go-control-plane/envoy
|
||||
|
||||
replace istio.io/pkg => ./external/pkg
|
||||
|
||||
replace istio.io/client-go => ./external/client-go
|
||||
|
||||
@@ -71,6 +71,11 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
routeType:
|
||||
enum:
|
||||
- HTTP
|
||||
- GRPC
|
||||
type: string
|
||||
service:
|
||||
items:
|
||||
type: string
|
||||
|
||||
298
hgctl/go.mod
298
hgctl/go.mod
@@ -1,8 +1,6 @@
|
||||
module github.com/alibaba/higress/hgctl
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.24.1
|
||||
go 1.24.4
|
||||
|
||||
replace github.com/spf13/viper => github.com/istio/viper v1.3.3-0.20190515210538-2789fed3109c
|
||||
|
||||
@@ -22,11 +20,11 @@ require (
|
||||
github.com/alibaba/higress/v2 v2.0.0-00010101000000-000000000000
|
||||
github.com/braydonk/yaml v0.7.0
|
||||
github.com/compose-spec/compose-go v1.17.0
|
||||
github.com/docker/cli v24.0.7+incompatible
|
||||
github.com/docker/cli v28.1.1+incompatible
|
||||
github.com/docker/compose/v2 v2.23.3
|
||||
github.com/docker/docker v24.0.7+incompatible
|
||||
github.com/evanphx/json-patch/v5 v5.7.0
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/docker/docker v28.0.1+incompatible
|
||||
github.com/evanphx/json-patch/v5 v5.9.11
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/fatih/structtag v1.2.0
|
||||
github.com/google/yamlfmt v0.10.0
|
||||
github.com/higress-group/openapi-to-mcpserver v0.0.0-20250925065334-de60a170f950
|
||||
@@ -36,38 +34,64 @@ require (
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.16.0
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.7
|
||||
github.com/spf13/viper v1.20.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
helm.sh/helm/v3 v3.12.2
|
||||
helm.sh/helm/v3 v3.18.5
|
||||
istio.io/istio v0.0.0
|
||||
k8s.io/api v0.28.3
|
||||
k8s.io/apimachinery v0.28.3
|
||||
k8s.io/cli-runtime v0.28.0
|
||||
k8s.io/client-go v0.28.3
|
||||
k8s.io/kubectl v0.28.0
|
||||
sigs.k8s.io/controller-runtime v0.16.3
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
k8s.io/api v0.33.3
|
||||
k8s.io/apimachinery v0.33.3
|
||||
k8s.io/cli-runtime v0.33.3
|
||||
k8s.io/client-go v0.33.3
|
||||
k8s.io/kubectl v0.33.3
|
||||
sigs.k8s.io/controller-runtime v0.21.0
|
||||
sigs.k8s.io/yaml v1.5.0
|
||||
)
|
||||
|
||||
require github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
|
||||
require (
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/chzyer/readline v1.5.0 // indirect
|
||||
github.com/containerd/containerd/api v1.8.0 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||
github.com/envoyproxy/go-control-plane/contrib v0.0.0-20251016030003-90eca0228178 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240409071808-615f978279ca // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.3 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
oras.land/oras-go/v2 v2.6.0 // indirect
|
||||
sigs.k8s.io/gateway-api-inference-extension v0.5.0 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.7 // indirect
|
||||
github.com/RageCage64/multilinediff v0.2.0 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.16 // indirect
|
||||
@@ -84,113 +108,110 @@ require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
|
||||
github.com/buger/goterm v1.0.4 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.3 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
|
||||
github.com/containerd/console v1.0.3 // indirect
|
||||
github.com/containerd/containerd v1.7.7 // indirect
|
||||
github.com/containerd/continuity v0.4.2 // indirect
|
||||
github.com/containerd/containerd v1.7.27 // indirect
|
||||
github.com/containerd/continuity v0.4.4 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.1.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/distribution/distribution/v3 v3.0.0-20230601133803-97b1d649c493 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
github.com/distribution/distribution/v3 v3.0.0 // indirect
|
||||
github.com/docker/buildx v0.12.0 // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.11.2-0.20230725211550-11bfe846bcd4 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsevents v0.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||
github.com/getkin/kin-openapi v0.118.0 // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.0.5 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-errors/errors v1.5.1 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/cel-go v0.16.1 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.25.0 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gosuri/uitable v0.0.4 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
|
||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.4 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/imdario/mergo v1.0.0 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/invopop/yaml v0.1.0 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
||||
github.com/jmoiron/sqlx v1.4.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.1 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.3 // indirect
|
||||
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
||||
github.com/lestrrat-go/iter v1.0.2 // indirect
|
||||
github.com/lestrrat-go/jwx v1.2.26 // indirect
|
||||
github.com/lestrrat-go/jwx v1.2.31 // indirect
|
||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/manifoldco/promptui v0.9.0
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/miekg/dns v1.1.59 // indirect
|
||||
github.com/miekg/dns v1.1.66 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/buildkit v0.13.0-beta1.0.20231023114302-d5c1d785b042 // indirect
|
||||
github.com/moby/buildkit v0.21.1 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.6.2 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.0 // indirect
|
||||
github.com/moby/sys/symlink v0.2.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/moby/term v0.5.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
@@ -198,28 +219,27 @@ require (
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runc v1.1.9 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.17.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.45.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/prometheus/prometheus v0.45.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.3 // indirect
|
||||
github.com/rubenv/sql-migrate v1.3.1 // indirect
|
||||
github.com/prometheus/client_golang v1.22.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.65.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/prometheus/prometheus v0.303.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rubenv/sql-migrate v1.8.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.8.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||
@@ -234,65 +254,64 @@ require (
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300 // indirect
|
||||
github.com/zmap/zlint/v3 v3.6.3 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.40.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect
|
||||
go.opentelemetry.io/otel v1.17.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.39.1-0.20230714155235-03b8c47770f2 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.17.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.17.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250717185816-542afb5b7346 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/oauth2 v0.13.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/term v0.33.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/grpc v1.73.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
istio.io/api v1.19.5-0.20231206014255-f55a2b1e931e // indirect
|
||||
istio.io/client-go v1.19.5-0.20231206015206-8cdf6a3b3cfd // indirect
|
||||
k8s.io/apiextensions-apiserver v0.28.3 // indirect
|
||||
k8s.io/apiserver v0.28.3 // indirect
|
||||
k8s.io/component-base v0.28.3 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
oras.land/oras-go v1.2.3 // indirect
|
||||
sigs.k8s.io/gateway-api v0.8.0 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.3 // indirect
|
||||
sigs.k8s.io/mcs-api v0.1.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
|
||||
istio.io/api v1.27.1-0.20250820125923-f5a5d3a605a9 // indirect
|
||||
istio.io/client-go v1.27.1-0.20250820130622-12f6d11feb40 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.33.3 // indirect
|
||||
k8s.io/apiserver v0.33.3 // indirect
|
||||
k8s.io/component-base v0.33.3 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
|
||||
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 // indirect
|
||||
sigs.k8s.io/gateway-api v1.3.0 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.19.0 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
|
||||
sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
||||
)
|
||||
|
||||
replace istio.io/api => ../external/api
|
||||
|
||||
replace github.com/envoyproxy/go-control-plane => ../external/go-control-plane
|
||||
|
||||
replace github.com/envoyproxy/go-control-plane/contrib => ../external/go-control-plane/contrib
|
||||
|
||||
replace github.com/envoyproxy/go-control-plane/envoy => ../external/go-control-plane/envoy
|
||||
|
||||
replace istio.io/pkg => ../external/pkg
|
||||
|
||||
replace istio.io/client-go => ../external/client-go
|
||||
@@ -303,6 +322,7 @@ replace github.com/alibaba/higress => ../
|
||||
|
||||
replace (
|
||||
github.com/cucumber/godog => github.com/laurazard/godog v0.0.0-20220922095256-4c4b17abdae7
|
||||
github.com/distribution/distribution/v3 => github.com/distribution/distribution/v3 v3.0.0-20230601133803-97b1d649c493
|
||||
github.com/docker/buildx => github.com/docker/buildx v0.11.2
|
||||
github.com/docker/cli => github.com/docker/cli v24.0.6+incompatible
|
||||
github.com/docker/compose/v2 => github.com/docker/compose/v2 v2.20.2
|
||||
|
||||
2043
hgctl/go.sum
2043
hgctl/go.sum
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,8 @@ package bootstrap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"istio.io/istio/pkg/config/mesh/meshwatcher"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
@@ -32,20 +34,16 @@ import (
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/aggregate"
|
||||
kubecontroller "istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/xds"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/mesh"
|
||||
"istio.io/istio/pkg/config/schema/collections"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/config/schema/kind"
|
||||
"istio.io/istio/pkg/keepalive"
|
||||
istiokube "istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/log"
|
||||
"istio.io/istio/pkg/security"
|
||||
"istio.io/istio/security/pkg/server/ca/authenticate"
|
||||
"istio.io/istio/security/pkg/server/ca/authenticate/kubeauth"
|
||||
"istio.io/pkg/ledger"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
@@ -152,7 +150,7 @@ type Server struct {
|
||||
func NewServer(args *ServerArgs) (*Server, error) {
|
||||
e := model.NewEnvironment()
|
||||
e.DomainSuffix = constants.DefaultClusterLocalDomain
|
||||
e.SetLedger(buildLedger(args.RegistryOptions))
|
||||
//e.SetLedger(buildLedger(args.RegistryOptions))
|
||||
ac := aggregate.NewController(aggregate.Options{
|
||||
MeshHolder: e,
|
||||
})
|
||||
@@ -164,7 +162,7 @@ func NewServer(args *ServerArgs) (*Server, error) {
|
||||
readinessProbes: make(map[string]readinessProbe),
|
||||
server: server.New(),
|
||||
}
|
||||
s.environment.Watcher = mesh.NewFixedWatcher(&v1alpha1.MeshConfig{})
|
||||
s.environment.Watcher = meshwatcher.NewTestWatcher(&v1alpha1.MeshConfig{})
|
||||
s.environment.Init()
|
||||
initFuncList := []func() error{
|
||||
s.initKubeClient,
|
||||
@@ -202,7 +200,7 @@ func (s *Server) initRegistryEventHandlers() error {
|
||||
pushReq := &model.PushRequest{
|
||||
Full: true,
|
||||
ConfigsUpdated: map[model.ConfigKey]struct{}{{
|
||||
Kind: kind.MustFromGVK(curr.GroupVersionKind),
|
||||
Kind: gvk.MustToKind(curr.GroupVersionKind),
|
||||
Name: curr.Name,
|
||||
Namespace: curr.Namespace,
|
||||
}: {}},
|
||||
@@ -340,7 +338,7 @@ func (s *Server) WaitUntilCompletion() {
|
||||
|
||||
func (s *Server) initXdsServer() error {
|
||||
log.Info("init xds server")
|
||||
s.xdsServer = xds.NewDiscoveryServer(s.environment, higressconfig.PodName, cluster.ID(higressconfig.PodNamespace), s.RegistryOptions.KubeOptions.ClusterAliases)
|
||||
s.xdsServer = xds.NewDiscoveryServer(s.environment, s.RegistryOptions.KubeOptions.ClusterAliases, krt.GlobalDebugHandler)
|
||||
generatorOptions := mcp.GeneratorOptions{KeepConfigLabels: s.XdsOptions.KeepConfigLabels, KeepConfigAnnotations: s.XdsOptions.KeepConfigAnnotations}
|
||||
s.xdsServer.Generators[gvk.WasmPlugin.String()] = &mcp.WasmPluginGenerator{Environment: s.environment, Server: s.xdsServer, GeneratorOptions: generatorOptions}
|
||||
s.xdsServer.Generators[gvk.DestinationRule.String()] = &mcp.DestinationRuleGenerator{Environment: s.environment, Server: s.xdsServer, GeneratorOptions: generatorOptions}
|
||||
@@ -354,8 +352,8 @@ func (s *Server) initXdsServer() error {
|
||||
s.xdsServer.Generators[gvk] = &mcp.FallbackGenerator{Environment: s.environment, Server: s.xdsServer}
|
||||
}
|
||||
}
|
||||
s.xdsServer.ProxyNeedsPush = func(proxy *model.Proxy, req *model.PushRequest) bool {
|
||||
return true
|
||||
s.xdsServer.ProxyNeedsPush = func(proxy *model.Proxy, req *model.PushRequest) (*model.PushRequest, bool) {
|
||||
return req, true
|
||||
}
|
||||
s.server.RunComponent("xds-server", func(stop <-chan struct{}) error {
|
||||
log.Infof("Starting ADS server")
|
||||
@@ -382,7 +380,7 @@ func (s *Server) initAuthenticators() error {
|
||||
&authenticate.ClientCertAuthenticator{},
|
||||
}
|
||||
authenticators = append(authenticators,
|
||||
kubeauth.NewKubeJWTAuthenticator(s.environment.Watcher, s.kubeClient.Kube(), s.RegistryOptions.KubeOptions.ClusterID, nil, features.JwtPolicy))
|
||||
kubeauth.NewKubeJWTAuthenticator(s.environment.Watcher, s.kubeClient.Kube(), s.RegistryOptions.KubeOptions.ClusterID, nil, nil))
|
||||
if features.XDSAuth {
|
||||
s.xdsServer.Authenticators = authenticators
|
||||
}
|
||||
@@ -528,12 +526,13 @@ func (s *Server) pushContextReady(expected int64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func buildLedger(ca RegistryOptions) ledger.Ledger {
|
||||
var result ledger.Ledger
|
||||
if ca.DistributionTrackingEnabled {
|
||||
result = ledger.Make(ca.DistributionCacheRetention)
|
||||
} else {
|
||||
result = &model.DisabledLedger{}
|
||||
}
|
||||
return result
|
||||
}
|
||||
// ledger has been removed in istio 1.27
|
||||
//func buildLedger(ca RegistryOptions) ledger.Ledger {
|
||||
// var result ledger.Ledger
|
||||
// if ca.DistributionTrackingEnabled {
|
||||
// result = ledger.Make(ca.DistributionCacheRetention)
|
||||
// } else {
|
||||
// result = &pkgcommon.DisabledLedger{}
|
||||
// }
|
||||
// return result
|
||||
//}
|
||||
|
||||
@@ -16,7 +16,9 @@ package bootstrap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/agiledragon/gomonkey/v2"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
@@ -31,8 +33,11 @@ func TestStartWithNoError(t *testing.T) {
|
||||
err error
|
||||
)
|
||||
|
||||
// Create fake client first
|
||||
fakeClient := higresskube.NewFakeClient()
|
||||
|
||||
mockFn := func(s *Server) error {
|
||||
s.kubeClient = higresskube.NewFakeClient()
|
||||
s.kubeClient = fakeClient
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -40,13 +45,49 @@ func TestStartWithNoError(t *testing.T) {
|
||||
|
||||
if s, err = NewServer(newServerArgs()); err != nil {
|
||||
t.Errorf("failed to create server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
if err = s.Start(ctx.Done()); err != nil {
|
||||
t.Errorf("failed to start the server: %v", err)
|
||||
// Start the fake client informers first
|
||||
go fakeClient.RunAndWait(ctx.Done())
|
||||
|
||||
// Give the client a moment to start informers
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var startErr error
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
startErr = s.Start(ctx.Done())
|
||||
}()
|
||||
|
||||
// Give the server a moment to start
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
// Cancel context to trigger shutdown
|
||||
cancel()
|
||||
|
||||
// Wait for server to shutdown with timeout
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
// Server may fail to sync cache in test environment due to missing resources,
|
||||
// which is acceptable for this test. The important thing is that the server
|
||||
// doesn't panic and handles shutdown gracefully.
|
||||
if startErr != nil && startErr.Error() != "failed to sync cache" {
|
||||
t.Logf("Server shutdown with error (may be expected in test env): %v", startErr)
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Errorf("server did not shutdown within timeout")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -42,7 +43,6 @@ import (
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/config/schema/kind"
|
||||
"istio.io/istio/pkg/log"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@@ -279,7 +279,7 @@ func (m *IngressConfig) AddLocalCluster(options common.Options) {
|
||||
}
|
||||
m.remoteIngressControllers[options.ClusterId] = ingressController
|
||||
if features.EnableGatewayAPI {
|
||||
m.remoteGatewayControllers[options.ClusterId] = gateway.NewController(m.localKubeClient, options)
|
||||
m.remoteGatewayControllers[options.ClusterId] = gateway.NewController(m.localKubeClient, options, m.XDSUpdater)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1054,7 +1054,17 @@ func (m *IngressConfig) convertIstioWasmPlugin(obj *higressext.WasmPlugin) (*ext
|
||||
validRule := false
|
||||
var matchItems []*_struct.Value
|
||||
// match ingress
|
||||
// if route type is not http, we should re-generate the route name for ingress matching
|
||||
// this is because the route name
|
||||
needAppendRuleType := false
|
||||
if rule.GetRouteType() != higressext.RouteType_HTTP {
|
||||
needAppendRuleType = true
|
||||
}
|
||||
|
||||
for _, ing := range rule.Ingress {
|
||||
if needAppendRuleType {
|
||||
ing = path.Join(rule.GetRouteType().String())
|
||||
}
|
||||
matchItems = append(matchItems, &_struct.Value{
|
||||
Kind: &_struct.Value_StringValue{
|
||||
StringValue: ing,
|
||||
@@ -1310,11 +1320,11 @@ func (m *IngressConfig) AddOrUpdateHttp2Rpc(clusterNamespacedName util.ClusterNa
|
||||
m.http2rpcs[clusterNamespacedName.Name] = &http2rpc.Spec
|
||||
m.mutex.Unlock()
|
||||
IngressLog.Infof("AddOrUpdateHttp2Rpc http2rpc ingress name %s", clusterNamespacedName.Name)
|
||||
push := func(gvk config.GroupVersionKind) {
|
||||
push := func(GVK config.GroupVersionKind) {
|
||||
m.XDSUpdater.ConfigUpdate(&istiomodel.PushRequest{
|
||||
Full: true,
|
||||
ConfigsUpdated: map[istiomodel.ConfigKey]struct{}{{
|
||||
Kind: kind.MustFromGVK(gvk),
|
||||
Kind: gvk.MustToKind(GVK),
|
||||
Name: clusterNamespacedName.Name,
|
||||
Namespace: clusterNamespacedName.Namespace,
|
||||
}: {}},
|
||||
@@ -1339,11 +1349,11 @@ func (m *IngressConfig) DeleteHttp2Rpc(clusterNamespacedName util.ClusterNamespa
|
||||
m.mutex.Unlock()
|
||||
if hit {
|
||||
IngressLog.Infof("Http2Rpc triggered deleted event executed %s", clusterNamespacedName.Name)
|
||||
push := func(gvk config.GroupVersionKind) {
|
||||
push := func(GVK config.GroupVersionKind) {
|
||||
m.XDSUpdater.ConfigUpdate(&istiomodel.PushRequest{
|
||||
Full: true,
|
||||
ConfigsUpdated: map[istiomodel.ConfigKey]struct{}{{
|
||||
Kind: kind.MustFromGVK(gvk),
|
||||
Kind: gvk.MustToKind(GVK),
|
||||
Name: clusterNamespacedName.Name,
|
||||
Namespace: clusterNamespacedName.Namespace,
|
||||
}: {}},
|
||||
@@ -1364,11 +1374,11 @@ func (m *IngressConfig) ReflectSecretChanges(clusterNamespacedName util.ClusterN
|
||||
m.mutex.RUnlock()
|
||||
|
||||
if hit {
|
||||
push := func(gvk config.GroupVersionKind) {
|
||||
push := func(GVK config.GroupVersionKind) {
|
||||
m.XDSUpdater.ConfigUpdate(&istiomodel.PushRequest{
|
||||
Full: true,
|
||||
ConfigsUpdated: map[istiomodel.ConfigKey]struct{}{{
|
||||
Kind: kind.MustFromGVK(gvk),
|
||||
Kind: gvk.MustToKind(GVK),
|
||||
Name: clusterNamespacedName.Name,
|
||||
Namespace: clusterNamespacedName.Namespace,
|
||||
}: {}},
|
||||
@@ -2058,11 +2068,11 @@ func (m *IngressConfig) constructMcpSseStatefulSessionEnvoyFilter(route *common.
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *IngressConfig) notifyXDSFullUpdate(gvk config.GroupVersionKind, reason istiomodel.TriggerReason, updatedConfigName *util.ClusterNamespacedName) {
|
||||
func (m *IngressConfig) notifyXDSFullUpdate(GVK config.GroupVersionKind, reason istiomodel.TriggerReason, updatedConfigName *util.ClusterNamespacedName) {
|
||||
var configsUpdated map[istiomodel.ConfigKey]struct{}
|
||||
if updatedConfigName != nil {
|
||||
configsUpdated = map[istiomodel.ConfigKey]struct{}{{
|
||||
Kind: kind.MustFromGVK(gvk),
|
||||
Kind: gvk.MustToKind(GVK),
|
||||
Name: updatedConfigName.Name,
|
||||
Namespace: updatedConfigName.Namespace,
|
||||
}: {}}
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/config/schema/kind"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
listersv1 "k8s.io/client-go/listers/core/v1"
|
||||
@@ -467,11 +466,11 @@ func (m *KIngressConfig) ReflectSecretChanges(clusterNamespacedName util.Cluster
|
||||
m.mutex.RUnlock()
|
||||
|
||||
if hit {
|
||||
push := func(gvk config.GroupVersionKind) {
|
||||
push := func(GVK config.GroupVersionKind) {
|
||||
m.XDSUpdater.ConfigUpdate(&istiomodel.PushRequest{
|
||||
Full: true,
|
||||
ConfigsUpdated: map[istiomodel.ConfigKey]struct{}{{
|
||||
Kind: kind.MustFromGVK(gvk),
|
||||
Kind: gvk.MustToKind(GVK),
|
||||
Name: clusterNamespacedName.Name,
|
||||
Namespace: clusterNamespacedName.Namespace,
|
||||
}: {}},
|
||||
|
||||
@@ -16,20 +16,20 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"sync"
|
||||
|
||||
"github.com/alibaba/higress/v2/pkg/ingress/kube/util"
|
||||
. "github.com/alibaba/higress/v2/pkg/ingress/log"
|
||||
istiomodel "istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/kind"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
)
|
||||
|
||||
// toConfigKey converts config.Config to istiomodel.ConfigKey
|
||||
func toConfigKey(cfg *config.Config) (istiomodel.ConfigKey, error) {
|
||||
return istiomodel.ConfigKey{
|
||||
Kind: kind.MustFromGVK(cfg.GroupVersionKind),
|
||||
Kind: gvk.MustToKind(cfg.GroupVersionKind),
|
||||
Name: cfg.Name,
|
||||
Namespace: cfg.Namespace,
|
||||
}, nil
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"sync/atomic"
|
||||
|
||||
"istio.io/istio/pilot/pkg/config/kube/crdclient"
|
||||
"istio.io/istio/pilot/pkg/credentials"
|
||||
kubecredentials "istio.io/istio/pilot/pkg/credentials/kube"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
kubecontroller "istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/status"
|
||||
@@ -30,7 +29,6 @@ import (
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/config/schema/resource"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/multicluster"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
higressconfig "github.com/alibaba/higress/v2/pkg/config"
|
||||
@@ -47,14 +45,13 @@ type gatewayController struct {
|
||||
envoyFilterHandlers []model.EventHandler
|
||||
|
||||
store model.ConfigStoreController
|
||||
credsController credentials.MulticlusterController
|
||||
istioController *istiogateway.Controller
|
||||
statusManager *status.Manager
|
||||
|
||||
resourceUpToDate atomic.Bool
|
||||
}
|
||||
|
||||
func NewController(client kube.Client, options common.Options) common.GatewayController {
|
||||
func NewController(client kube.Client, options common.Options, xdsUpdater model.XDSUpdater) common.GatewayController {
|
||||
domainSuffix := util.GetDomainSuffix()
|
||||
opts := crdclient.Option{
|
||||
Revision: higressconfig.Revision,
|
||||
@@ -68,12 +65,19 @@ func NewController(client kube.Client, options common.Options) common.GatewayCon
|
||||
}
|
||||
return false
|
||||
})
|
||||
// Add gateway api inference schema if enabled
|
||||
if features.EnableGatewayAPIInferenceExtension {
|
||||
schemasBuilder.MustAdd(collections.InferencePool)
|
||||
}
|
||||
store := crdclient.NewForSchemas(client, opts, schemasBuilder.Build())
|
||||
|
||||
clusterId := options.ClusterId
|
||||
credsController := kubecredentials.NewMulticluster(clusterId)
|
||||
credsController.ClusterAdded(&multicluster.Cluster{ID: clusterId, Client: client}, nil)
|
||||
istioController := istiogateway.NewController(client, store, client.CrdWatcher().WaitForCRD, credsController, kubecontroller.Options{DomainSuffix: domainSuffix})
|
||||
opt := kubecontroller.Options{
|
||||
DomainSuffix: domainSuffix,
|
||||
ClusterID: clusterId,
|
||||
Revision: higressconfig.Revision,
|
||||
}
|
||||
istioController := istiogateway.NewController(client, client.CrdWatcher().WaitForCRD, opt, xdsUpdater)
|
||||
if options.GatewaySelectorKey != "" {
|
||||
istioController.DefaultGatewaySelector = map[string]string{options.GatewaySelectorKey: options.GatewaySelectorValue}
|
||||
}
|
||||
@@ -88,7 +92,6 @@ func NewController(client kube.Client, options common.Options) common.GatewayCon
|
||||
|
||||
return &gatewayController{
|
||||
store: store,
|
||||
credsController: credsController,
|
||||
istioController: istioController,
|
||||
statusManager: statusManager,
|
||||
}
|
||||
@@ -104,10 +107,7 @@ func (g *gatewayController) Get(typ config.GroupVersionKind, name, namespace str
|
||||
|
||||
func (g *gatewayController) List(typ config.GroupVersionKind, namespace string) []config.Config {
|
||||
if g.resourceUpToDate.CompareAndSwap(false, true) {
|
||||
err := g.istioController.Reconcile(model.NewPushContext())
|
||||
if err != nil {
|
||||
IngressLog.Errorf("failed to recompute Gateway API resources: %v", err)
|
||||
}
|
||||
g.istioController.Reconcile(model.NewPushContext())
|
||||
}
|
||||
return g.istioController.List(typ, namespace)
|
||||
}
|
||||
@@ -165,10 +165,7 @@ func (g *gatewayController) SetWatchErrorHandler(f func(r *cache.Reflector, err
|
||||
func (g *gatewayController) HasSynced() bool {
|
||||
ret := g.istioController.HasSynced()
|
||||
if ret {
|
||||
err := g.istioController.Reconcile(model.NewPushContext())
|
||||
if err != nil {
|
||||
IngressLog.Errorf("failed to recompute Gateway API resources: %v", err)
|
||||
}
|
||||
g.istioController.Reconcile(model.NewPushContext())
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
461
pkg/ingress/kube/gateway/istio/backend_policies.go
Normal file
461
pkg/ingress/kube/gateway/istio/backend_policies.go
Normal file
@@ -0,0 +1,461 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
gatewayalpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
gatewayalpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
gatewayx "sigs.k8s.io/gateway-api/apisx/v1alpha1"
|
||||
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
kubesecrets "istio.io/istio/pilot/pkg/credentials/kube"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pilot/pkg/model/credentials"
|
||||
"istio.io/istio/pilot/pkg/status"
|
||||
"istio.io/istio/pilot/pkg/util/protoconv"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/config/schema/kind"
|
||||
schematypes "istio.io/istio/pkg/config/schema/kubetypes"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/maps"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/slices"
|
||||
)
|
||||
|
||||
type TypedNamedspacedName struct {
|
||||
types.NamespacedName
|
||||
Kind kind.Kind
|
||||
}
|
||||
|
||||
func (n TypedNamedspacedName) String() string {
|
||||
return n.Kind.String() + "/" + n.NamespacedName.String()
|
||||
}
|
||||
|
||||
type BackendPolicy struct {
|
||||
Source TypedNamedspacedName
|
||||
TargetIndex int
|
||||
Target TypedNamedspacedName
|
||||
TLS *networking.ClientTLSSettings
|
||||
LoadBalancer *networking.LoadBalancerSettings
|
||||
RetryBudget *networking.TrafficPolicy_RetryBudget
|
||||
CreationTime time.Time
|
||||
}
|
||||
|
||||
func (b BackendPolicy) ResourceName() string {
|
||||
return b.Source.String() + "/" + fmt.Sprint(b.TargetIndex)
|
||||
}
|
||||
|
||||
func (b BackendPolicy) Equals(other BackendPolicy) bool {
|
||||
return b.Source == other.Source &&
|
||||
protoconv.Equals(b.TLS, other.TLS) &&
|
||||
protoconv.Equals(b.LoadBalancer, other.LoadBalancer) &&
|
||||
protoconv.Equals(b.RetryBudget, other.RetryBudget)
|
||||
}
|
||||
|
||||
// DestinationRuleCollection returns a collection of DestinationRule objects. These are built from a few different
|
||||
// policy types that are merged together.
|
||||
func DestinationRuleCollection(
|
||||
trafficPolicies krt.Collection[*gatewayx.XBackendTrafficPolicy],
|
||||
tlsPolicies krt.Collection[*gatewayalpha3.BackendTLSPolicy],
|
||||
references *ReferenceSet,
|
||||
domainSuffix string,
|
||||
c *Controller,
|
||||
opts krt.OptionsBuilder,
|
||||
) krt.Collection[*config.Config] {
|
||||
trafficPolicyStatus, backendTrafficPolicies := BackendTrafficPolicyCollection(trafficPolicies, references, opts)
|
||||
status.RegisterStatus(c.status, trafficPolicyStatus, GetStatus)
|
||||
|
||||
tlsPolicyStatus, backendTLSPolicies := BackendTLSPolicyCollection(tlsPolicies, references, opts)
|
||||
status.RegisterStatus(c.status, tlsPolicyStatus, GetStatus)
|
||||
|
||||
// We need to merge these by hostname into a single DR
|
||||
allPolicies := krt.JoinCollection([]krt.Collection[BackendPolicy]{backendTrafficPolicies, backendTLSPolicies})
|
||||
byTarget := krt.NewIndex(allPolicies, "target", func(o BackendPolicy) []TypedNamedspacedName {
|
||||
return []TypedNamedspacedName{o.Target}
|
||||
})
|
||||
indexOpts := append(opts.WithName("BackendPolicyByTarget"), krt.WithIndexCollectionFromString(func(s string) TypedNamedspacedName {
|
||||
parts := strings.Split(s, "/")
|
||||
if len(parts) != 3 {
|
||||
panic("invalid TypedNamedspacedName: " + s)
|
||||
}
|
||||
return TypedNamedspacedName{
|
||||
NamespacedName: types.NamespacedName{
|
||||
Namespace: parts[1],
|
||||
Name: parts[2],
|
||||
},
|
||||
Kind: kind.FromString(parts[0]),
|
||||
}
|
||||
}))
|
||||
merged := krt.NewCollection(
|
||||
byTarget.AsCollection(indexOpts...),
|
||||
func(ctx krt.HandlerContext, i krt.IndexObject[TypedNamedspacedName, BackendPolicy]) **config.Config {
|
||||
svc := i.Key
|
||||
// Sort so we can pick the oldest, which will win.
|
||||
// Not yet standardized but likely will be (https://github.com/kubernetes-sigs/gateway-api/issues/3516#issuecomment-2684039692)
|
||||
pols := slices.SortFunc(i.Objects, func(a, b BackendPolicy) int {
|
||||
if r := a.CreationTime.Compare(b.CreationTime); r != 0 {
|
||||
return r
|
||||
}
|
||||
if r := cmp.Compare(a.Source.Namespace, b.Source.Namespace); r != 0 {
|
||||
return r
|
||||
}
|
||||
return cmp.Compare(a.Source.Name, b.Source.Name)
|
||||
})
|
||||
tlsSet := false
|
||||
lbSet := false
|
||||
rbSet := false
|
||||
spec := &networking.DestinationRule{
|
||||
Host: fmt.Sprintf("%s.%s.svc.%v", svc.Name, svc.Namespace, domainSuffix),
|
||||
TrafficPolicy: &networking.TrafficPolicy{},
|
||||
}
|
||||
parents := make([]string, 0, len(pols))
|
||||
for _, pol := range pols {
|
||||
if pol.TLS != nil {
|
||||
if tlsSet {
|
||||
// We only allow 1. TODO: report status if there are multiple
|
||||
continue
|
||||
}
|
||||
tlsSet = true
|
||||
spec.TrafficPolicy.Tls = pol.TLS
|
||||
}
|
||||
if pol.LoadBalancer != nil {
|
||||
if lbSet {
|
||||
// We only allow 1. TODO: report status if there are multiple
|
||||
continue
|
||||
}
|
||||
lbSet = true
|
||||
spec.TrafficPolicy.LoadBalancer = pol.LoadBalancer
|
||||
}
|
||||
if pol.RetryBudget != nil {
|
||||
if rbSet {
|
||||
// We only allow 1. TODO: report status if there are multiple
|
||||
continue
|
||||
}
|
||||
rbSet = true
|
||||
spec.TrafficPolicy.RetryBudget = pol.RetryBudget
|
||||
}
|
||||
parents = append(parents, fmt.Sprintf("%s/%s.%s", pol.Source.Kind, pol.Source.Namespace, pol.Source.Name))
|
||||
}
|
||||
cfg := &config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.DestinationRule,
|
||||
Name: fmt.Sprintf("%s-%s", svc.Name, constants.KubernetesGatewayName),
|
||||
Namespace: svc.Namespace,
|
||||
Annotations: map[string]string{
|
||||
constants.InternalParentNames: strings.Join(parents, ","),
|
||||
},
|
||||
},
|
||||
Spec: spec,
|
||||
}
|
||||
return &cfg
|
||||
}, opts.WithName("BackendPolicyMerged")...)
|
||||
return merged
|
||||
}
|
||||
|
||||
func BackendTLSPolicyCollection(
|
||||
tlsPolicies krt.Collection[*gatewayalpha3.BackendTLSPolicy],
|
||||
references *ReferenceSet,
|
||||
opts krt.OptionsBuilder,
|
||||
) (krt.StatusCollection[*gatewayalpha3.BackendTLSPolicy, gatewayalpha2.PolicyStatus], krt.Collection[BackendPolicy]) {
|
||||
return krt.NewStatusManyCollection(tlsPolicies, func(ctx krt.HandlerContext, i *gatewayalpha3.BackendTLSPolicy) (
|
||||
*gatewayalpha2.PolicyStatus,
|
||||
[]BackendPolicy,
|
||||
) {
|
||||
status := i.Status.DeepCopy()
|
||||
res := make([]BackendPolicy, 0, len(i.Spec.TargetRefs))
|
||||
ancestors := make([]gatewayalpha2.PolicyAncestorStatus, 0, len(i.Spec.TargetRefs))
|
||||
|
||||
tls := &networking.ClientTLSSettings{Mode: networking.ClientTLSSettings_SIMPLE}
|
||||
s := i.Spec
|
||||
|
||||
conds := map[string]*condition{
|
||||
string(gatewayalpha2.PolicyConditionAccepted): {
|
||||
reason: string(gatewayalpha2.PolicyReasonAccepted),
|
||||
message: "Configuration is valid",
|
||||
},
|
||||
}
|
||||
tls.Sni = string(s.Validation.Hostname)
|
||||
tls.SubjectAltNames = slices.MapFilter(s.Validation.SubjectAltNames, func(e gatewayalpha3.SubjectAltName) *string {
|
||||
switch e.Type {
|
||||
case gatewayalpha3.HostnameSubjectAltNameType:
|
||||
return ptr.Of(string(e.Hostname))
|
||||
case gatewayalpha3.URISubjectAltNameType:
|
||||
return ptr.Of(string(e.URI))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
tls.CredentialName = getBackendTLSCredentialName(s.Validation, i.Namespace, conds, references)
|
||||
for idx, t := range i.Spec.TargetRefs {
|
||||
conds = maps.Clone(conds)
|
||||
refo, err := references.LocalPolicyTargetRef(t.LocalPolicyTargetReference, i.Namespace)
|
||||
if err == nil {
|
||||
switch refo.(type) {
|
||||
case *v1.Service:
|
||||
default:
|
||||
err = fmt.Errorf("unsupported reference kind: %v", t.Kind)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
|
||||
Reason: string(gatewayalpha2.PolicyReasonTargetNotFound),
|
||||
Message: fmt.Sprintf("targetRefs invalid: %v", err),
|
||||
}
|
||||
} else {
|
||||
// Only create an object if we can resolve the target
|
||||
res = append(res, BackendPolicy{
|
||||
Source: TypedNamedspacedName{
|
||||
NamespacedName: config.NamespacedName(i),
|
||||
Kind: kind.BackendTLSPolicy,
|
||||
},
|
||||
TargetIndex: idx,
|
||||
Target: TypedNamedspacedName{
|
||||
NamespacedName: types.NamespacedName{
|
||||
Name: string(t.Name),
|
||||
Namespace: i.Namespace,
|
||||
},
|
||||
Kind: gvk.MustToKind(schematypes.GvkFromObject(refo.(controllers.Object))),
|
||||
},
|
||||
TLS: tls,
|
||||
CreationTime: i.CreationTimestamp.Time,
|
||||
})
|
||||
}
|
||||
// TODO: section name
|
||||
ancestors = append(ancestors, setAncestorStatus(t.LocalPolicyTargetReference, status, i.Generation, conds))
|
||||
}
|
||||
status.Ancestors = mergeAncestors(status.Ancestors, ancestors)
|
||||
return status, res
|
||||
}, opts.WithName("BackendTLSPolicy")...)
|
||||
}
|
||||
|
||||
func getBackendTLSCredentialName(
|
||||
validation gatewayalpha3.BackendTLSPolicyValidation,
|
||||
policyNamespace string,
|
||||
conds map[string]*condition,
|
||||
references *ReferenceSet,
|
||||
) string {
|
||||
if wk := validation.WellKnownCACertificates; wk != nil {
|
||||
switch *wk {
|
||||
case gatewayalpha3.WellKnownCACertificatesSystem:
|
||||
// Already our default, no action needed
|
||||
default:
|
||||
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
|
||||
Reason: string(gatewayalpha2.PolicyReasonInvalid),
|
||||
Message: fmt.Sprintf("Unknown wellKnownCACertificates: %v", *wk),
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
if len(validation.CACertificateRefs) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Spec should require but double check
|
||||
// We only support 1
|
||||
ref := validation.CACertificateRefs[0]
|
||||
if len(validation.CACertificateRefs) > 1 {
|
||||
conds[string(gatewayalpha2.PolicyConditionAccepted)].message += "; warning: only the first caCertificateRefs will be used"
|
||||
}
|
||||
refo, err := references.LocalPolicyRef(ref, policyNamespace)
|
||||
if err == nil {
|
||||
switch to := refo.(type) {
|
||||
case *v1.ConfigMap:
|
||||
if _, rerr := kubesecrets.ExtractRootFromString(to.Data); rerr != nil {
|
||||
err = rerr
|
||||
} else {
|
||||
return credentials.KubernetesConfigMapTypeURI + policyNamespace + "/" + string(ref.Name)
|
||||
}
|
||||
// TODO: for now we do not support Secret references.
|
||||
// Core requires only ConfigMap
|
||||
// We can do so, we just need to make it so this propagates through to SecretAllowed, otherwise clients in other namespaces
|
||||
// will not be given access.
|
||||
// Additionally, we will need to ensure we don't accidentally authorize them to access the private key, just the ca.crt
|
||||
default:
|
||||
err = fmt.Errorf("unsupported reference kind: %v", ref.Kind)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
|
||||
Reason: string(gatewayalpha2.PolicyReasonInvalid),
|
||||
Message: fmt.Sprintf("Certificate reference invalid: %v", err),
|
||||
}
|
||||
// Generate an invalid reference. This ensures traffic is blocked.
|
||||
// See https://github.com/kubernetes-sigs/gateway-api/issues/3516 for upstream clarification on desired behavior here.
|
||||
return credentials.InvalidSecretTypeURI
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func BackendTrafficPolicyCollection(
|
||||
trafficPolicies krt.Collection[*gatewayx.XBackendTrafficPolicy],
|
||||
references *ReferenceSet,
|
||||
opts krt.OptionsBuilder,
|
||||
) (krt.StatusCollection[*gatewayx.XBackendTrafficPolicy, gatewayx.PolicyStatus], krt.Collection[BackendPolicy]) {
|
||||
return krt.NewStatusManyCollection(trafficPolicies, func(ctx krt.HandlerContext, i *gatewayx.XBackendTrafficPolicy) (
|
||||
*gatewayx.PolicyStatus,
|
||||
[]BackendPolicy,
|
||||
) {
|
||||
status := i.Status.DeepCopy()
|
||||
res := make([]BackendPolicy, 0, len(i.Spec.TargetRefs))
|
||||
ancestors := make([]gatewayalpha2.PolicyAncestorStatus, 0, len(i.Spec.TargetRefs))
|
||||
|
||||
lb := &networking.LoadBalancerSettings{}
|
||||
var retryBudget *networking.TrafficPolicy_RetryBudget
|
||||
|
||||
conds := map[string]*condition{
|
||||
string(gatewayalpha2.PolicyConditionAccepted): {
|
||||
reason: string(gatewayalpha2.PolicyReasonAccepted),
|
||||
message: "Configuration is valid",
|
||||
},
|
||||
}
|
||||
var unsupported []string
|
||||
// TODO(https://github.com/istio/istio/issues/55839): implement i.Spec.SessionPersistence.
|
||||
// This will need to map into a StatefulSession filter which Istio doesn't currently support on DestinationRule
|
||||
if i.Spec.SessionPersistence != nil {
|
||||
unsupported = append(unsupported, "sessionPersistence")
|
||||
}
|
||||
if i.Spec.RetryConstraint != nil {
|
||||
// TODO: add support for interval.
|
||||
retryBudget = &networking.TrafficPolicy_RetryBudget{}
|
||||
if i.Spec.RetryConstraint.Budget.Percent != nil {
|
||||
retryBudget.Percent = &wrapperspb.DoubleValue{Value: float64(*i.Spec.RetryConstraint.Budget.Percent)}
|
||||
}
|
||||
retryBudget.MinRetryConcurrency = 10 // Gateway API default
|
||||
if i.Spec.RetryConstraint.MinRetryRate != nil {
|
||||
retryBudget.MinRetryConcurrency = uint32(*i.Spec.RetryConstraint.MinRetryRate.Count)
|
||||
}
|
||||
}
|
||||
if len(unsupported) > 0 {
|
||||
msg := fmt.Sprintf("Configuration is valid, but Istio does not support the following fields: %v", humanReadableJoin(unsupported))
|
||||
conds[string(gatewayalpha2.PolicyConditionAccepted)].message = msg
|
||||
}
|
||||
|
||||
for idx, t := range i.Spec.TargetRefs {
|
||||
conds = maps.Clone(conds)
|
||||
refo, err := references.LocalPolicyTargetRef(t, i.Namespace)
|
||||
if err == nil {
|
||||
switch refo.(type) {
|
||||
case *v1.Service:
|
||||
default:
|
||||
err = fmt.Errorf("unsupported reference kind: %v", t.Kind)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
conds[string(gatewayalpha2.PolicyConditionAccepted)].error = &ConfigError{
|
||||
Reason: string(gatewayalpha2.PolicyReasonTargetNotFound),
|
||||
Message: fmt.Sprintf("targetRefs invalid: %v", err),
|
||||
}
|
||||
} else {
|
||||
// Only create an object if we can resolve the target
|
||||
res = append(res, BackendPolicy{
|
||||
Source: TypedNamedspacedName{
|
||||
NamespacedName: config.NamespacedName(i),
|
||||
Kind: kind.XBackendTrafficPolicy,
|
||||
},
|
||||
TargetIndex: idx,
|
||||
Target: TypedNamedspacedName{
|
||||
NamespacedName: types.NamespacedName{
|
||||
Name: string(t.Name),
|
||||
Namespace: i.Namespace,
|
||||
},
|
||||
Kind: kind.Service,
|
||||
},
|
||||
TLS: nil,
|
||||
LoadBalancer: lb,
|
||||
RetryBudget: retryBudget,
|
||||
CreationTime: i.CreationTimestamp.Time,
|
||||
})
|
||||
}
|
||||
ancestors = append(ancestors, setAncestorStatus(t, status, i.Generation, conds))
|
||||
}
|
||||
status.Ancestors = mergeAncestors(status.Ancestors, ancestors)
|
||||
return status, res
|
||||
}, opts.WithName("BackendTrafficPolicy")...)
|
||||
}
|
||||
|
||||
func setAncestorStatus(
|
||||
t gatewayalpha2.LocalPolicyTargetReference,
|
||||
status *gatewayalpha2.PolicyStatus,
|
||||
generation int64,
|
||||
conds map[string]*condition,
|
||||
) gatewayalpha2.PolicyAncestorStatus {
|
||||
pr := gatewayalpha2.ParentReference{
|
||||
Group: &t.Group,
|
||||
Kind: &t.Kind,
|
||||
Name: t.Name,
|
||||
}
|
||||
currentAncestor := slices.FindFunc(status.Ancestors, func(ex gatewayalpha2.PolicyAncestorStatus) bool {
|
||||
return parentRefEqual(ex.AncestorRef, pr)
|
||||
})
|
||||
var currentConds []metav1.Condition
|
||||
if currentAncestor != nil {
|
||||
currentConds = currentAncestor.Conditions
|
||||
}
|
||||
return gatewayalpha2.PolicyAncestorStatus{
|
||||
AncestorRef: pr,
|
||||
ControllerName: k8s.GatewayController(features.ManagedGatewayController),
|
||||
Conditions: setConditions(generation, currentConds, conds),
|
||||
}
|
||||
}
|
||||
|
||||
func parentRefEqual(a, b gatewayalpha2.ParentReference) bool {
|
||||
return ptr.Equal(a.Group, b.Group) &&
|
||||
ptr.Equal(a.Kind, b.Kind) &&
|
||||
a.Name == b.Name &&
|
||||
ptr.Equal(a.Namespace, b.Namespace) &&
|
||||
ptr.Equal(a.SectionName, b.SectionName) &&
|
||||
ptr.Equal(a.Port, b.Port)
|
||||
}
|
||||
|
||||
// mergeAncestors merges an existing ancestor with in incoming one. We preserve order, prune stale references set by our controller,
|
||||
// and add any new references from our controller.
|
||||
func mergeAncestors(existing []gatewayalpha2.PolicyAncestorStatus, incoming []gatewayalpha2.PolicyAncestorStatus) []gatewayalpha2.PolicyAncestorStatus {
|
||||
ourController := k8s.GatewayController(features.ManagedGatewayController)
|
||||
n := 0
|
||||
for _, x := range existing {
|
||||
if x.ControllerName != ourController {
|
||||
// Keep it as-is
|
||||
existing[n] = x
|
||||
n++
|
||||
continue
|
||||
}
|
||||
replacement := slices.IndexFunc(incoming, func(status gatewayalpha2.PolicyAncestorStatus) bool {
|
||||
return parentRefEqual(status.AncestorRef, x.AncestorRef)
|
||||
})
|
||||
if replacement != -1 {
|
||||
// We found a replacement!
|
||||
existing[n] = incoming[replacement]
|
||||
incoming = slices.Delete(incoming, replacement)
|
||||
n++
|
||||
}
|
||||
// Else, do nothing and it will be filtered
|
||||
}
|
||||
existing = existing[:n]
|
||||
// Add all remaining ones.
|
||||
existing = append(existing, incoming...)
|
||||
return existing
|
||||
}
|
||||
@@ -18,18 +18,16 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1"
|
||||
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pilot/pkg/model/kstatus"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
"istio.io/istio/pkg/maps"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/slices"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
k8sbeta "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
)
|
||||
|
||||
// RouteParentResult holds the result of a route for a specific parent
|
||||
@@ -40,19 +38,31 @@ type RouteParentResult struct {
|
||||
DeniedReason *ParentError
|
||||
// RouteError, if present, indicates why the reference was not valid
|
||||
RouteError *ConfigError
|
||||
// WaypointError, if present, indicates why the reference was does not have a waypoint
|
||||
WaypointError *WaypointError
|
||||
}
|
||||
|
||||
func createRouteStatus(parentResults []RouteParentResult, obj config.Config, currentParents []k8s.RouteParentStatus) []k8s.RouteParentStatus {
|
||||
parents := make([]k8s.RouteParentStatus, 0, len(parentResults))
|
||||
// Fill in all the gateways that are already present but not owned by us. This is non-trivial as there may be multiple
|
||||
// gateway controllers that are exposing their status on the same route. We need to attempt to manage ours properly (including
|
||||
// removing gateway references when they are removed), without mangling other Controller's status.
|
||||
for _, r := range currentParents {
|
||||
if r.ControllerName != constants.ManagedGatewayController {
|
||||
// We don't own this status, so keep it around
|
||||
parents = append(parents, r)
|
||||
func createRouteStatus(
|
||||
parentResults []RouteParentResult,
|
||||
objectNamespace string,
|
||||
generation int64,
|
||||
currentParents []k8s.RouteParentStatus,
|
||||
) []k8s.RouteParentStatus {
|
||||
parents := slices.Clone(currentParents)
|
||||
parentIndexes := map[string]int{}
|
||||
for idx, p := range parents {
|
||||
// Only consider our own
|
||||
if p.ControllerName != k8s.GatewayController(features.ManagedGatewayController) {
|
||||
continue
|
||||
}
|
||||
rs := parentRefString(p.ParentRef, objectNamespace)
|
||||
if _, f := parentIndexes[rs]; f {
|
||||
log.Warnf("invalid HTTPRoute detected: duplicate parent: %v", rs)
|
||||
} else {
|
||||
parentIndexes[rs] = idx
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all of our unique parent references. There may be multiple when we have a route without section name,
|
||||
// but reference a parent with multiple sections.
|
||||
// While we process these internally for-each sectionName, in the status we are just supposed to report one merged entry
|
||||
@@ -72,55 +82,63 @@ func createRouteStatus(parentResults []RouteParentResult, obj config.Config, cur
|
||||
seenReasons.Insert(ParentNoError)
|
||||
}
|
||||
}
|
||||
reasonRanking := []ParentErrorReason{
|
||||
// No errors is preferred
|
||||
ParentNoError,
|
||||
// All route level errors
|
||||
ParentErrorNotAllowed,
|
||||
ParentErrorNoHostname,
|
||||
ParentErrorParentRefConflict,
|
||||
// Failures to match the Port or SectionName. These are last so that if we bind to 1 listener we
|
||||
// just report errors for that 1 listener instead of for all sections we didn't bind to
|
||||
ParentErrorNotAccepted,
|
||||
|
||||
const (
|
||||
rankParentNoErrors = iota
|
||||
rankParentErrorNotAllowed
|
||||
rankParentErrorNoHostname
|
||||
rankParentErrorParentRefConflict
|
||||
rankParentErrorNotAccepted
|
||||
)
|
||||
|
||||
rankParentError := func(result RouteParentResult) int {
|
||||
if result.DeniedReason == nil {
|
||||
return rankParentNoErrors
|
||||
}
|
||||
switch result.DeniedReason.Reason {
|
||||
case ParentErrorNotAllowed:
|
||||
return rankParentErrorNotAllowed
|
||||
case ParentErrorNoHostname:
|
||||
return rankParentErrorNoHostname
|
||||
case ParentErrorParentRefConflict:
|
||||
return rankParentErrorParentRefConflict
|
||||
case ParentErrorNotAccepted:
|
||||
return rankParentErrorNotAccepted
|
||||
}
|
||||
return rankParentNoErrors
|
||||
}
|
||||
|
||||
// Next we want to collapse these. We need to report 1 type of error, or none.
|
||||
report := map[k8s.ParentReference]RouteParentResult{}
|
||||
for _, wantReason := range reasonRanking {
|
||||
if !seenReasons.Contains(wantReason) {
|
||||
for ref, results := range seen {
|
||||
if len(results) == 0 {
|
||||
continue
|
||||
}
|
||||
// We found our highest priority ranking, now we need to collapse this into a single message
|
||||
for k, refs := range seen {
|
||||
for _, ref := range refs {
|
||||
reason := ParentNoError
|
||||
if ref.DeniedReason != nil {
|
||||
reason = ref.DeniedReason.Reason
|
||||
}
|
||||
if wantReason != reason {
|
||||
// Skip this one, it is for a less relevant reason
|
||||
continue
|
||||
}
|
||||
exist, f := report[k]
|
||||
if f {
|
||||
if ref.DeniedReason != nil {
|
||||
if exist.DeniedReason != nil {
|
||||
// join the error
|
||||
exist.DeniedReason.Message += "; " + ref.DeniedReason.Message
|
||||
} else {
|
||||
exist.DeniedReason = ref.DeniedReason
|
||||
}
|
||||
}
|
||||
|
||||
toReport := results[0]
|
||||
mostSevereRankSeen := rankParentError(toReport)
|
||||
|
||||
for _, result := range results[1:] {
|
||||
resultRank := rankParentError(result)
|
||||
// lower number means more severe
|
||||
if resultRank < mostSevereRankSeen {
|
||||
mostSevereRankSeen = resultRank
|
||||
toReport = result
|
||||
} else if resultRank == mostSevereRankSeen {
|
||||
// join the error messages
|
||||
if toReport.DeniedReason == nil {
|
||||
toReport.DeniedReason = result.DeniedReason
|
||||
} else {
|
||||
exist = ref
|
||||
toReport.DeniedReason.Message += "; " + result.DeniedReason.Message
|
||||
}
|
||||
report[k] = exist
|
||||
}
|
||||
}
|
||||
// Once we find the best reason, do not consider any others
|
||||
break
|
||||
|
||||
report[ref] = toReport
|
||||
}
|
||||
|
||||
// Now we fill in all the parents we do own
|
||||
var toAppend []k8s.RouteParentStatus
|
||||
for k, gw := range report {
|
||||
msg := "Route was valid"
|
||||
if successCount[k] > 1 {
|
||||
@@ -151,31 +169,64 @@ func createRouteStatus(parentResults []RouteParentResult, obj config.Config, cur
|
||||
}
|
||||
}
|
||||
|
||||
// when ambient is enabled, report the waypoints resolved condition
|
||||
if features.EnableAmbient {
|
||||
cond := &condition{
|
||||
reason: string(RouteReasonResolvedWaypoints),
|
||||
message: "All waypoints resolved",
|
||||
}
|
||||
if gw.WaypointError != nil {
|
||||
cond.message = gw.WaypointError.Message
|
||||
}
|
||||
conds[string(RouteConditionResolvedWaypoints)] = cond
|
||||
}
|
||||
|
||||
myRef := parentRefString(gw.OriginalReference, objectNamespace)
|
||||
var currentConditions []metav1.Condition
|
||||
currentStatus := slices.FindFunc(currentParents, func(s k8sbeta.RouteParentStatus) bool {
|
||||
return parentRefString(s.ParentRef) == parentRefString(gw.OriginalReference)
|
||||
currentStatus := slices.FindFunc(currentParents, func(s k8s.RouteParentStatus) bool {
|
||||
return parentRefString(s.ParentRef, objectNamespace) == myRef &&
|
||||
s.ControllerName == k8s.GatewayController(features.ManagedGatewayController)
|
||||
})
|
||||
if currentStatus != nil {
|
||||
currentConditions = currentStatus.Conditions
|
||||
}
|
||||
parents = append(parents, k8s.RouteParentStatus{
|
||||
ns := k8s.RouteParentStatus{
|
||||
ParentRef: gw.OriginalReference,
|
||||
ControllerName: constants.ManagedGatewayController,
|
||||
Conditions: setConditions(obj.Generation, currentConditions, conds),
|
||||
})
|
||||
ControllerName: k8s.GatewayController(features.ManagedGatewayController),
|
||||
Conditions: setConditions(generation, currentConditions, conds),
|
||||
}
|
||||
// Parent ref already exists, insert in the same place
|
||||
if idx, f := parentIndexes[myRef]; f {
|
||||
parents[idx] = ns
|
||||
// Clear it out so we can detect which ones we need to delete later
|
||||
delete(parentIndexes, myRef)
|
||||
} else {
|
||||
// Else queue it up to append to the end. We don't append now since we will want to sort them.
|
||||
toAppend = append(toAppend, ns)
|
||||
}
|
||||
}
|
||||
// Ensure output is deterministic.
|
||||
// TODO: will we fight over other controllers doing similar (but not identical) ordering?
|
||||
sort.SliceStable(parents, func(i, j int) bool {
|
||||
return parentRefString(parents[i].ParentRef) > parentRefString(parents[j].ParentRef)
|
||||
sort.SliceStable(toAppend, func(i, j int) bool {
|
||||
return parentRefString(toAppend[i].ParentRef, objectNamespace) > parentRefString(toAppend[j].ParentRef, objectNamespace)
|
||||
})
|
||||
parents = append(parents, toAppend...)
|
||||
toDelete := sets.New(maps.Values(parentIndexes)...)
|
||||
parents = FilterInPlaceByIndex(parents, func(i int) bool {
|
||||
_, f := toDelete[i]
|
||||
return !f
|
||||
})
|
||||
|
||||
if parents == nil {
|
||||
return []k8s.RouteParentStatus{}
|
||||
}
|
||||
return parents
|
||||
}
|
||||
|
||||
type ParentErrorReason string
|
||||
|
||||
const (
|
||||
ParentErrorNotAccepted = ParentErrorReason(k8sbeta.RouteReasonNoMatchingParent)
|
||||
ParentErrorNotAccepted = ParentErrorReason(k8s.RouteReasonNoMatchingParent)
|
||||
ParentErrorNotAllowed = ParentErrorReason(k8s.RouteReasonNotAllowedByListeners)
|
||||
ParentErrorNoHostname = ParentErrorReason(k8s.RouteReasonNoMatchingListenerHostname)
|
||||
ParentErrorParentRefConflict = ParentErrorReason("ParentRefConflict")
|
||||
@@ -185,29 +236,41 @@ const (
|
||||
type ConfigErrorReason = string
|
||||
|
||||
const (
|
||||
// InvalidRefNotPermitted indicates a route was not permitted
|
||||
InvalidRefNotPermitted ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonRefNotPermitted)
|
||||
// InvalidDestination indicates an issue with the destination
|
||||
InvalidDestination ConfigErrorReason = "InvalidDestination"
|
||||
InvalidAddress ConfigErrorReason = ConfigErrorReason(k8sbeta.GatewayReasonUnsupportedAddress)
|
||||
InvalidAddress ConfigErrorReason = ConfigErrorReason(k8s.GatewayReasonUnsupportedAddress)
|
||||
// InvalidDestinationPermit indicates a destination was not permitted
|
||||
InvalidDestinationPermit ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonRefNotPermitted)
|
||||
// InvalidDestinationKind indicates an issue with the destination kind
|
||||
InvalidDestinationKind ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonInvalidKind)
|
||||
// InvalidDestinationNotFound indicates a destination does not exist
|
||||
InvalidDestinationNotFound ConfigErrorReason = ConfigErrorReason(k8s.RouteReasonBackendNotFound)
|
||||
// InvalidParentRef indicates we could not refer to the parent we request
|
||||
InvalidParentRef ConfigErrorReason = "InvalidParentReference"
|
||||
// InvalidFilter indicates an issue with the filters
|
||||
InvalidFilter ConfigErrorReason = "InvalidFilter"
|
||||
// InvalidTLS indicates an issue with TLS settings
|
||||
InvalidTLS ConfigErrorReason = ConfigErrorReason(k8sbeta.ListenerReasonInvalidCertificateRef)
|
||||
InvalidTLS ConfigErrorReason = ConfigErrorReason(k8s.ListenerReasonInvalidCertificateRef)
|
||||
// InvalidListenerRefNotPermitted indicates a listener reference was not permitted
|
||||
InvalidListenerRefNotPermitted ConfigErrorReason = ConfigErrorReason(k8sbeta.ListenerReasonRefNotPermitted)
|
||||
InvalidListenerRefNotPermitted ConfigErrorReason = ConfigErrorReason(k8s.ListenerReasonRefNotPermitted)
|
||||
// InvalidConfiguration indicates a generic error for all other invalid configurations
|
||||
InvalidConfiguration ConfigErrorReason = "InvalidConfiguration"
|
||||
InvalidResources ConfigErrorReason = ConfigErrorReason(k8sbeta.GatewayReasonNoResources)
|
||||
DeprecateFieldUsage = "DeprecatedField"
|
||||
DeprecateFieldUsage ConfigErrorReason = "DeprecatedField"
|
||||
)
|
||||
|
||||
const (
|
||||
// This condition indicates whether a route's parent reference has
|
||||
// a waypoint configured by resolving the "istio.io/use-waypoint" label
|
||||
// on either the referenced parent or the parent's namespace.
|
||||
RouteConditionResolvedWaypoints k8s.RouteConditionType = "ResolvedWaypoints"
|
||||
RouteReasonResolvedWaypoints k8s.RouteConditionReason = "ResolvedWaypoints"
|
||||
)
|
||||
|
||||
type WaypointErrorReason string
|
||||
|
||||
const (
|
||||
WaypointErrorReasonMissingLabel = WaypointErrorReason("MissingUseWaypointLabel")
|
||||
WaypointErrorMsgMissingLabel = "istio.io/use-waypoint label missing from parent and parent namespace; in ambient mode, route will not be respected"
|
||||
WaypointErrorReasonNoMatchingParent = WaypointErrorReason("NoMatchingParent")
|
||||
WaypointErrorMsgNoMatchingParent = "parent not found"
|
||||
)
|
||||
|
||||
// ParentError represents that a parent could not be referenced
|
||||
@@ -222,6 +285,11 @@ type ConfigError struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
type WaypointError struct {
|
||||
Reason WaypointErrorReason
|
||||
Message string
|
||||
}
|
||||
|
||||
type condition struct {
|
||||
// reason defines the reason to report on success. Ignored if error is set
|
||||
reason string
|
||||
@@ -282,59 +350,48 @@ func setConditions(generation int64, existingConditions []metav1.Condition, cond
|
||||
return existingConditions
|
||||
}
|
||||
|
||||
func reportListenerAttachedRoutes(index int, obj config.Config, i int32) {
|
||||
obj.Status.(*kstatus.WrappedStatus).Mutate(func(s config.Status) config.Status {
|
||||
gs := s.(*k8s.GatewayStatus)
|
||||
for index >= len(gs.Listeners) {
|
||||
gs.Listeners = append(gs.Listeners, k8s.ListenerStatus{})
|
||||
func reportListenerCondition(index int, l k8s.Listener, obj controllers.Object,
|
||||
statusListeners []k8s.ListenerStatus, conditions map[string]*condition,
|
||||
) []k8s.ListenerStatus {
|
||||
for index >= len(statusListeners) {
|
||||
statusListeners = append(statusListeners, k8s.ListenerStatus{})
|
||||
}
|
||||
cond := statusListeners[index].Conditions
|
||||
supported, valid := generateSupportedKinds(l)
|
||||
if !valid {
|
||||
conditions[string(k8s.ListenerConditionResolvedRefs)] = &condition{
|
||||
reason: string(k8s.ListenerReasonInvalidRouteKinds),
|
||||
status: metav1.ConditionFalse,
|
||||
message: "Invalid route kinds",
|
||||
}
|
||||
status := gs.Listeners[index]
|
||||
status.AttachedRoutes = i
|
||||
gs.Listeners[index] = status
|
||||
return gs
|
||||
})
|
||||
}
|
||||
|
||||
func reportListenerCondition(index int, l k8s.Listener, obj config.Config, conditions map[string]*condition) {
|
||||
obj.Status.(*kstatus.WrappedStatus).Mutate(func(s config.Status) config.Status {
|
||||
gs := s.(*k8s.GatewayStatus)
|
||||
for index >= len(gs.Listeners) {
|
||||
gs.Listeners = append(gs.Listeners, k8s.ListenerStatus{})
|
||||
}
|
||||
cond := gs.Listeners[index].Conditions
|
||||
supported, valid := generateSupportedKinds(l)
|
||||
if !valid {
|
||||
conditions[string(k8sbeta.ListenerConditionResolvedRefs)] = &condition{
|
||||
reason: string(k8sbeta.ListenerReasonInvalidRouteKinds),
|
||||
status: metav1.ConditionFalse,
|
||||
message: "Invalid route kinds",
|
||||
}
|
||||
}
|
||||
gs.Listeners[index] = k8s.ListenerStatus{
|
||||
Name: l.Name,
|
||||
AttachedRoutes: 0, // this will be reported later
|
||||
SupportedKinds: supported,
|
||||
Conditions: setConditions(obj.Generation, cond, conditions),
|
||||
}
|
||||
return gs
|
||||
})
|
||||
}
|
||||
statusListeners[index] = k8s.ListenerStatus{
|
||||
Name: l.Name,
|
||||
AttachedRoutes: 0, // this will be reported later
|
||||
SupportedKinds: supported,
|
||||
Conditions: setConditions(obj.GetGeneration(), cond, conditions),
|
||||
}
|
||||
return statusListeners
|
||||
}
|
||||
|
||||
func generateSupportedKinds(l k8s.Listener) ([]k8s.RouteGroupKind, bool) {
|
||||
supported := []k8s.RouteGroupKind{}
|
||||
switch l.Protocol {
|
||||
case k8sbeta.HTTPProtocolType, k8sbeta.HTTPSProtocolType:
|
||||
case k8s.HTTPProtocolType, k8s.HTTPSProtocolType:
|
||||
// Only terminate allowed, so its always HTTP
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.HTTPRoute.Group)), Kind: k8s.Kind(gvk.HTTPRoute.Kind)}}
|
||||
case k8sbeta.TCPProtocolType:
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.TCPRoute.Group)), Kind: k8s.Kind(gvk.TCPRoute.Kind)}}
|
||||
case k8sbeta.TLSProtocolType:
|
||||
if l.TLS != nil && l.TLS.Mode != nil && *l.TLS.Mode == k8sbeta.TLSModePassthrough {
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.TLSRoute.Group)), Kind: k8s.Kind(gvk.TLSRoute.Kind)}}
|
||||
} else {
|
||||
supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.TCPRoute.Group)), Kind: k8s.Kind(gvk.TCPRoute.Kind)}}
|
||||
supported = []k8s.RouteGroupKind{
|
||||
toRouteKind(gvk.HTTPRoute),
|
||||
toRouteKind(gvk.GRPCRoute),
|
||||
}
|
||||
// UDP route note support
|
||||
case k8s.TCPProtocolType:
|
||||
supported = []k8s.RouteGroupKind{toRouteKind(gvk.TCPRoute)}
|
||||
case k8s.TLSProtocolType:
|
||||
if l.TLS != nil && l.TLS.Mode != nil && *l.TLS.Mode == k8s.TLSModePassthrough {
|
||||
supported = []k8s.RouteGroupKind{toRouteKind(gvk.TLSRoute)}
|
||||
} else {
|
||||
supported = []k8s.RouteGroupKind{toRouteKind(gvk.TCPRoute)}
|
||||
}
|
||||
// UDP route not support
|
||||
}
|
||||
if l.AllowedRoutes != nil && len(l.AllowedRoutes.Kinds) > 0 {
|
||||
// We need to filter down to only ones we actually support
|
||||
@@ -352,11 +409,15 @@ func generateSupportedKinds(l k8s.Listener) ([]k8s.RouteGroupKind, bool) {
|
||||
return supported, true
|
||||
}
|
||||
|
||||
// This and the following function really belongs in some gateway-api lib
|
||||
func routeGroupKindEqual(rgk1, rgk2 k8s.RouteGroupKind) bool {
|
||||
return rgk1.Kind == rgk2.Kind && getGroup(rgk1) == getGroup(rgk2)
|
||||
}
|
||||
func FilterInPlaceByIndex[E any](s []E, keep func(int) bool) []E {
|
||||
i := 0
|
||||
for j := 0; j < len(s); j++ {
|
||||
if keep(j) {
|
||||
s[i] = s[j]
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
func getGroup(rgk k8s.RouteGroupKind) k8s.Group {
|
||||
return ptr.OrDefault(rgk.Group, k8s.Group(gvk.KubernetesGateway.Group))
|
||||
clear(s[i:]) // zero/nil out the obsolete elements, for GC
|
||||
return s[:i]
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
)
|
||||
|
||||
func TestCreateRouteStatus(t *testing.T) {
|
||||
@@ -32,7 +32,14 @@ func TestCreateRouteStatus(t *testing.T) {
|
||||
parentStatus := []k8s.RouteParentStatus{
|
||||
{
|
||||
ParentRef: parentRef,
|
||||
ControllerName: constants.ManagedGatewayController,
|
||||
ControllerName: k8s.GatewayController("another-gateway-controller"),
|
||||
Conditions: []metav1.Condition{
|
||||
{Type: "foo", Status: "bar"},
|
||||
},
|
||||
},
|
||||
{
|
||||
ParentRef: parentRef,
|
||||
ControllerName: k8s.GatewayController(features.ManagedGatewayController),
|
||||
Conditions: []metav1.Condition{
|
||||
{
|
||||
Type: string(k8s.RouteReasonAccepted),
|
||||
@@ -48,6 +55,13 @@ func TestCreateRouteStatus(t *testing.T) {
|
||||
LastTransitionTime: lastTransitionTime,
|
||||
Message: "All references resolved",
|
||||
},
|
||||
{
|
||||
Type: string(RouteConditionResolvedWaypoints),
|
||||
Status: metav1.ConditionTrue,
|
||||
ObservedGeneration: 1,
|
||||
LastTransitionTime: lastTransitionTime,
|
||||
Message: "All waypoints resolved",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -100,7 +114,7 @@ func TestCreateRouteStatus(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := createRouteStatus(tt.args.gateways, tt.args.obj, tt.args.current)
|
||||
got := createRouteStatus(tt.args.gateways, "default", tt.args.obj.Generation, tt.args.current)
|
||||
equal := reflect.DeepEqual(got, tt.args.current)
|
||||
if equal != tt.wantEqual {
|
||||
t.Errorf("route status: old: %+v, new: %+v", tt.args.current, got)
|
||||
|
||||
@@ -17,35 +17,37 @@ package istio
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
serviceRegistryKube "istio.io/istio/pilot/pkg/serviceregistry/kube"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"istio.io/api/label"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
serviceRegistryKube "istio.io/istio/pilot/pkg/serviceregistry/kube"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// GatewayContext contains a minimal subset of push context functionality to be exposed to GatewayAPIControllers
|
||||
type GatewayContext struct {
|
||||
ps *model.PushContext
|
||||
ps *model.PushContext
|
||||
cluster cluster.ID
|
||||
// Start - Updated by Higress
|
||||
client kube.Client
|
||||
domainSuffix string
|
||||
clusterID cluster.ID
|
||||
// End - Updated by Higress
|
||||
}
|
||||
|
||||
// Start - Updated by Higress
|
||||
|
||||
func NewGatewayContext(ps *model.PushContext, client kube.Client, domainSuffix string, clusterID cluster.ID) GatewayContext {
|
||||
return GatewayContext{ps, client, domainSuffix, clusterID}
|
||||
func NewGatewayContext(ps *model.PushContext, cluster cluster.ID, client kube.Client, domainSuffix string) GatewayContext {
|
||||
return GatewayContext{ps, cluster, client, domainSuffix}
|
||||
}
|
||||
|
||||
// ResolveGatewayInstances attempts to resolve all instances that a gateway will be exposed on.
|
||||
@@ -54,6 +56,7 @@ func NewGatewayContext(ps *model.PushContext, client kube.Client, domainSuffix s
|
||||
// The actual configuration generation is done on a per-workload basis and will get the exact set of matched instances for that workload.
|
||||
// Four sets are exposed:
|
||||
// * Internal addresses (eg istio-ingressgateway.istio-system.svc.cluster.local:80).
|
||||
// * Internal IP addresses (eg 1.2.3.4). This comes from ClusterIP.
|
||||
// * External addresses (eg 1.2.3.4), this comes from LoadBalancer services. There may be multiple in some cases (especially multi cluster).
|
||||
// * Pending addresses (eg istio-ingressgateway.istio-system.svc), are LoadBalancer-type services with pending external addresses.
|
||||
// * Warnings for references that could not be resolved. These are intended to be user facing.
|
||||
@@ -61,19 +64,22 @@ func (gc GatewayContext) ResolveGatewayInstances(
|
||||
namespace string,
|
||||
gwsvcs []string,
|
||||
servers []*networking.Server,
|
||||
) (internal, external, pending, warns []string) {
|
||||
) (internal, external, pending, warns []string, allUsable bool) {
|
||||
ports := map[int]struct{}{}
|
||||
for _, s := range servers {
|
||||
ports[int(s.Port.Number)] = struct{}{}
|
||||
}
|
||||
foundInternal := sets.New[string]()
|
||||
foundInternalIP := sets.New[string]()
|
||||
foundExternal := sets.New[string]()
|
||||
foundPending := sets.New[string]()
|
||||
warnings := []string{}
|
||||
foundUnusable := false
|
||||
|
||||
// Cache endpoints to reduce redundant queries
|
||||
endpointsCache := make(map[string]*corev1.Endpoints)
|
||||
|
||||
log.Debugf("Resolving gateway instances for %v in namespace %s", gwsvcs, namespace)
|
||||
for _, g := range gwsvcs {
|
||||
svc := gc.GetService(g, namespace, gvk.Service.Kind)
|
||||
if svc == nil {
|
||||
@@ -85,6 +91,9 @@ func (gc GatewayContext) ResolveGatewayInstances(
|
||||
exists := checkServicePortExists(svc, port)
|
||||
if exists {
|
||||
foundInternal.Insert(fmt.Sprintf("%s:%d", g, port))
|
||||
dummyProxy := &model.Proxy{Metadata: &model.NodeMetadata{ClusterID: gc.cluster}}
|
||||
dummyProxy.SetIPMode(model.Dual)
|
||||
foundInternalIP.InsertAll(svc.GetAllAddressesForProxy(dummyProxy)...)
|
||||
if svc.Attributes.ClusterExternalAddresses.Len() > 0 {
|
||||
// Fetch external IPs from all clusters
|
||||
svc.Attributes.ClusterExternalAddresses.ForEach(func(c cluster.ID, externalIPs []string) {
|
||||
@@ -121,20 +130,36 @@ func (gc GatewayContext) ResolveGatewayInstances(
|
||||
if hintWorkloadPort {
|
||||
warnings = append(warnings, fmt.Sprintf(
|
||||
"port %d not found for hostname %q (hint: the service port should be specified, not the workload port", port, g))
|
||||
foundUnusable = true
|
||||
} else {
|
||||
warnings = append(warnings, fmt.Sprintf("port %d not found for hostname %q", port, g))
|
||||
_, isManaged := svc.Attributes.Labels[label.GatewayManaged.Name]
|
||||
var portExistsOnService bool
|
||||
for _, p := range svc.Ports {
|
||||
if p.Port == port {
|
||||
portExistsOnService = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// If this is a managed gateway, the only possible explanation for no instances for the port
|
||||
// is a delay in endpoint sync. Therefore, we don't want to warn/change the Programmed condition
|
||||
// in this case as long as the port exists on the `Service` object.
|
||||
if !isManaged || !portExistsOnService {
|
||||
warnings = append(warnings, fmt.Sprintf("port %d not found for hostname %q", port, g))
|
||||
foundUnusable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(warnings)
|
||||
return sets.SortedList(foundInternal), sets.SortedList(foundExternal), sets.SortedList(foundPending), warnings
|
||||
return sets.SortedList(foundInternal), sets.SortedList(foundExternal), sets.SortedList(foundPending),
|
||||
warnings, !foundUnusable
|
||||
}
|
||||
|
||||
func (gc GatewayContext) GetService(hostname, namespace, kind string) *model.Service {
|
||||
// Currently only supports type Kubernetes Service
|
||||
if kind != gvk.Service.Kind {
|
||||
// Currently only supports type Kubernetes Service and InferencePool
|
||||
if kind != gvk.Service.Kind && kind != gvk.InferencePool.Kind {
|
||||
log.Warnf("Unsupported kind: expected 'Service', but got '%s'", kind)
|
||||
return nil
|
||||
}
|
||||
@@ -149,7 +174,7 @@ func (gc GatewayContext) GetService(hostname, namespace, kind string) *model.Ser
|
||||
return nil
|
||||
}
|
||||
|
||||
return serviceRegistryKube.ConvertService(*svc, gc.domainSuffix, gc.clusterID)
|
||||
return serviceRegistryKube.ConvertService(*svc, gc.domainSuffix, gc.cluster, nil)
|
||||
}
|
||||
|
||||
func (gc GatewayContext) GetEndpoints(hostname, namespace string) *corev1.Endpoints {
|
||||
|
||||
@@ -12,25 +12,31 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
"istio.io/istio/pilot/pkg/credentials"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
|
||||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gatewayalpha "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
gatewayalpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
gatewayx "sigs.k8s.io/gateway-api/apisx/v1alpha1"
|
||||
|
||||
networkingclient "istio.io/client-go/pkg/apis/networking/v1"
|
||||
kubesecrets "istio.io/istio/pilot/pkg/credentials/kube"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/model/kstatus"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/status"
|
||||
"istio.io/istio/pkg/cluster"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/labels"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collection"
|
||||
"istio.io/istio/pkg/config/schema/collections"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
@@ -39,110 +45,435 @@ import (
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
"istio.io/istio/pkg/kube/kclient"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/kube/kubetypes"
|
||||
istiolog "istio.io/istio/pkg/log"
|
||||
"istio.io/istio/pkg/maps"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/revisions"
|
||||
"istio.io/istio/pkg/slices"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
klabels "k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var log = istiolog.RegisterScope("gateway", "gateway-api controller")
|
||||
|
||||
var errUnsupportedOp = fmt.Errorf("unsupported operation: the gateway config store is a read-only view")
|
||||
|
||||
// Controller defines the controller for the gateway-api. The controller acts a bit different from most.
|
||||
// Rather than watching the CRs directly, we depend on the existing model.ConfigStoreController which
|
||||
// already watches all CRs. When there are updates, a new PushContext will be computed, which will eventually
|
||||
// call Controller.Reconcile(). Once this happens, we will inspect the current state of the world, and transform
|
||||
// gateway-api types into Istio types (Gateway/VirtualService). Future calls to Get/List will return these
|
||||
// Istio types. These are not stored in the cluster at all, and are purely internal; they can be seen on /debug/configz.
|
||||
// During Reconcile(), the status on all gateway-api types is also tracked. Once completed, if the status
|
||||
// has changed at all, it is queued to asynchronously update the status of the object in Kubernetes.
|
||||
// Controller defines the controller for the gateway-api. The controller reads a variety of resources (Gateway types, as well
|
||||
// as adjacent types like Namespace and Service), and through `krt`, translates them into Istio types (Gateway/VirtualService).
|
||||
//
|
||||
// Most resources are fully "self-contained" with krt, but there are a few usages breaking out of `krt`; these are managed by `krt.RecomputeProtected`.
|
||||
// These are recomputed on each new PushContext initialization, which will call Controller.Reconcile().
|
||||
//
|
||||
// The generated Istio types are not stored in the cluster at all and are purely internal. Calls to List() (from PushContext)
|
||||
// will expose these. They can be introspected at /debug/configz.
|
||||
//
|
||||
// The status on all gateway-api types is also tracked. Each collection emits downstream objects, but also status about the
|
||||
// input type. If the status changes, it is queued to asynchronously update the status of the object in Kubernetes.
|
||||
type Controller struct {
|
||||
// client for accessing Kubernetes
|
||||
client kube.Client
|
||||
// cache provides access to the underlying gateway-configs
|
||||
cache model.ConfigStoreController
|
||||
|
||||
// Gateway-api types reference namespace labels directly, so we need access to these
|
||||
namespaces kclient.Client[*corev1.Namespace]
|
||||
namespaceHandler model.EventHandler
|
||||
|
||||
// Gateway-api types reference secrets directly, so we need access to these
|
||||
credentialsController credentials.MulticlusterController
|
||||
secretHandler model.EventHandler
|
||||
|
||||
// the cluster where the gateway-api controller runs
|
||||
cluster cluster.ID
|
||||
// domain stores the cluster domain, typically cluster.local
|
||||
domain string
|
||||
// revision the controller is running under
|
||||
revision string
|
||||
|
||||
// state is our computed Istio resources. Access is guarded by stateMu. This is updated from Reconcile().
|
||||
state IstioResources
|
||||
stateMu sync.RWMutex
|
||||
|
||||
// statusController controls the status working queue. Status will only be written if statusEnabled is true, which
|
||||
// status controls the status writing queue. Status will only be written if statusEnabled is true, which
|
||||
// is only the case when we are the leader.
|
||||
statusController *status.Controller
|
||||
statusEnabled *atomic.Bool
|
||||
status *status.StatusCollections
|
||||
|
||||
waitForCRD func(class schema.GroupVersionResource, stop <-chan struct{}) bool
|
||||
|
||||
// gatewayContext exposes us to the internal Istio service registry. This is outside krt knowledge (currently), so,
|
||||
// so we wrap it in a RecomputeProtected.
|
||||
// Most usages in the API are directly referenced typed objects (Service, ServiceEntry, etc) so this is not needed typically.
|
||||
gatewayContext krt.RecomputeProtected[*atomic.Pointer[GatewayContext]]
|
||||
// tagWatcher allows us to check which tags are ours. Unlike most Istio codepaths, we read istio.io/rev=<tag> and not just
|
||||
// revisions for Gateways. This is because a Gateway is sort of a mix of a Deployment and Config.
|
||||
// Since the TagWatcher is not yet krt-aware, we wrap this in RecomputeProtected.
|
||||
tagWatcher krt.RecomputeProtected[revisions.TagWatcher]
|
||||
|
||||
stop chan struct{}
|
||||
|
||||
xdsUpdater model.XDSUpdater
|
||||
|
||||
// Handlers tracks all registered handlers, so that syncing can be detected
|
||||
handlers []krt.HandlerRegistration
|
||||
|
||||
// outputs contains all the output collections for this controller.
|
||||
// Currently, the only usage of this controller is from non-krt things (PushContext) so this is not exposed directly.
|
||||
// If desired in the future, it could be.
|
||||
outputs Outputs
|
||||
|
||||
domainSuffix string // the domain suffix to use for generated resources
|
||||
|
||||
shadowServiceReconciler controllers.Queue
|
||||
|
||||
// Start - Added by Higress
|
||||
DefaultGatewaySelector map[string]string
|
||||
// End - Added by Higress
|
||||
}
|
||||
|
||||
waitForCRD func(class schema.GroupVersionResource, stop <-chan struct{}) bool
|
||||
type ParentInfo struct {
|
||||
Key parentKey
|
||||
Info parentInfo
|
||||
}
|
||||
|
||||
func (pi ParentInfo) ResourceName() string {
|
||||
return pi.Key.Name // TODO!!!! more infoi and section name
|
||||
}
|
||||
|
||||
type TypedResource struct {
|
||||
Kind config.GroupVersionKind
|
||||
Name types.NamespacedName
|
||||
}
|
||||
|
||||
type Outputs struct {
|
||||
Gateways krt.Collection[Gateway]
|
||||
VirtualServices krt.Collection[*config.Config]
|
||||
ReferenceGrants ReferenceGrants
|
||||
DestinationRules krt.Collection[*config.Config]
|
||||
InferencePools krt.Collection[InferencePool]
|
||||
InferencePoolsByGateway krt.Index[types.NamespacedName, InferencePool]
|
||||
}
|
||||
|
||||
type Inputs struct {
|
||||
Namespaces krt.Collection[*corev1.Namespace]
|
||||
|
||||
Services krt.Collection[*corev1.Service]
|
||||
Secrets krt.Collection[*corev1.Secret]
|
||||
ConfigMaps krt.Collection[*corev1.ConfigMap]
|
||||
|
||||
GatewayClasses krt.Collection[*gateway.GatewayClass]
|
||||
Gateways krt.Collection[*gateway.Gateway]
|
||||
HTTPRoutes krt.Collection[*gateway.HTTPRoute]
|
||||
GRPCRoutes krt.Collection[*gatewayv1.GRPCRoute]
|
||||
TCPRoutes krt.Collection[*gatewayalpha.TCPRoute]
|
||||
TLSRoutes krt.Collection[*gatewayalpha.TLSRoute]
|
||||
ListenerSets krt.Collection[*gatewayx.XListenerSet]
|
||||
ReferenceGrants krt.Collection[*gateway.ReferenceGrant]
|
||||
BackendTrafficPolicy krt.Collection[*gatewayx.XBackendTrafficPolicy]
|
||||
BackendTLSPolicies krt.Collection[*gatewayalpha3.BackendTLSPolicy]
|
||||
ServiceEntries krt.Collection[*networkingclient.ServiceEntry]
|
||||
InferencePools krt.Collection[*inferencev1alpha2.InferencePool]
|
||||
}
|
||||
|
||||
var _ model.GatewayController = &Controller{}
|
||||
|
||||
func NewController(
|
||||
kc kube.Client,
|
||||
c model.ConfigStoreController,
|
||||
waitForCRD func(class schema.GroupVersionResource, stop <-chan struct{}) bool,
|
||||
credsController credentials.MulticlusterController,
|
||||
options controller.Options,
|
||||
xdsUpdater model.XDSUpdater,
|
||||
) *Controller {
|
||||
var ctl *status.Controller
|
||||
stop := make(chan struct{})
|
||||
opts := krt.NewOptionsBuilder(stop, "gateway", options.KrtDebugger)
|
||||
|
||||
namespaces := kclient.New[*corev1.Namespace](kc)
|
||||
gatewayController := &Controller{
|
||||
client: kc,
|
||||
cache: c,
|
||||
namespaces: namespaces,
|
||||
credentialsController: credsController,
|
||||
cluster: options.ClusterID,
|
||||
domain: options.DomainSuffix,
|
||||
statusController: ctl,
|
||||
// Disabled by default, we will enable only if we win the leader election
|
||||
statusEnabled: atomic.NewBool(false),
|
||||
waitForCRD: waitForCRD,
|
||||
tw := revisions.NewTagWatcher(kc, options.Revision)
|
||||
c := &Controller{
|
||||
client: kc,
|
||||
cluster: options.ClusterID,
|
||||
revision: options.Revision,
|
||||
status: &status.StatusCollections{},
|
||||
tagWatcher: krt.NewRecomputeProtected(tw, false, opts.WithName("tagWatcher")...),
|
||||
waitForCRD: waitForCRD,
|
||||
gatewayContext: krt.NewRecomputeProtected(atomic.NewPointer[GatewayContext](nil), false, opts.WithName("gatewayContext")...),
|
||||
stop: stop,
|
||||
xdsUpdater: xdsUpdater,
|
||||
domainSuffix: options.DomainSuffix,
|
||||
}
|
||||
|
||||
namespaces.AddEventHandler(controllers.EventHandler[*corev1.Namespace]{
|
||||
UpdateFunc: func(oldNs, newNs *corev1.Namespace) {
|
||||
if options.DiscoveryNamespacesFilter != nil && !options.DiscoveryNamespacesFilter.Filter(newNs) {
|
||||
return
|
||||
}
|
||||
if !labels.Instance(oldNs.Labels).Equals(newNs.Labels) {
|
||||
gatewayController.namespaceEvent(oldNs, newNs)
|
||||
}
|
||||
},
|
||||
tw.AddHandler(func(s sets.String) {
|
||||
c.tagWatcher.TriggerRecomputation()
|
||||
})
|
||||
|
||||
if credsController != nil {
|
||||
credsController.AddSecretHandler(gatewayController.secretEvent)
|
||||
svcClient := kclient.NewFiltered[*corev1.Service](kc, kubetypes.Filter{ObjectFilter: kc.ObjectFilter()})
|
||||
|
||||
inputs := Inputs{
|
||||
Namespaces: krt.NewInformer[*corev1.Namespace](kc, opts.WithName("informer/Namespaces")...),
|
||||
Secrets: krt.WrapClient[*corev1.Secret](
|
||||
kclient.NewFiltered[*corev1.Secret](kc, kubetypes.Filter{
|
||||
FieldSelector: kubesecrets.SecretsFieldSelector,
|
||||
ObjectFilter: kc.ObjectFilter(),
|
||||
}),
|
||||
opts.WithName("informer/Secrets")...,
|
||||
),
|
||||
ConfigMaps: krt.WrapClient[*corev1.ConfigMap](
|
||||
kclient.NewFiltered[*corev1.ConfigMap](kc, kubetypes.Filter{ObjectFilter: kc.ObjectFilter()}),
|
||||
opts.WithName("informer/ConfigMaps")...,
|
||||
),
|
||||
Services: krt.WrapClient[*corev1.Service](svcClient, opts.WithName("informer/Services")...),
|
||||
GatewayClasses: buildClient[*gateway.GatewayClass](c, kc, gvr.GatewayClass, opts, "informer/GatewayClasses"),
|
||||
Gateways: buildClient[*gateway.Gateway](c, kc, gvr.KubernetesGateway, opts, "informer/Gateways"),
|
||||
HTTPRoutes: buildClient[*gateway.HTTPRoute](c, kc, gvr.HTTPRoute, opts, "informer/HTTPRoutes"),
|
||||
GRPCRoutes: buildClient[*gatewayv1.GRPCRoute](c, kc, gvr.GRPCRoute, opts, "informer/GRPCRoutes"),
|
||||
|
||||
ReferenceGrants: buildClient[*gateway.ReferenceGrant](c, kc, gvr.ReferenceGrant, opts, "informer/ReferenceGrants"),
|
||||
ServiceEntries: buildClient[*networkingclient.ServiceEntry](c, kc, gvr.ServiceEntry, opts, "informer/ServiceEntries"),
|
||||
}
|
||||
if features.EnableAlphaGatewayAPI {
|
||||
inputs.TCPRoutes = buildClient[*gatewayalpha.TCPRoute](c, kc, gvr.TCPRoute, opts, "informer/TCPRoutes")
|
||||
inputs.TLSRoutes = buildClient[*gatewayalpha.TLSRoute](c, kc, gvr.TLSRoute, opts, "informer/TLSRoutes")
|
||||
inputs.BackendTLSPolicies = buildClient[*gatewayalpha3.BackendTLSPolicy](c, kc, gvr.BackendTLSPolicy, opts, "informer/BackendTLSPolicies")
|
||||
inputs.BackendTrafficPolicy = buildClient[*gatewayx.XBackendTrafficPolicy](c, kc, gvr.XBackendTrafficPolicy, opts, "informer/XBackendTrafficPolicy")
|
||||
inputs.ListenerSets = buildClient[*gatewayx.XListenerSet](c, kc, gvr.XListenerSet, opts, "informer/XListenerSet")
|
||||
} else {
|
||||
// If disabled, still build a collection but make it always empty
|
||||
inputs.TCPRoutes = krt.NewStaticCollection[*gatewayalpha.TCPRoute](nil, nil, opts.WithName("disable/TCPRoutes")...)
|
||||
inputs.TLSRoutes = krt.NewStaticCollection[*gatewayalpha.TLSRoute](nil, nil, opts.WithName("disable/TLSRoutes")...)
|
||||
inputs.BackendTLSPolicies = krt.NewStaticCollection[*gatewayalpha3.BackendTLSPolicy](nil, nil, opts.WithName("disable/BackendTLSPolicies")...)
|
||||
inputs.BackendTrafficPolicy = krt.NewStaticCollection[*gatewayx.XBackendTrafficPolicy](nil, nil, opts.WithName("disable/XBackendTrafficPolicy")...)
|
||||
inputs.ListenerSets = krt.NewStaticCollection[*gatewayx.XListenerSet](nil, nil, opts.WithName("disable/XListenerSet")...)
|
||||
}
|
||||
|
||||
return gatewayController
|
||||
if features.EnableGatewayAPIInferenceExtension {
|
||||
inputs.InferencePools = buildClient[*inferencev1alpha2.InferencePool](c, kc, gvr.InferencePool, opts, "informer/InferencePools")
|
||||
} else {
|
||||
// If disabled, still build a collection but make it always empty
|
||||
inputs.InferencePools = krt.NewStaticCollection[*inferencev1alpha2.InferencePool](nil, nil, opts.WithName("disable/InferencePools")...)
|
||||
}
|
||||
|
||||
references := NewReferenceSet(
|
||||
AddReference(inputs.Services),
|
||||
AddReference(inputs.ConfigMaps),
|
||||
AddReference(inputs.Secrets),
|
||||
)
|
||||
|
||||
handlers := []krt.HandlerRegistration{}
|
||||
|
||||
httpRoutesByInferencePool := krt.NewIndex(inputs.HTTPRoutes, "inferencepool-route", indexHTTPRouteByInferencePool)
|
||||
|
||||
GatewayClassStatus, GatewayClasses := GatewayClassesCollection(inputs.GatewayClasses, opts)
|
||||
status.RegisterStatus(c.status, GatewayClassStatus, GetStatus)
|
||||
|
||||
ReferenceGrants := BuildReferenceGrants(ReferenceGrantsCollection(inputs.ReferenceGrants, opts))
|
||||
ListenerSetStatus, ListenerSets := ListenerSetCollection(
|
||||
inputs.ListenerSets,
|
||||
inputs.Gateways,
|
||||
GatewayClasses,
|
||||
inputs.Namespaces,
|
||||
ReferenceGrants,
|
||||
inputs.Secrets,
|
||||
options.DomainSuffix,
|
||||
c.gatewayContext,
|
||||
c.tagWatcher,
|
||||
opts,
|
||||
c.DefaultGatewaySelector,
|
||||
)
|
||||
status.RegisterStatus(c.status, ListenerSetStatus, GetStatus)
|
||||
|
||||
DestinationRules := DestinationRuleCollection(
|
||||
inputs.BackendTrafficPolicy,
|
||||
inputs.BackendTLSPolicies,
|
||||
references,
|
||||
c.domainSuffix,
|
||||
c,
|
||||
opts,
|
||||
)
|
||||
|
||||
// GatewaysStatus is not fully complete until its join with route attachments to report attachedRoutes.
|
||||
// Do not register yet.
|
||||
GatewaysStatus, Gateways := GatewayCollection(
|
||||
inputs.Gateways,
|
||||
ListenerSets,
|
||||
GatewayClasses,
|
||||
inputs.Namespaces,
|
||||
ReferenceGrants,
|
||||
inputs.Secrets,
|
||||
c.domainSuffix,
|
||||
c.gatewayContext,
|
||||
c.tagWatcher,
|
||||
opts,
|
||||
c.DefaultGatewaySelector,
|
||||
)
|
||||
|
||||
InferencePoolStatus, InferencePools := InferencePoolCollection(
|
||||
inputs.InferencePools,
|
||||
inputs.Services,
|
||||
inputs.HTTPRoutes,
|
||||
inputs.Gateways,
|
||||
httpRoutesByInferencePool,
|
||||
c,
|
||||
opts,
|
||||
)
|
||||
|
||||
// Create a queue for handling service updates.
|
||||
// We create the queue even if the env var is off just to prevent nil pointer issues.
|
||||
c.shadowServiceReconciler = controllers.NewQueue("inference pool shadow service reconciler",
|
||||
controllers.WithReconciler(c.reconcileShadowService(svcClient, InferencePools, inputs.Services)),
|
||||
controllers.WithMaxAttempts(5))
|
||||
|
||||
if features.EnableGatewayAPIInferenceExtension {
|
||||
status.RegisterStatus(c.status, InferencePoolStatus, GetStatus)
|
||||
}
|
||||
|
||||
RouteParents := BuildRouteParents(Gateways)
|
||||
|
||||
routeInputs := RouteContextInputs{
|
||||
Grants: ReferenceGrants,
|
||||
RouteParents: RouteParents,
|
||||
DomainSuffix: c.domainSuffix,
|
||||
Services: inputs.Services,
|
||||
Namespaces: inputs.Namespaces,
|
||||
ServiceEntries: inputs.ServiceEntries,
|
||||
InferencePools: inputs.InferencePools,
|
||||
internalContext: c.gatewayContext,
|
||||
}
|
||||
tcpRoutes := TCPRouteCollection(
|
||||
inputs.TCPRoutes,
|
||||
routeInputs,
|
||||
opts,
|
||||
)
|
||||
status.RegisterStatus(c.status, tcpRoutes.Status, GetStatus)
|
||||
tlsRoutes := TLSRouteCollection(
|
||||
inputs.TLSRoutes,
|
||||
routeInputs,
|
||||
opts,
|
||||
)
|
||||
status.RegisterStatus(c.status, tlsRoutes.Status, GetStatus)
|
||||
httpRoutes := HTTPRouteCollection(
|
||||
inputs.HTTPRoutes,
|
||||
routeInputs,
|
||||
opts,
|
||||
)
|
||||
status.RegisterStatus(c.status, httpRoutes.Status, GetStatus)
|
||||
grpcRoutes := GRPCRouteCollection(
|
||||
inputs.GRPCRoutes,
|
||||
routeInputs,
|
||||
opts,
|
||||
)
|
||||
status.RegisterStatus(c.status, grpcRoutes.Status, GetStatus)
|
||||
|
||||
RouteAttachments := krt.JoinCollection([]krt.Collection[RouteAttachment]{
|
||||
tcpRoutes.RouteAttachments,
|
||||
tlsRoutes.RouteAttachments,
|
||||
httpRoutes.RouteAttachments,
|
||||
grpcRoutes.RouteAttachments,
|
||||
}, opts.WithName("RouteAttachments")...)
|
||||
RouteAttachmentsIndex := krt.NewIndex(RouteAttachments, "to", func(o RouteAttachment) []types.NamespacedName {
|
||||
return []types.NamespacedName{o.To}
|
||||
})
|
||||
|
||||
GatewayFinalStatus := FinalGatewayStatusCollection(GatewaysStatus, RouteAttachments, RouteAttachmentsIndex, opts)
|
||||
status.RegisterStatus(c.status, GatewayFinalStatus, GetStatus)
|
||||
|
||||
VirtualServices := krt.JoinCollection([]krt.Collection[*config.Config]{
|
||||
tcpRoutes.VirtualServices,
|
||||
tlsRoutes.VirtualServices,
|
||||
httpRoutes.VirtualServices,
|
||||
grpcRoutes.VirtualServices,
|
||||
}, opts.WithName("DerivedVirtualServices")...)
|
||||
|
||||
InferencePoolsByGateway := krt.NewIndex(InferencePools, "byGateway", func(i InferencePool) []types.NamespacedName {
|
||||
return i.gatewayParents.UnsortedList()
|
||||
})
|
||||
|
||||
outputs := Outputs{
|
||||
ReferenceGrants: ReferenceGrants,
|
||||
Gateways: Gateways,
|
||||
VirtualServices: VirtualServices,
|
||||
DestinationRules: DestinationRules,
|
||||
InferencePools: InferencePools,
|
||||
InferencePoolsByGateway: InferencePoolsByGateway,
|
||||
}
|
||||
c.outputs = outputs
|
||||
|
||||
handlers = append(handlers,
|
||||
outputs.VirtualServices.RegisterBatch(pushXds(xdsUpdater,
|
||||
func(t *config.Config) model.ConfigKey {
|
||||
return model.ConfigKey{
|
||||
Kind: kind.VirtualService,
|
||||
Name: t.Name,
|
||||
Namespace: t.Namespace,
|
||||
}
|
||||
}), false),
|
||||
outputs.DestinationRules.RegisterBatch(pushXds(xdsUpdater,
|
||||
func(t *config.Config) model.ConfigKey {
|
||||
return model.ConfigKey{
|
||||
Kind: kind.DestinationRule,
|
||||
Name: t.Name,
|
||||
Namespace: t.Namespace,
|
||||
}
|
||||
}), false),
|
||||
outputs.Gateways.RegisterBatch(pushXds(xdsUpdater,
|
||||
func(t Gateway) model.ConfigKey {
|
||||
return model.ConfigKey{
|
||||
Kind: kind.Gateway,
|
||||
Name: t.Name,
|
||||
Namespace: t.Namespace,
|
||||
}
|
||||
}), false),
|
||||
outputs.InferencePools.Register(func(e krt.Event[InferencePool]) {
|
||||
obj := e.Latest()
|
||||
c.shadowServiceReconciler.Add(types.NamespacedName{
|
||||
Namespace: obj.shadowService.key.Namespace,
|
||||
Name: obj.shadowService.poolName,
|
||||
})
|
||||
}),
|
||||
// Reconcile shadow services if users break them.
|
||||
inputs.Services.Register(func(o krt.Event[*corev1.Service]) {
|
||||
obj := o.Latest()
|
||||
// We only care about services that are tagged with the internal service semantics label.
|
||||
if obj.GetLabels()[constants.InternalServiceSemantics] != constants.ServiceSemanticsInferencePool {
|
||||
return
|
||||
}
|
||||
// We only care about delete events
|
||||
if o.Event != controllers.EventDelete && o.Event != controllers.EventUpdate {
|
||||
return
|
||||
}
|
||||
|
||||
poolName, ok := obj.Labels[InferencePoolRefLabel]
|
||||
if !ok && o.Event == controllers.EventUpdate && o.Old != nil {
|
||||
// Try and find the label from the old object
|
||||
old := ptr.Flatten(o.Old)
|
||||
poolName, ok = old.Labels[InferencePoolRefLabel]
|
||||
}
|
||||
|
||||
if !ok {
|
||||
log.Errorf("service %s/%s is missing the %s label, cannot reconcile shadow service",
|
||||
obj.Namespace, obj.Name, InferencePoolRefLabel)
|
||||
return
|
||||
}
|
||||
|
||||
// Add it back
|
||||
c.shadowServiceReconciler.Add(types.NamespacedName{
|
||||
Namespace: obj.Namespace,
|
||||
Name: poolName,
|
||||
})
|
||||
log.Infof("Re-adding shadow service for deleted inference pool service %s/%s",
|
||||
obj.Namespace, obj.Name)
|
||||
}),
|
||||
)
|
||||
c.handlers = handlers
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// buildClient is a small wrapper to build a krt collection based on a delayed informer.
|
||||
func buildClient[I controllers.ComparableObject](
|
||||
c *Controller,
|
||||
kc kube.Client,
|
||||
res schema.GroupVersionResource,
|
||||
opts krt.OptionsBuilder,
|
||||
name string,
|
||||
) krt.Collection[I] {
|
||||
filter := kclient.Filter{
|
||||
ObjectFilter: kubetypes.ComposeFilters(kc.ObjectFilter(), c.inRevision),
|
||||
}
|
||||
|
||||
// all other types are filtered by revision, but for gateways we need to select tags as well
|
||||
if res == gvr.KubernetesGateway {
|
||||
filter.ObjectFilter = kc.ObjectFilter()
|
||||
}
|
||||
|
||||
cc := kclient.NewDelayedInformer[I](kc, res, kubetypes.StandardInformer, filter)
|
||||
return krt.WrapClient[I](cc, opts.WithName(name)...)
|
||||
}
|
||||
|
||||
func (c *Controller) Schemas() collection.Schemas {
|
||||
return collection.SchemasFor(
|
||||
collections.VirtualService,
|
||||
collections.Gateway,
|
||||
collections.DestinationRule,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -151,115 +482,46 @@ func (c *Controller) Get(typ config.GroupVersionKind, name, namespace string) *c
|
||||
}
|
||||
|
||||
func (c *Controller) List(typ config.GroupVersionKind, namespace string) []config.Config {
|
||||
if typ != gvk.Gateway && typ != gvk.VirtualService {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.stateMu.RLock()
|
||||
defer c.stateMu.RUnlock()
|
||||
switch typ {
|
||||
case gvk.Gateway:
|
||||
return filterNamespace(c.state.Gateway, namespace)
|
||||
res := slices.MapFilter(c.outputs.Gateways.List(), func(g Gateway) *config.Config {
|
||||
if g.Valid {
|
||||
return g.Config
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return res
|
||||
case gvk.VirtualService:
|
||||
return filterNamespace(c.state.VirtualService, namespace)
|
||||
return slices.Map(c.outputs.VirtualServices.List(), func(e *config.Config) config.Config {
|
||||
return *e
|
||||
})
|
||||
case gvk.DestinationRule:
|
||||
return slices.Map(c.outputs.DestinationRules.List(), func(e *config.Config) config.Config {
|
||||
return *e
|
||||
})
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) SetStatusWrite(enabled bool, statusManager *status.Manager) {
|
||||
c.statusEnabled.Store(enabled)
|
||||
if enabled && features.EnableGatewayAPIStatus && statusManager != nil {
|
||||
c.statusController = statusManager.CreateGenericController(func(status any, context any) status.GenerationProvider {
|
||||
return &gatewayGeneration{context}
|
||||
var q status.Queue = statusManager.CreateGenericController(func(status status.Manipulator, context any) {
|
||||
status.SetInner(context)
|
||||
})
|
||||
c.status.SetQueue(q)
|
||||
} else {
|
||||
c.statusController = nil
|
||||
c.status.UnsetQueue()
|
||||
}
|
||||
}
|
||||
|
||||
// Reconcile takes in a current snapshot of the gateway-api configs, and regenerates our internal state.
|
||||
// Any status updates required will be enqueued as well.
|
||||
func (c *Controller) Reconcile(ps *model.PushContext) error {
|
||||
t0 := time.Now()
|
||||
defer func() {
|
||||
log.Debugf("reconcile complete in %v", time.Since(t0))
|
||||
}()
|
||||
gatewayClass := c.cache.List(gvk.GatewayClass, metav1.NamespaceAll)
|
||||
gateway := c.cache.List(gvk.KubernetesGateway, metav1.NamespaceAll)
|
||||
httpRoute := c.cache.List(gvk.HTTPRoute, metav1.NamespaceAll)
|
||||
tcpRoute := c.cache.List(gvk.TCPRoute, metav1.NamespaceAll)
|
||||
tlsRoute := c.cache.List(gvk.TLSRoute, metav1.NamespaceAll)
|
||||
referenceGrant := c.cache.List(gvk.ReferenceGrant, metav1.NamespaceAll)
|
||||
|
||||
input := GatewayResources{
|
||||
GatewayClass: deepCopyStatus(gatewayClass),
|
||||
Gateway: deepCopyStatus(gateway),
|
||||
HTTPRoute: deepCopyStatus(httpRoute),
|
||||
TCPRoute: deepCopyStatus(tcpRoute),
|
||||
TLSRoute: deepCopyStatus(tlsRoute),
|
||||
ReferenceGrant: referenceGrant,
|
||||
DefaultGatewaySelector: c.DefaultGatewaySelector,
|
||||
Domain: c.domain,
|
||||
// Start - Updated by Higress
|
||||
Context: NewGatewayContext(ps, c.client, c.domain, c.cluster),
|
||||
// End - Updated by Higress
|
||||
}
|
||||
|
||||
if !input.hasResources() {
|
||||
// Early exit for common case of no gateway-api used.
|
||||
c.stateMu.Lock()
|
||||
defer c.stateMu.Unlock()
|
||||
// make sure we clear out the state, to handle the last gateway-api resource being removed
|
||||
c.state = IstioResources{}
|
||||
return nil
|
||||
}
|
||||
|
||||
nsl := c.namespaces.List("", klabels.Everything())
|
||||
namespaces := make(map[string]*corev1.Namespace, len(nsl))
|
||||
for _, ns := range nsl {
|
||||
namespaces[ns.Name] = ns
|
||||
}
|
||||
input.Namespaces = namespaces
|
||||
|
||||
if c.credentialsController != nil {
|
||||
credentials, err := c.credentialsController.ForCluster(c.cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get credentials: %v", err)
|
||||
}
|
||||
input.Credentials = credentials
|
||||
}
|
||||
|
||||
output := convertResources(input)
|
||||
|
||||
// Handle all status updates
|
||||
c.QueueStatusUpdates(input)
|
||||
|
||||
c.stateMu.Lock()
|
||||
defer c.stateMu.Unlock()
|
||||
c.state = output
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) QueueStatusUpdates(r GatewayResources) {
|
||||
c.handleStatusUpdates(r.GatewayClass)
|
||||
c.handleStatusUpdates(r.Gateway)
|
||||
c.handleStatusUpdates(r.HTTPRoute)
|
||||
c.handleStatusUpdates(r.TCPRoute)
|
||||
c.handleStatusUpdates(r.TLSRoute)
|
||||
}
|
||||
|
||||
func (c *Controller) handleStatusUpdates(configs []config.Config) {
|
||||
if c.statusController == nil || !c.statusEnabled.Load() {
|
||||
return
|
||||
}
|
||||
for _, cfg := range configs {
|
||||
ws := cfg.Status.(*kstatus.WrappedStatus)
|
||||
if ws.Dirty {
|
||||
res := status.ResourceFromModelConfig(cfg)
|
||||
c.statusController.EnqueueStatusUpdateResource(ws.Unwrap(), res)
|
||||
}
|
||||
}
|
||||
// Reconcile is called each time the `gatewayContext` may change. We use this to mark it as updated.
|
||||
func (c *Controller) Reconcile(ps *model.PushContext) {
|
||||
ctx := NewGatewayContext(ps, c.cluster, c.client, c.domainSuffix)
|
||||
c.gatewayContext.Modify(func(i **atomic.Pointer[GatewayContext]) {
|
||||
(*i).Store(&ctx)
|
||||
})
|
||||
c.gatewayContext.MarkSynced()
|
||||
}
|
||||
|
||||
func (c *Controller) Create(config config.Config) (revision string, err error) {
|
||||
@@ -283,123 +545,84 @@ func (c *Controller) Delete(typ config.GroupVersionKind, name, namespace string,
|
||||
}
|
||||
|
||||
func (c *Controller) RegisterEventHandler(typ config.GroupVersionKind, handler model.EventHandler) {
|
||||
switch typ {
|
||||
case gvk.Namespace:
|
||||
c.namespaceHandler = handler
|
||||
case gvk.Secret:
|
||||
c.secretHandler = handler
|
||||
}
|
||||
// For all other types, do nothing as c.cache has been registered
|
||||
// We do not do event handler registration this way, and instead directly call the XDS Updated.
|
||||
}
|
||||
|
||||
func (c *Controller) Run(stop <-chan struct{}) {
|
||||
if features.EnableGatewayAPIGatewayClassController {
|
||||
go func() {
|
||||
if c.waitForCRD(gvr.GatewayClass, stop) {
|
||||
gcc := NewClassController(c.client)
|
||||
c.client.RunAndWait(stop)
|
||||
gcc.Run(stop)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
tw := c.tagWatcher.AccessUnprotected()
|
||||
go tw.Run(stop)
|
||||
go c.shadowServiceReconciler.Run(stop)
|
||||
go func() {
|
||||
if c.waitForCRD(gvr.GatewayClass, stop) {
|
||||
gcc := NewClassController(c.client)
|
||||
c.client.RunAndWait(stop)
|
||||
gcc.Run(stop)
|
||||
}
|
||||
kube.WaitForCacheSync("gateway tag watcher", stop, tw.HasSynced)
|
||||
c.tagWatcher.MarkSynced()
|
||||
}()
|
||||
|
||||
<-stop
|
||||
close(c.stop)
|
||||
}
|
||||
|
||||
func (c *Controller) HasSynced() bool {
|
||||
return c.cache.HasSynced() && c.namespaces.HasSynced()
|
||||
}
|
||||
|
||||
func (c *Controller) SecretAllowed(resourceName string, namespace string) bool {
|
||||
c.stateMu.RLock()
|
||||
defer c.stateMu.RUnlock()
|
||||
return c.state.AllowedReferences.SecretAllowed(resourceName, namespace)
|
||||
}
|
||||
|
||||
// namespaceEvent handles a namespace add/update. Gateway's can select routes by label, so we need to handle
|
||||
// when the labels change.
|
||||
// Note: we don't handle delete as a delete would also clean up any relevant gateway-api types which will
|
||||
// trigger its own event.
|
||||
func (c *Controller) namespaceEvent(oldNs, newNs *corev1.Namespace) {
|
||||
// First, find all the label keys on the old/new namespace. We include NamespaceNameLabel
|
||||
// since we have special logic to always allow this on namespace.
|
||||
touchedNamespaceLabels := sets.New(NamespaceNameLabel)
|
||||
touchedNamespaceLabels.InsertAll(getLabelKeys(oldNs)...)
|
||||
touchedNamespaceLabels.InsertAll(getLabelKeys(newNs)...)
|
||||
|
||||
// Next, we find all keys our Gateways actually reference.
|
||||
c.stateMu.RLock()
|
||||
intersection := touchedNamespaceLabels.Intersection(c.state.ReferencedNamespaceKeys)
|
||||
c.stateMu.RUnlock()
|
||||
|
||||
// If there was any overlap, then a relevant namespace label may have changed, and we trigger a
|
||||
// push. A more exact check could actually determine if the label selection result actually changed.
|
||||
// However, this is a much simpler approach that is likely to scale well enough for now.
|
||||
if !intersection.IsEmpty() && c.namespaceHandler != nil {
|
||||
log.Debugf("namespace labels changed, triggering namespace handler: %v", intersection.UnsortedList())
|
||||
c.namespaceHandler(config.Config{}, config.Config{}, model.EventUpdate)
|
||||
if !(c.outputs.VirtualServices.HasSynced() &&
|
||||
c.outputs.DestinationRules.HasSynced() &&
|
||||
c.outputs.Gateways.HasSynced() &&
|
||||
c.outputs.ReferenceGrants.collection.HasSynced()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// getLabelKeys extracts all label keys from a namespace object.
|
||||
func getLabelKeys(ns *corev1.Namespace) []string {
|
||||
if ns == nil {
|
||||
return nil
|
||||
for _, h := range c.handlers {
|
||||
if !h.HasSynced() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return maps.Keys(ns.Labels)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Controller) secretEvent(name, namespace string) {
|
||||
var impactedConfigs []model.ConfigKey
|
||||
c.stateMu.RLock()
|
||||
impactedConfigs = c.state.ResourceReferences[model.ConfigKey{
|
||||
Kind: kind.Secret,
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}]
|
||||
c.stateMu.RUnlock()
|
||||
if len(impactedConfigs) > 0 {
|
||||
log.Debugf("secret %s/%s changed, triggering secret handler", namespace, name)
|
||||
for _, cfg := range impactedConfigs {
|
||||
gw := config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.KubernetesGateway,
|
||||
Namespace: cfg.Namespace,
|
||||
Name: cfg.Name,
|
||||
},
|
||||
func (c *Controller) SecretAllowed(ourKind config.GroupVersionKind, resourceName string, namespace string) bool {
|
||||
return c.outputs.ReferenceGrants.SecretAllowed(nil, ourKind, resourceName, namespace)
|
||||
}
|
||||
|
||||
func pushXds[T any](xds model.XDSUpdater, f func(T) model.ConfigKey) func(events []krt.Event[T]) {
|
||||
return func(events []krt.Event[T]) {
|
||||
if xds == nil {
|
||||
return
|
||||
}
|
||||
cu := sets.New[model.ConfigKey]()
|
||||
for _, e := range events {
|
||||
for _, i := range e.Items() {
|
||||
c := f(i)
|
||||
if c != (model.ConfigKey{}) {
|
||||
cu.Insert(c)
|
||||
}
|
||||
}
|
||||
c.secretHandler(gw, gw, model.EventUpdate)
|
||||
}
|
||||
if len(cu) == 0 {
|
||||
return
|
||||
}
|
||||
xds.ConfigUpdate(&model.PushRequest{
|
||||
Full: true,
|
||||
ConfigsUpdated: cu,
|
||||
Reason: model.NewReasonStats(model.ConfigUpdate),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// deepCopyStatus creates a copy of all configs, with a copy of the status field that we can mutate.
|
||||
// This allows our functions to call Status.Mutate, and then we can later persist all changes into the
|
||||
// API server.
|
||||
func deepCopyStatus(configs []config.Config) []config.Config {
|
||||
return slices.Map(configs, func(c config.Config) config.Config {
|
||||
return config.Config{
|
||||
Meta: c.Meta,
|
||||
Spec: c.Spec,
|
||||
Status: kstatus.Wrap(c.Status),
|
||||
}
|
||||
})
|
||||
func (c *Controller) HasInferencePool(gw types.NamespacedName) bool {
|
||||
return len(c.outputs.InferencePoolsByGateway.Lookup(gw)) > 0
|
||||
}
|
||||
|
||||
// filterNamespace allows filtering out configs to only a specific namespace. This allows implementing the
|
||||
// List call which can specify a specific namespace.
|
||||
func filterNamespace(cfgs []config.Config, namespace string) []config.Config {
|
||||
if namespace == metav1.NamespaceAll {
|
||||
return cfgs
|
||||
func (c *Controller) inRevision(obj any) bool {
|
||||
object := controllers.ExtractObject(obj)
|
||||
if object == nil {
|
||||
return false
|
||||
}
|
||||
return slices.Filter(cfgs, func(c config.Config) bool {
|
||||
return c.Namespace == namespace
|
||||
})
|
||||
}
|
||||
|
||||
// hasResources determines if there are any gateway-api resources created at all.
|
||||
// If not, we can short circuit all processing to avoid excessive work.
|
||||
func (kr GatewayResources) hasResources() bool {
|
||||
return len(kr.GatewayClass) > 0 ||
|
||||
len(kr.Gateway) > 0 ||
|
||||
len(kr.HTTPRoute) > 0 ||
|
||||
len(kr.TCPRoute) > 0 ||
|
||||
len(kr.TLSRoute) > 0 ||
|
||||
len(kr.ReferenceGrant) > 0
|
||||
return config.LabelsInRevision(object.GetLabels(), c.revision)
|
||||
}
|
||||
|
||||
@@ -12,50 +12,42 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/config/memory"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pilot/pkg/networking/core/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/util/xdsfake"
|
||||
"istio.io/istio/pkg/config"
|
||||
istioconst "istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/collections"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/kclient/clienttest"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1"
|
||||
k8sbeta "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
higressconstant "github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/networking/core"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/test/util/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
gatewayClassSpec = &k8s.GatewayClassSpec{
|
||||
ControllerName: constants.ManagedGatewayController,
|
||||
ControllerName: higressconstant.ManagedGatewayController,
|
||||
}
|
||||
gatewaySpec = &k8s.GatewaySpec{
|
||||
GatewayClassName: "gwclass",
|
||||
GatewayClassName: "higress",
|
||||
Listeners: []k8s.Listener{
|
||||
{
|
||||
Name: "default",
|
||||
Port: 9009,
|
||||
Protocol: "HTTP",
|
||||
AllowedRoutes: &k8s.AllowedRoutes{Namespaces: &k8s.RouteNamespaces{From: func() *k8s.FromNamespaces { x := k8sbeta.NamespacesFromAll; return &x }()}},
|
||||
AllowedRoutes: &k8s.AllowedRoutes{Namespaces: &k8s.RouteNamespaces{From: func() *k8s.FromNamespaces { x := k8s.NamespacesFromAll; return &x }()}},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -84,122 +76,62 @@ var AlwaysReady = func(class schema.GroupVersionResource, stop <-chan struct{})
|
||||
return true
|
||||
}
|
||||
|
||||
func setupController(t *testing.T, objs ...runtime.Object) *Controller {
|
||||
kc := kube.NewFakeClient(objs...)
|
||||
setupClientCRDs(t, kc)
|
||||
stop := test.NewStop(t)
|
||||
controller := NewController(
|
||||
kc,
|
||||
AlwaysReady,
|
||||
controller.Options{KrtDebugger: krt.GlobalDebugHandler},
|
||||
nil)
|
||||
kc.RunAndWait(stop)
|
||||
go controller.Run(stop)
|
||||
cg := core.NewConfigGenTest(t, core.TestOptions{})
|
||||
controller.Reconcile(cg.PushContext())
|
||||
kube.WaitForCacheSync("test", stop, controller.HasSynced)
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
func TestListInvalidGroupVersionKind(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
clientSet := kube.NewFakeClient()
|
||||
store := memory.NewController(memory.Make(collections.All))
|
||||
controller := NewController(clientSet, store, AlwaysReady, nil, controller.Options{})
|
||||
controller := setupController(t)
|
||||
|
||||
typ := config.GroupVersionKind{Kind: "wrong-kind"}
|
||||
c := controller.List(typ, "ns1")
|
||||
g.Expect(c).To(HaveLen(0))
|
||||
assert.Equal(t, len(c), 0)
|
||||
}
|
||||
|
||||
func TestListGatewayResourceType(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
clientSet := kube.NewFakeClient()
|
||||
store := memory.NewController(memory.Make(collections.All))
|
||||
controller := NewController(clientSet, store, AlwaysReady, nil, controller.Options{})
|
||||
|
||||
store.Create(config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.GatewayClass,
|
||||
Name: "gwclass",
|
||||
Namespace: "ns1",
|
||||
controller := setupController(t,
|
||||
&k8sbeta.GatewayClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "higress",
|
||||
},
|
||||
Spec: *gatewayClassSpec,
|
||||
},
|
||||
Spec: gatewayClassSpec,
|
||||
})
|
||||
if _, err := store.Create(config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.KubernetesGateway,
|
||||
Name: "gwspec",
|
||||
Namespace: "ns1",
|
||||
&k8sbeta.Gateway{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "gwspec",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: *gatewaySpec,
|
||||
},
|
||||
Spec: gatewaySpec,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
store.Create(config.Config{
|
||||
Meta: config.Meta{
|
||||
GroupVersionKind: gvk.HTTPRoute,
|
||||
Name: "http-route",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: httpRouteSpec,
|
||||
})
|
||||
|
||||
cg := v1alpha3.NewConfigGenTest(t, v1alpha3.TestOptions{})
|
||||
g.Expect(controller.Reconcile(cg.PushContext())).ToNot(HaveOccurred())
|
||||
cfg := controller.List(gvk.Gateway, "ns1")
|
||||
g.Expect(cfg).To(HaveLen(1))
|
||||
for _, c := range cfg {
|
||||
g.Expect(c.GroupVersionKind).To(Equal(gvk.Gateway))
|
||||
g.Expect(c.Name).To(Equal("gwspec" + "-" + istioconst.KubernetesGatewayName + "-default"))
|
||||
g.Expect(c.Namespace).To(Equal("ns1"))
|
||||
g.Expect(c.Spec).To(Equal(expectedgw))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamespaceEvent(t *testing.T) {
|
||||
clientSet := kube.NewFakeClient()
|
||||
store := memory.NewController(memory.Make(collections.All))
|
||||
c := NewController(clientSet, store, AlwaysReady, nil, controller.Options{})
|
||||
s := xdsfake.NewFakeXDS()
|
||||
|
||||
c.RegisterEventHandler(gvk.Namespace, func(_, cfg config.Config, _ model.Event) {
|
||||
s.ConfigUpdate(&model.PushRequest{
|
||||
Full: true,
|
||||
Reason: model.NewReasonStats(model.NamespaceUpdate),
|
||||
&k8sbeta.HTTPRoute{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "http-route",
|
||||
Namespace: "ns1",
|
||||
},
|
||||
Spec: *httpRouteSpec,
|
||||
})
|
||||
})
|
||||
|
||||
stop := test.NewStop(t)
|
||||
c.Run(stop)
|
||||
kube.WaitForCacheSync("test", stop, c.HasSynced)
|
||||
c.state.ReferencedNamespaceKeys = sets.String{"allowed": struct{}{}}
|
||||
|
||||
ns1 := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns1",
|
||||
Labels: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
}}
|
||||
ns2 := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ns2",
|
||||
Labels: map[string]string{
|
||||
"allowed": "true",
|
||||
},
|
||||
}}
|
||||
ns := clienttest.Wrap(t, c.namespaces)
|
||||
|
||||
ns.Create(ns1)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns.Create(ns2)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns1.Annotations = map[string]string{"foo": "bar"}
|
||||
ns.Update(ns1)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns2.Annotations = map[string]string{"foo": "bar"}
|
||||
ns.Update(ns2)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns1.Labels["bar"] = "foo"
|
||||
ns.Update(ns1)
|
||||
s.AssertEmpty(t, time.Millisecond*10)
|
||||
|
||||
ns2.Labels["foo"] = "bar"
|
||||
ns.Update(ns2)
|
||||
s.WaitOrFail(t, "xds full")
|
||||
|
||||
ns1.Labels["allowed"] = "true"
|
||||
ns.Update(ns1)
|
||||
s.WaitOrFail(t, "xds full")
|
||||
|
||||
ns2.Labels["allowed"] = "false"
|
||||
ns.Update(ns2)
|
||||
s.WaitOrFail(t, "xds full")
|
||||
dumpOnFailure(t, krt.GlobalDebugHandler)
|
||||
cfg := controller.List(gvk.Gateway, "ns1")
|
||||
assert.Equal(t, len(cfg), 1)
|
||||
for _, c := range cfg {
|
||||
assert.Equal(t, c.GroupVersionKind, gvk.Gateway)
|
||||
assert.Equal(t, c.Name, "gwspec"+"-"+constants.KubernetesGatewayName+"-default")
|
||||
assert.Equal(t, c.Namespace, "ns1")
|
||||
assert.Equal(t, c.Spec, any(expectedgw))
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,21 +12,21 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
higressconstants "github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
)
|
||||
|
||||
// classInfo holds information about a gateway class
|
||||
type classInfo struct {
|
||||
// controller name for this class
|
||||
controller string
|
||||
// controller label for this class
|
||||
controllerLabel string
|
||||
// description for this class
|
||||
description string
|
||||
// The key in the templates to use for this class
|
||||
@@ -37,6 +37,15 @@ type classInfo struct {
|
||||
|
||||
// disableRouteGeneration, if set, will make it so the controller ignores this class.
|
||||
disableRouteGeneration bool
|
||||
|
||||
// supportsListenerSet declares whether a given class supports ListenerSet
|
||||
supportsListenerSet bool
|
||||
|
||||
// disableNameSuffix, if set, will avoid appending -<class> to names
|
||||
disableNameSuffix bool
|
||||
|
||||
// addressType is the default address type to report
|
||||
addressType gateway.AddressType
|
||||
}
|
||||
|
||||
var classInfos = getClassInfos()
|
||||
@@ -45,15 +54,25 @@ var builtinClasses = getBuiltinClasses()
|
||||
|
||||
func getBuiltinClasses() map[gateway.ObjectName]gateway.GatewayController {
|
||||
res := map[gateway.ObjectName]gateway.GatewayController{
|
||||
defaultClassName: constants.ManagedGatewayController,
|
||||
// Start - Commented by Higress
|
||||
// constants.RemoteGatewayClassName: constants.UnmanagedGatewayController,
|
||||
// End - Commented by Higress
|
||||
// Start - Updated by Higress
|
||||
//gateway.ObjectName(features.GatewayAPIDefaultGatewayClass): gateway.GatewayController(features.ManagedGatewayController),
|
||||
higressconstants.DefaultGatewayClass: higressconstants.ManagedGatewayController,
|
||||
// End - Updated by Higress
|
||||
}
|
||||
// Start - Commented by Higress
|
||||
//if features.EnableAmbientControllers {
|
||||
//if features.MultiNetworkGatewayAPI {
|
||||
// res[constants.RemoteGatewayClassName] = constants.UnmanagedGatewayController
|
||||
//}
|
||||
//
|
||||
//if features.EnableAmbientWaypoints {
|
||||
// res[constants.WaypointGatewayClassName] = constants.ManagedGatewayMeshController
|
||||
//}
|
||||
//
|
||||
//// N.B Ambient e/w gateways are just fancy waypoints, but we want a different
|
||||
//// GatewayClass for better UX
|
||||
//if features.EnableAmbientMultiNetwork {
|
||||
// res[constants.EastWestGatewayClassName] = constants.ManagedGatewayEastWestController
|
||||
//}
|
||||
// End - Commented by Higress
|
||||
return res
|
||||
}
|
||||
@@ -61,28 +80,55 @@ func getBuiltinClasses() map[gateway.ObjectName]gateway.GatewayController {
|
||||
func getClassInfos() map[gateway.GatewayController]classInfo {
|
||||
// Start - Updated by Higress
|
||||
m := map[gateway.GatewayController]classInfo{
|
||||
constants.ManagedGatewayController: {
|
||||
controller: constants.ManagedGatewayController,
|
||||
gateway.GatewayController(higressconstants.ManagedGatewayController): {
|
||||
controller: higressconstants.ManagedGatewayController,
|
||||
description: "The default Higress GatewayClass",
|
||||
templates: "kube-gateway",
|
||||
defaultServiceType: corev1.ServiceTypeLoadBalancer,
|
||||
//addressType: gateway.HostnameAddressType,
|
||||
//controllerLabel: constants.ManagedGatewayControllerLabel,
|
||||
//supportsListenerSet: true,
|
||||
},
|
||||
//UnmanagedGatewayController: {
|
||||
// // This represents a gateway that our control plane cannot discover directly via the API server.
|
||||
// // We shouldn't generate Istio resources for it. We aren't programming this gateway.
|
||||
// controller: UnmanagedGatewayController,
|
||||
// description: "Remote to this cluster. Does not deploy or affect configuration.",
|
||||
// disableRouteGeneration: true,
|
||||
//},
|
||||
}
|
||||
//if features.EnableAmbientControllers {
|
||||
// m[constants.ManagedGatewayMeshController] = classInfo{
|
||||
// controller: constants.ManagedGatewayMeshController,
|
||||
// description: "The default Istio waypoint GatewayClass",
|
||||
// templates: "waypoint",
|
||||
// defaultServiceType: corev1.ServiceTypeClusterIP,
|
||||
|
||||
//if features.MultiNetworkGatewayAPI {
|
||||
// m[constants.UnmanagedGatewayController] = classInfo{
|
||||
// // This represents a gateway that our control plane cannot discover directly via the API server.
|
||||
// // We shouldn't generate Istio resources for it. We aren't programming this gateway.
|
||||
// controller: constants.UnmanagedGatewayController,
|
||||
// description: "Remote to this cluster. Does not deploy or affect configuration.",
|
||||
// disableRouteGeneration: true,
|
||||
// addressType: gateway.HostnameAddressType,
|
||||
// supportsListenerSet: false,
|
||||
// }
|
||||
//}
|
||||
//if features.EnableAmbientWaypoints {
|
||||
// m[constants.ManagedGatewayMeshController] = classInfo{
|
||||
// controller: constants.ManagedGatewayMeshController,
|
||||
// description: "The default Istio waypoint GatewayClass",
|
||||
// templates: "waypoint",
|
||||
// disableNameSuffix: true,
|
||||
// defaultServiceType: corev1.ServiceTypeClusterIP,
|
||||
// supportsListenerSet: false,
|
||||
// // Report both. Consumers of the gateways can choose which they want.
|
||||
// // In particular, Istio across different versions consumes different address types, so this retains compat
|
||||
// addressType: "",
|
||||
// controllerLabel: constants.ManagedGatewayMeshControllerLabel,
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//if features.EnableAmbientMultiNetwork {
|
||||
// m[constants.ManagedGatewayEastWestController] = classInfo{
|
||||
// controller: constants.ManagedGatewayEastWestController,
|
||||
// description: "The default GatewayClass for Istio East West Gateways",
|
||||
// templates: "waypoint",
|
||||
// disableNameSuffix: true,
|
||||
// defaultServiceType: corev1.ServiceTypeLoadBalancer,
|
||||
// addressType: "",
|
||||
// controllerLabel: constants.ManagedGatewayEastWestControllerLabel,
|
||||
// }
|
||||
//}
|
||||
|
||||
// End - Updated by Higress
|
||||
return m
|
||||
}
|
||||
|
||||
476
pkg/ingress/kube/gateway/istio/gateway_collection.go
Normal file
476
pkg/ingress/kube/gateway/istio/gateway_collection.go
Normal file
@@ -0,0 +1,476 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
gatewayx "sigs.k8s.io/gateway-api/apisx/v1alpha1"
|
||||
|
||||
istio "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
kubeconfig "istio.io/istio/pkg/config/gateway/kube"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/revisions"
|
||||
"istio.io/istio/pkg/slices"
|
||||
)
|
||||
|
||||
type Gateway struct {
|
||||
*config.Config `json:"config"`
|
||||
Parent parentKey `json:"parent"`
|
||||
ParentInfo parentInfo `json:"parentInfo"`
|
||||
Valid bool `json:"valid"`
|
||||
}
|
||||
|
||||
func (g Gateway) ResourceName() string {
|
||||
return config.NamespacedName(g.Config).String()
|
||||
}
|
||||
|
||||
func (g Gateway) Equals(other Gateway) bool {
|
||||
return g.Config.Equals(other.Config) &&
|
||||
g.Valid == other.Valid // TODO: ok to ignore parent/parentInfo?
|
||||
}
|
||||
|
||||
type ListenerSet struct {
|
||||
*config.Config `json:"config"`
|
||||
Parent parentKey `json:"parent"`
|
||||
ParentInfo parentInfo `json:"parentInfo"`
|
||||
GatewayParent types.NamespacedName `json:"gatewayParent"`
|
||||
Valid bool `json:"valid"`
|
||||
}
|
||||
|
||||
func (g ListenerSet) ResourceName() string {
|
||||
return config.NamespacedName(g.Config).Name
|
||||
}
|
||||
|
||||
func (g ListenerSet) Equals(other ListenerSet) bool {
|
||||
return g.Config.Equals(other.Config) &&
|
||||
g.GatewayParent == other.GatewayParent &&
|
||||
g.Valid == other.Valid // TODO: ok to ignore parent/parentInfo?
|
||||
}
|
||||
|
||||
func ListenerSetCollection(
|
||||
listenerSets krt.Collection[*gatewayx.XListenerSet],
|
||||
gateways krt.Collection[*gateway.Gateway],
|
||||
gatewayClasses krt.Collection[GatewayClass],
|
||||
namespaces krt.Collection[*corev1.Namespace],
|
||||
grants ReferenceGrants,
|
||||
secrets krt.Collection[*corev1.Secret],
|
||||
domainSuffix string,
|
||||
gatewayContext krt.RecomputeProtected[*atomic.Pointer[GatewayContext]],
|
||||
tagWatcher krt.RecomputeProtected[revisions.TagWatcher],
|
||||
opts krt.OptionsBuilder,
|
||||
defaultGatewaySelector map[string]string,
|
||||
) (
|
||||
krt.StatusCollection[*gatewayx.XListenerSet, gatewayx.ListenerSetStatus],
|
||||
krt.Collection[ListenerSet],
|
||||
) {
|
||||
statusCol, gw := krt.NewStatusManyCollection(listenerSets,
|
||||
func(ctx krt.HandlerContext, obj *gatewayx.XListenerSet) (*gatewayx.ListenerSetStatus, []ListenerSet) {
|
||||
// We currently depend on service discovery information not know to krt; mark we depend on it.
|
||||
context := gatewayContext.Get(ctx).Load()
|
||||
if context == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if !tagWatcher.Get(ctx).IsMine(obj.ObjectMeta) {
|
||||
return nil, nil
|
||||
}
|
||||
result := []ListenerSet{}
|
||||
ls := obj.Spec
|
||||
status := obj.Status.DeepCopy()
|
||||
|
||||
p := ls.ParentRef
|
||||
if normalizeReference(p.Group, p.Kind, gvk.KubernetesGateway) != gvk.KubernetesGateway {
|
||||
// Cannot report status since we don't know if it is for us
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
pns := ptr.OrDefault(p.Namespace, gatewayx.Namespace(obj.Namespace))
|
||||
parentGwObj := ptr.Flatten(krt.FetchOne(ctx, gateways, krt.FilterKey(string(pns)+"/"+string(p.Name))))
|
||||
if parentGwObj == nil {
|
||||
// Cannot report status since we don't know if it is for us
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
class := fetchClass(ctx, gatewayClasses, parentGwObj.Spec.GatewayClassName)
|
||||
if class == nil {
|
||||
// Cannot report status since we don't know if it is for us
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
controllerName := class.Controller
|
||||
classInfo, f := classInfos[controllerName]
|
||||
if !f {
|
||||
// Cannot report status since we don't know if it is for us
|
||||
return nil, nil
|
||||
}
|
||||
if !classInfo.supportsListenerSet {
|
||||
reportUnsupportedListenerSet(class.Name, status, obj)
|
||||
return status, nil
|
||||
}
|
||||
|
||||
if !namespaceAcceptedByAllowListeners(obj.Namespace, parentGwObj, func(s string) *corev1.Namespace {
|
||||
return ptr.Flatten(krt.FetchOne(ctx, namespaces, krt.FilterKey(s)))
|
||||
}) {
|
||||
reportNotAllowedListenerSet(status, obj)
|
||||
return status, nil
|
||||
}
|
||||
|
||||
gatewayServices, useDefaultService, err := extractGatewayServices(domainSuffix, parentGwObj, classInfo)
|
||||
if len(gatewayServices) == 0 && !useDefaultService && err != nil {
|
||||
// Short circuit if it's a hard failure
|
||||
reportListenerSetStatus(context, parentGwObj, obj, status, gatewayServices, nil, err)
|
||||
return status, nil
|
||||
}
|
||||
|
||||
servers := []*istio.Server{}
|
||||
for i, l := range ls.Listeners {
|
||||
port, portErr := detectListenerPortNumber(l)
|
||||
l.Port = port
|
||||
standardListener := convertListenerSetToListener(l)
|
||||
originalStatus := slices.Map(status.Listeners, convertListenerSetStatusToStandardStatus)
|
||||
server, updatedStatus, programmed := buildListener(ctx, secrets, grants, namespaces, obj, originalStatus, standardListener, i, controllerName, portErr)
|
||||
status.Listeners = slices.Map(updatedStatus, convertStandardStatusToListenerSetStatus(l))
|
||||
|
||||
servers = append(servers, server)
|
||||
if controllerName == constants.ManagedGatewayMeshController || controllerName == constants.ManagedGatewayEastWestController {
|
||||
// Waypoint doesn't actually convert the routes to VirtualServices
|
||||
continue
|
||||
}
|
||||
meta := parentMeta(obj, &l.Name)
|
||||
meta[constants.InternalGatewaySemantics] = constants.GatewaySemanticsGateway
|
||||
//meta[model.InternalGatewayServiceAnnotation] = strings.Join(gatewayServices, ",")
|
||||
meta[constants.InternalParentNamespace] = parentGwObj.Namespace
|
||||
|
||||
// Start - Updated by Higress
|
||||
var selector map[string]string
|
||||
if len(gatewayServices) != 0 {
|
||||
meta[model.InternalGatewayServiceAnnotation] = strings.Join(gatewayServices, ",")
|
||||
} else if useDefaultService {
|
||||
selector = defaultGatewaySelector
|
||||
} else {
|
||||
// Protective programming. This shouldn't happen.
|
||||
continue
|
||||
}
|
||||
// End - Updated by Higress
|
||||
|
||||
// Each listener generates an Istio Gateway with a single Server. This allows binding to a specific listener.
|
||||
gatewayConfig := config.Config{
|
||||
Meta: config.Meta{
|
||||
CreationTimestamp: obj.CreationTimestamp.Time,
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
Name: kubeconfig.InternalGatewayName(obj.Name, string(l.Name)),
|
||||
Annotations: meta,
|
||||
Namespace: obj.Namespace,
|
||||
Domain: domainSuffix,
|
||||
},
|
||||
Spec: &istio.Gateway{
|
||||
Servers: []*istio.Server{server},
|
||||
// Start - Added by Higress
|
||||
Selector: selector,
|
||||
// End - Added by Higress
|
||||
},
|
||||
}
|
||||
|
||||
allowed, _ := generateSupportedKinds(standardListener)
|
||||
ref := parentKey{
|
||||
Kind: gvk.XListenerSet,
|
||||
Name: obj.Name,
|
||||
Namespace: obj.Namespace,
|
||||
}
|
||||
pri := parentInfo{
|
||||
InternalName: obj.Namespace + "/" + gatewayConfig.Name,
|
||||
AllowedKinds: allowed,
|
||||
Hostnames: server.Hosts,
|
||||
OriginalHostname: string(ptr.OrEmpty(l.Hostname)),
|
||||
SectionName: l.Name,
|
||||
Port: l.Port,
|
||||
Protocol: l.Protocol,
|
||||
}
|
||||
|
||||
res := ListenerSet{
|
||||
Config: &gatewayConfig,
|
||||
Valid: programmed,
|
||||
Parent: ref,
|
||||
GatewayParent: config.NamespacedName(parentGwObj),
|
||||
ParentInfo: pri,
|
||||
}
|
||||
result = append(result, res)
|
||||
}
|
||||
|
||||
reportListenerSetStatus(context, parentGwObj, obj, status, gatewayServices, servers, err)
|
||||
return status, result
|
||||
}, opts.WithName("ListenerSets")...)
|
||||
|
||||
return statusCol, gw
|
||||
}
|
||||
|
||||
func GatewayCollection(
|
||||
gateways krt.Collection[*gateway.Gateway],
|
||||
listenerSets krt.Collection[ListenerSet],
|
||||
gatewayClasses krt.Collection[GatewayClass],
|
||||
namespaces krt.Collection[*corev1.Namespace],
|
||||
grants ReferenceGrants,
|
||||
secrets krt.Collection[*corev1.Secret],
|
||||
domainSuffix string,
|
||||
gatewayContext krt.RecomputeProtected[*atomic.Pointer[GatewayContext]],
|
||||
tagWatcher krt.RecomputeProtected[revisions.TagWatcher],
|
||||
opts krt.OptionsBuilder,
|
||||
defaultGatewaySelector map[string]string,
|
||||
) (
|
||||
krt.StatusCollection[*gateway.Gateway, gateway.GatewayStatus],
|
||||
krt.Collection[Gateway],
|
||||
) {
|
||||
listenerIndex := krt.NewIndex(listenerSets, "gatewayParent", func(o ListenerSet) []types.NamespacedName {
|
||||
return []types.NamespacedName{o.GatewayParent}
|
||||
})
|
||||
statusCol, gw := krt.NewStatusManyCollection(gateways, func(ctx krt.HandlerContext, obj *gateway.Gateway) (*gateway.GatewayStatus, []Gateway) {
|
||||
// We currently depend on service discovery information not known to krt; mark we depend on it.
|
||||
context := gatewayContext.Get(ctx).Load()
|
||||
if context == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if !tagWatcher.Get(ctx).IsMine(obj.ObjectMeta) {
|
||||
return nil, nil
|
||||
}
|
||||
result := []Gateway{}
|
||||
kgw := obj.Spec
|
||||
status := obj.Status.DeepCopy()
|
||||
class := fetchClass(ctx, gatewayClasses, kgw.GatewayClassName)
|
||||
if class == nil {
|
||||
return nil, nil
|
||||
}
|
||||
controllerName := class.Controller
|
||||
classInfo, f := classInfos[controllerName]
|
||||
if !f {
|
||||
return nil, nil
|
||||
}
|
||||
if classInfo.disableRouteGeneration {
|
||||
reportUnmanagedGatewayStatus(status, obj)
|
||||
// We found it, but don't want to handle this class
|
||||
return status, nil
|
||||
}
|
||||
servers := []*istio.Server{}
|
||||
|
||||
// Start - Updated by Higress
|
||||
// Extract the addresses. A gateway will bind to a specific Service
|
||||
gatewayServices, useDefaultService, err := extractGatewayServices(domainSuffix, obj, classInfo)
|
||||
if len(gatewayServices) == 0 && !useDefaultService && err != nil {
|
||||
// Short circuit if its a hard failure
|
||||
reportGatewayStatus(context, obj, status, gatewayServices, servers, 0, err)
|
||||
return status, nil
|
||||
}
|
||||
// End - Updated by Higress
|
||||
|
||||
for i, l := range kgw.Listeners {
|
||||
server, updatedStatus, programmed := buildListener(ctx, secrets, grants, namespaces, obj, status.Listeners, l, i, controllerName, nil)
|
||||
status.Listeners = updatedStatus
|
||||
|
||||
servers = append(servers, server)
|
||||
if controllerName == constants.ManagedGatewayMeshController || controllerName == constants.ManagedGatewayEastWestController {
|
||||
// Waypoint and ambient e/w don't actually convert the routes to VirtualServices
|
||||
// TODO: Maybe E/W gateway should for non 15008 ports for backwards compat?
|
||||
continue
|
||||
}
|
||||
meta := parentMeta(obj, &l.Name)
|
||||
meta[constants.InternalGatewaySemantics] = constants.GatewaySemanticsGateway
|
||||
// Start - Updated by Higress
|
||||
var selector map[string]string
|
||||
if len(gatewayServices) != 0 {
|
||||
meta[model.InternalGatewayServiceAnnotation] = strings.Join(gatewayServices, ",")
|
||||
} else if useDefaultService {
|
||||
selector = defaultGatewaySelector
|
||||
} else {
|
||||
// Protective programming. This shouldn't happen.
|
||||
continue
|
||||
}
|
||||
// End - Updated by Higress
|
||||
|
||||
// Each listener generates an Istio Gateway with a single Server. This allows binding to a specific listener.
|
||||
gatewayConfig := config.Config{
|
||||
Meta: config.Meta{
|
||||
CreationTimestamp: obj.CreationTimestamp.Time,
|
||||
GroupVersionKind: gvk.Gateway,
|
||||
Name: kubeconfig.InternalGatewayName(obj.Name, string(l.Name)),
|
||||
Annotations: meta,
|
||||
Namespace: obj.Namespace,
|
||||
Domain: domainSuffix,
|
||||
},
|
||||
Spec: &istio.Gateway{
|
||||
Servers: []*istio.Server{server},
|
||||
// Start - Added by Higress
|
||||
Selector: selector,
|
||||
// End - Added by Higress
|
||||
},
|
||||
}
|
||||
|
||||
allowed, _ := generateSupportedKinds(l)
|
||||
ref := parentKey{
|
||||
Kind: gvk.KubernetesGateway,
|
||||
Name: obj.Name,
|
||||
Namespace: obj.Namespace,
|
||||
}
|
||||
pri := parentInfo{
|
||||
InternalName: obj.Namespace + "/" + gatewayConfig.Name,
|
||||
AllowedKinds: allowed,
|
||||
Hostnames: server.Hosts,
|
||||
OriginalHostname: string(ptr.OrEmpty(l.Hostname)),
|
||||
SectionName: l.Name,
|
||||
Port: l.Port,
|
||||
Protocol: l.Protocol,
|
||||
}
|
||||
|
||||
res := Gateway{
|
||||
Config: &gatewayConfig,
|
||||
Valid: programmed,
|
||||
Parent: ref,
|
||||
ParentInfo: pri,
|
||||
}
|
||||
result = append(result, res)
|
||||
}
|
||||
listenersFromSets := krt.Fetch(ctx, listenerSets, krt.FilterIndex(listenerIndex, config.NamespacedName(obj)))
|
||||
for _, ls := range listenersFromSets {
|
||||
servers = append(servers, ls.Config.Spec.(*istio.Gateway).Servers...)
|
||||
result = append(result, Gateway{
|
||||
Config: ls.Config,
|
||||
Parent: ls.Parent,
|
||||
ParentInfo: ls.ParentInfo,
|
||||
Valid: ls.Valid,
|
||||
})
|
||||
}
|
||||
|
||||
reportGatewayStatus(context, obj, status, gatewayServices, servers, len(listenersFromSets), err)
|
||||
return status, result
|
||||
}, opts.WithName("KubernetesGateway")...)
|
||||
|
||||
return statusCol, gw
|
||||
}
|
||||
|
||||
// FinalGatewayStatusCollection finalizes a Gateway status. There is a circular logic between Gateways and Routes to determine
|
||||
// the attachedRoute count, so we first build a partial Gateway status, then once routes are computed we finalize it with
|
||||
// the attachedRoute count.
|
||||
func FinalGatewayStatusCollection(
|
||||
gatewayStatuses krt.StatusCollection[*gateway.Gateway, gateway.GatewayStatus],
|
||||
routeAttachments krt.Collection[RouteAttachment],
|
||||
routeAttachmentsIndex krt.Index[types.NamespacedName, RouteAttachment],
|
||||
opts krt.OptionsBuilder,
|
||||
) krt.StatusCollection[*gateway.Gateway, gateway.GatewayStatus] {
|
||||
return krt.NewCollection(
|
||||
gatewayStatuses,
|
||||
func(ctx krt.HandlerContext, i krt.ObjectWithStatus[*gateway.Gateway, gateway.GatewayStatus]) *krt.ObjectWithStatus[*gateway.Gateway, gateway.GatewayStatus] {
|
||||
tcpRoutes := krt.Fetch(ctx, routeAttachments, krt.FilterIndex(routeAttachmentsIndex, config.NamespacedName(i.Obj)))
|
||||
counts := map[string]int32{}
|
||||
for _, r := range tcpRoutes {
|
||||
counts[r.ListenerName]++
|
||||
}
|
||||
status := i.Status.DeepCopy()
|
||||
for i, s := range status.Listeners {
|
||||
s.AttachedRoutes = counts[string(s.Name)]
|
||||
status.Listeners[i] = s
|
||||
}
|
||||
return &krt.ObjectWithStatus[*gateway.Gateway, gateway.GatewayStatus]{
|
||||
Obj: i.Obj,
|
||||
Status: *status,
|
||||
}
|
||||
}, opts.WithName("GatewayFinalStatus")...)
|
||||
}
|
||||
|
||||
// RouteParents holds information about things routes can reference as parents.
|
||||
type RouteParents struct {
|
||||
gateways krt.Collection[Gateway]
|
||||
gatewayIndex krt.Index[parentKey, Gateway]
|
||||
}
|
||||
|
||||
func (p RouteParents) fetch(ctx krt.HandlerContext, pk parentKey) []*parentInfo {
|
||||
if pk == meshParentKey {
|
||||
// Special case
|
||||
return []*parentInfo{
|
||||
{
|
||||
InternalName: "mesh",
|
||||
// Mesh has no configurable AllowedKinds, so allow all supported
|
||||
AllowedKinds: []gateway.RouteGroupKind{
|
||||
{Group: (*gateway.Group)(ptr.Of(gvk.HTTPRoute.Group)), Kind: gateway.Kind(gvk.HTTPRoute.Kind)},
|
||||
{Group: (*gateway.Group)(ptr.Of(gvk.GRPCRoute.Group)), Kind: gateway.Kind(gvk.GRPCRoute.Kind)},
|
||||
{Group: (*gateway.Group)(ptr.Of(gvk.TCPRoute.Group)), Kind: gateway.Kind(gvk.TCPRoute.Kind)},
|
||||
{Group: (*gateway.Group)(ptr.Of(gvk.TLSRoute.Group)), Kind: gateway.Kind(gvk.TLSRoute.Kind)},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return slices.Map(krt.Fetch(ctx, p.gateways, krt.FilterIndex(p.gatewayIndex, pk)), func(gw Gateway) *parentInfo {
|
||||
return &gw.ParentInfo
|
||||
})
|
||||
}
|
||||
|
||||
func BuildRouteParents(
|
||||
gateways krt.Collection[Gateway],
|
||||
) RouteParents {
|
||||
idx := krt.NewIndex(gateways, "parent", func(o Gateway) []parentKey {
|
||||
return []parentKey{o.Parent}
|
||||
})
|
||||
return RouteParents{
|
||||
gateways: gateways,
|
||||
gatewayIndex: idx,
|
||||
}
|
||||
}
|
||||
|
||||
func detectListenerPortNumber(l gatewayx.ListenerEntry) (gatewayx.PortNumber, error) {
|
||||
if l.Port != 0 {
|
||||
return l.Port, nil
|
||||
}
|
||||
switch l.Protocol {
|
||||
case gatewayv1.HTTPProtocolType:
|
||||
return 80, nil
|
||||
case gatewayv1.HTTPSProtocolType:
|
||||
return 443, nil
|
||||
}
|
||||
return 0, fmt.Errorf("protocol %v requires a port to be set", l.Protocol)
|
||||
}
|
||||
|
||||
func convertStandardStatusToListenerSetStatus(l gatewayx.ListenerEntry) func(e gateway.ListenerStatus) gatewayx.ListenerEntryStatus {
|
||||
return func(e gateway.ListenerStatus) gatewayx.ListenerEntryStatus {
|
||||
return gatewayx.ListenerEntryStatus{
|
||||
Name: e.Name,
|
||||
Port: l.Port,
|
||||
SupportedKinds: e.SupportedKinds,
|
||||
AttachedRoutes: e.AttachedRoutes,
|
||||
Conditions: e.Conditions,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func convertListenerSetStatusToStandardStatus(e gatewayx.ListenerEntryStatus) gateway.ListenerStatus {
|
||||
return gateway.ListenerStatus{
|
||||
Name: e.Name,
|
||||
SupportedKinds: e.SupportedKinds,
|
||||
AttachedRoutes: e.AttachedRoutes,
|
||||
Conditions: e.Conditions,
|
||||
}
|
||||
}
|
||||
|
||||
func convertListenerSetToListener(l gatewayx.ListenerEntry) gateway.Listener {
|
||||
// For now, structs are identical enough Go can cast them. I doubt this will hold up forever, but we can adjust as needed.
|
||||
return gateway.Listener(l)
|
||||
}
|
||||
@@ -12,22 +12,21 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
k8sv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"istio.io/istio/pilot/pkg/model/kstatus"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
"istio.io/istio/pkg/kube/kclient"
|
||||
"istio.io/istio/pkg/util/istiomultierror"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
)
|
||||
|
||||
// ClassController is a controller that creates the default Istio GatewayClass(s). This will not
|
||||
@@ -103,19 +102,19 @@ func (c *ClassController) reconcileClass(class gateway.ObjectName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetClassStatus(existing *k8s.GatewayClassStatus, gen int64) k8s.GatewayClassStatus {
|
||||
func GetClassStatus(existing *k8sv1.GatewayClassStatus, gen int64) *k8sv1.GatewayClassStatus {
|
||||
if existing == nil {
|
||||
existing = &k8s.GatewayClassStatus{}
|
||||
existing = &k8sv1.GatewayClassStatus{}
|
||||
}
|
||||
existing.Conditions = kstatus.UpdateConditionIfChanged(existing.Conditions, metav1.Condition{
|
||||
Type: string(gateway.GatewayClassConditionStatusAccepted),
|
||||
Type: string(k8sv1.GatewayClassConditionStatusAccepted),
|
||||
Status: kstatus.StatusTrue,
|
||||
ObservedGeneration: gen,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: string(gateway.GatewayClassConditionStatusAccepted),
|
||||
Reason: string(k8sv1.GatewayClassConditionStatusAccepted),
|
||||
// Start - Updated by Higress
|
||||
Message: "Handled by Higress controller",
|
||||
// End - Updated by Higress
|
||||
})
|
||||
return *existing
|
||||
return existing
|
||||
}
|
||||
|
||||
68
pkg/ingress/kube/gateway/istio/gatewayclass_collection.go
Normal file
68
pkg/ingress/kube/gateway/istio/gatewayclass_collection.go
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
)
|
||||
|
||||
type GatewayClass struct {
|
||||
Name string
|
||||
Controller gateway.GatewayController
|
||||
}
|
||||
|
||||
func (g GatewayClass) ResourceName() string {
|
||||
return g.Name
|
||||
}
|
||||
|
||||
func GatewayClassesCollection(
|
||||
gatewayClasses krt.Collection[*gateway.GatewayClass],
|
||||
opts krt.OptionsBuilder,
|
||||
) (
|
||||
krt.StatusCollection[*gateway.GatewayClass, gateway.GatewayClassStatus],
|
||||
krt.Collection[GatewayClass],
|
||||
) {
|
||||
return krt.NewStatusCollection(gatewayClasses, func(ctx krt.HandlerContext, obj *gateway.GatewayClass) (*gateway.GatewayClassStatus, *GatewayClass) {
|
||||
_, known := classInfos[obj.Spec.ControllerName]
|
||||
if !known {
|
||||
return nil, nil
|
||||
}
|
||||
status := obj.Status.DeepCopy()
|
||||
status = GetClassStatus(status, obj.Generation)
|
||||
return status, &GatewayClass{
|
||||
Name: obj.Name,
|
||||
Controller: obj.Spec.ControllerName,
|
||||
}
|
||||
}, opts.WithName("GatewayClasses")...)
|
||||
}
|
||||
|
||||
func fetchClass(ctx krt.HandlerContext, gatewayClasses krt.Collection[GatewayClass], gc gatewayv1.ObjectName) *GatewayClass {
|
||||
class := krt.FetchOne(ctx, gatewayClasses, krt.FilterKey(string(gc)))
|
||||
if class == nil {
|
||||
if bc, f := builtinClasses[gc]; f {
|
||||
// We allow some classes to exist without being in the cluster
|
||||
return &GatewayClass{
|
||||
Name: string(gc),
|
||||
Controller: bc,
|
||||
}
|
||||
}
|
||||
// No gateway class found, this may be meant for another controller; should be skipped.
|
||||
return nil
|
||||
}
|
||||
return class
|
||||
}
|
||||
@@ -16,17 +16,17 @@ package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/kclient/clienttest"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/test/util/retry"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
)
|
||||
|
||||
func TestClassController(t *testing.T) {
|
||||
@@ -71,19 +71,19 @@ func TestClassController(t *testing.T) {
|
||||
}
|
||||
|
||||
// Class should be created initially
|
||||
expectClass(defaultClassName, constants.ManagedGatewayController)
|
||||
expectClass(constants.DefaultGatewayClass, constants.ManagedGatewayController)
|
||||
|
||||
// Once we delete it, it should be added back
|
||||
deleteClass(defaultClassName)
|
||||
expectClass(defaultClassName, constants.ManagedGatewayController)
|
||||
deleteClass(constants.DefaultGatewayClass)
|
||||
expectClass(constants.DefaultGatewayClass, constants.ManagedGatewayController)
|
||||
|
||||
// Overwrite the class, controller should not reconcile it back
|
||||
createClass(defaultClassName, "different-controller")
|
||||
expectClass(defaultClassName, "different-controller")
|
||||
createClass(constants.DefaultGatewayClass, "different-controller")
|
||||
expectClass(constants.DefaultGatewayClass, "different-controller")
|
||||
|
||||
// Once we delete it, it should be added back
|
||||
deleteClass(defaultClassName)
|
||||
expectClass(defaultClassName, constants.ManagedGatewayController)
|
||||
deleteClass(constants.DefaultGatewayClass)
|
||||
expectClass(constants.DefaultGatewayClass, constants.ManagedGatewayController)
|
||||
|
||||
// Create an unrelated GatewayClass, we should not do anything to it
|
||||
createClass("something-else", "different-controller")
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
Copyright Istio Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package istio
|
||||
|
||||
type gatewayGeneration struct {
|
||||
inner any
|
||||
}
|
||||
|
||||
func (g *gatewayGeneration) SetObservedGeneration(i int64) {
|
||||
// Intentionally blank. The observed generation of a gateway
|
||||
// status type is contained in the individual conditions
|
||||
// not at the top level, and is the responsibility
|
||||
// of the condition functions to update.
|
||||
}
|
||||
|
||||
func (g *gatewayGeneration) Unwrap() any {
|
||||
return g.inner
|
||||
}
|
||||
599
pkg/ingress/kube/gateway/istio/inferencepool_collection.go
Normal file
599
pkg/ingress/kube/gateway/istio/inferencepool_collection.go
Normal file
@@ -0,0 +1,599 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
|
||||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube/kclient"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/maps"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/slices"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
)
|
||||
|
||||
const (
|
||||
maxServiceNameLength = 63
|
||||
hashSize = 8
|
||||
InferencePoolRefLabel = "higress.io/inferencepool-name"
|
||||
InferencePoolExtensionRefSvc = "higress.io/inferencepool-extension-service"
|
||||
InferencePoolExtensionRefPort = "higress.io/inferencepool-extension-port"
|
||||
InferencePoolExtensionRefFailureMode = "higress.io/inferencepool-extension-failure-mode"
|
||||
)
|
||||
|
||||
// // ManagedLabel is the label used to identify resources managed by this controller
|
||||
// const ManagedLabel = "inference.x-k8s.io/managed-by"
|
||||
|
||||
// ControllerName is the name of this controller for labeling resources it manages
|
||||
const ControllerName = "inference-controller"
|
||||
|
||||
var supportedControllers = getSupportedControllers()
|
||||
|
||||
func getSupportedControllers() sets.Set[gatewayv1.GatewayController] {
|
||||
ret := sets.New[gatewayv1.GatewayController]()
|
||||
for _, controller := range builtinClasses {
|
||||
ret.Insert(controller)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type shadowServiceInfo struct {
|
||||
key types.NamespacedName
|
||||
selector map[string]string
|
||||
poolName string
|
||||
poolUID types.UID
|
||||
targetPort int32
|
||||
}
|
||||
|
||||
type extRefInfo struct {
|
||||
name string
|
||||
port int32
|
||||
failureMode string
|
||||
}
|
||||
|
||||
type InferencePool struct {
|
||||
shadowService shadowServiceInfo
|
||||
extRef extRefInfo
|
||||
gatewayParents sets.Set[types.NamespacedName] // Gateways that reference this InferencePool
|
||||
}
|
||||
|
||||
func (i InferencePool) ResourceName() string {
|
||||
return i.shadowService.key.Namespace + "/" + i.shadowService.poolName
|
||||
}
|
||||
|
||||
func InferencePoolCollection(
|
||||
pools krt.Collection[*inferencev1alpha2.InferencePool],
|
||||
services krt.Collection[*corev1.Service],
|
||||
httpRoutes krt.Collection[*gateway.HTTPRoute],
|
||||
gateways krt.Collection[*gateway.Gateway],
|
||||
routesByInferencePool krt.Index[string, *gateway.HTTPRoute],
|
||||
c *Controller,
|
||||
opts krt.OptionsBuilder,
|
||||
) (krt.StatusCollection[*inferencev1alpha2.InferencePool, inferencev1alpha2.InferencePoolStatus], krt.Collection[InferencePool]) {
|
||||
return krt.NewStatusCollection(pools,
|
||||
func(
|
||||
ctx krt.HandlerContext,
|
||||
pool *inferencev1alpha2.InferencePool,
|
||||
) (*inferencev1alpha2.InferencePoolStatus, *InferencePool) {
|
||||
// Fetch HTTPRoutes that reference this InferencePool once and reuse
|
||||
routeList := krt.Fetch(ctx, httpRoutes, krt.FilterIndex(routesByInferencePool, pool.Namespace+"/"+pool.Name))
|
||||
|
||||
// Find gateway parents that reference this InferencePool through HTTPRoutes
|
||||
gatewayParents := findGatewayParents(pool, routeList)
|
||||
|
||||
// TODO: If no gateway parents, we should not do anything
|
||||
// note: we stil need to filter out our Status to clean up previous reconciliations
|
||||
|
||||
// Create the InferencePool only if there are Gateways connected
|
||||
var inferencePool *InferencePool
|
||||
if len(gatewayParents) > 0 {
|
||||
// Create the InferencePool object
|
||||
inferencePool = createInferencePoolObject(pool, gatewayParents)
|
||||
}
|
||||
|
||||
// Calculate status
|
||||
status := calculateInferencePoolStatus(pool, gatewayParents, services, gateways, routeList)
|
||||
|
||||
return status, inferencePool
|
||||
}, opts.WithName("InferenceExtension")...)
|
||||
}
|
||||
|
||||
// createInferencePoolObject creates the InferencePool object with shadow service and extension ref info
|
||||
func createInferencePoolObject(pool *inferencev1alpha2.InferencePool, gatewayParents sets.Set[types.NamespacedName]) *InferencePool {
|
||||
// Build extension reference info
|
||||
extRef := extRefInfo{
|
||||
name: string(pool.Spec.ExtensionRef.Name),
|
||||
}
|
||||
if pool.Spec.ExtensionRef.PortNumber != nil {
|
||||
extRef.port = int32(*pool.Spec.ExtensionRef.PortNumber)
|
||||
} else {
|
||||
extRef.port = 9002 // Default port for the inference extension
|
||||
}
|
||||
if pool.Spec.ExtensionRef.FailureMode != nil {
|
||||
extRef.failureMode = string(*pool.Spec.ExtensionRef.FailureMode)
|
||||
} else {
|
||||
extRef.failureMode = string(inferencev1alpha2.FailClose)
|
||||
}
|
||||
|
||||
svcName, err := InferencePoolServiceName(pool.Name)
|
||||
if err != nil {
|
||||
log.Errorf("failed to generate service name for InferencePool %s: %v", pool.Name, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
shadowSvcInfo := shadowServiceInfo{
|
||||
key: types.NamespacedName{
|
||||
Name: svcName,
|
||||
Namespace: pool.GetNamespace(),
|
||||
},
|
||||
selector: make(map[string]string, len(pool.Spec.Selector)),
|
||||
poolName: pool.GetName(),
|
||||
targetPort: pool.Spec.TargetPortNumber,
|
||||
poolUID: pool.GetUID(),
|
||||
}
|
||||
|
||||
for k, v := range pool.Spec.Selector {
|
||||
shadowSvcInfo.selector[string(k)] = string(v)
|
||||
}
|
||||
|
||||
return &InferencePool{
|
||||
shadowService: shadowSvcInfo,
|
||||
extRef: extRef,
|
||||
gatewayParents: gatewayParents,
|
||||
}
|
||||
}
|
||||
|
||||
// calculateInferencePoolStatus calculates the complete status for an InferencePool
|
||||
func calculateInferencePoolStatus(
|
||||
pool *inferencev1alpha2.InferencePool,
|
||||
gatewayParents sets.Set[types.NamespacedName],
|
||||
services krt.Collection[*corev1.Service],
|
||||
gateways krt.Collection[*gateway.Gateway],
|
||||
routeList []*gateway.HTTPRoute,
|
||||
) *inferencev1alpha2.InferencePoolStatus {
|
||||
// Calculate status for each gateway parent
|
||||
existingParents := pool.Status.DeepCopy().Parents
|
||||
finalParents := []inferencev1alpha2.PoolStatus{}
|
||||
|
||||
// Add existing parents from other controllers (not managed by us)
|
||||
for _, existingParent := range existingParents {
|
||||
gtwName := string(existingParent.GatewayRef.Name)
|
||||
gtwNamespace := pool.Namespace
|
||||
if existingParent.GatewayRef.Namespace != nil {
|
||||
gtwNamespace = string(*existingParent.GatewayRef.Namespace)
|
||||
}
|
||||
parentKey := types.NamespacedName{
|
||||
Name: gtwName,
|
||||
Namespace: gtwNamespace,
|
||||
}
|
||||
|
||||
isCurrentlyOurs := gatewayParents.Contains(parentKey)
|
||||
|
||||
// Keep parents that are not ours and not default status parents
|
||||
if !isCurrentlyOurs &&
|
||||
!isOurManagedGateway(gateways, gtwNamespace, gtwName) &&
|
||||
!isDefaultStatusParent(existingParent) {
|
||||
finalParents = append(finalParents, existingParent)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate status for each of our gateway parents
|
||||
for gatewayParent := range gatewayParents {
|
||||
parentStatus := calculateSingleParentStatus(pool, gatewayParent, services, existingParents, routeList)
|
||||
finalParents = append(finalParents, parentStatus)
|
||||
}
|
||||
|
||||
return &inferencev1alpha2.InferencePoolStatus{
|
||||
Parents: finalParents,
|
||||
}
|
||||
}
|
||||
|
||||
// findGatewayParents finds all Gateway parents that reference this InferencePool through HTTPRoutes
|
||||
func findGatewayParents(
|
||||
pool *inferencev1alpha2.InferencePool,
|
||||
routeList []*gateway.HTTPRoute,
|
||||
) sets.Set[types.NamespacedName] {
|
||||
gatewayParents := sets.New[types.NamespacedName]()
|
||||
|
||||
for _, route := range routeList {
|
||||
// Only process routes that reference our InferencePool
|
||||
if !routeReferencesInferencePool(route, pool) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check the route's parent status to find accepted gateways
|
||||
for _, parentStatus := range route.Status.Parents {
|
||||
// Only consider parents managed by our supported controllers (from supportedControllers variable)
|
||||
// This filters out parents from other controllers we don't manage
|
||||
if !supportedControllers.Contains(parentStatus.ControllerName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get the gateway namespace (default to route namespace if not specified)
|
||||
gatewayNamespace := route.Namespace
|
||||
if ptr.OrEmpty(parentStatus.ParentRef.Namespace) != "" {
|
||||
gatewayNamespace = string(*parentStatus.ParentRef.Namespace)
|
||||
}
|
||||
|
||||
gatewayParents.Insert(types.NamespacedName{
|
||||
Name: string(parentStatus.ParentRef.Name),
|
||||
Namespace: gatewayNamespace,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return gatewayParents
|
||||
}
|
||||
|
||||
// routeReferencesInferencePool checks if an HTTPRoute references the given InferencePool
|
||||
func routeReferencesInferencePool(route *gateway.HTTPRoute, pool *inferencev1alpha2.InferencePool) bool {
|
||||
for _, rule := range route.Spec.Rules {
|
||||
for _, backendRef := range rule.BackendRefs {
|
||||
if !isInferencePoolBackendRef(backendRef.BackendRef) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if this backend ref points to our InferencePool
|
||||
if string(backendRef.BackendRef.Name) != pool.ObjectMeta.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check namespace match
|
||||
backendRefNamespace := route.Namespace
|
||||
if ptr.OrEmpty(backendRef.BackendRef.Namespace) != "" {
|
||||
backendRefNamespace = string(*backendRef.BackendRef.Namespace)
|
||||
}
|
||||
|
||||
if backendRefNamespace == pool.Namespace {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isInferencePoolBackendRef checks if a BackendRef is pointing to an InferencePool
|
||||
func isInferencePoolBackendRef(backendRef gatewayv1.BackendRef) bool {
|
||||
return ptr.OrEmpty(backendRef.Group) == gatewayv1.Group(gvk.InferencePool.Group) &&
|
||||
ptr.OrEmpty(backendRef.Kind) == gatewayv1.Kind(gvk.InferencePool.Kind)
|
||||
}
|
||||
|
||||
// calculateSingleParentStatus calculates the status for a single gateway parent
|
||||
func calculateSingleParentStatus(
|
||||
pool *inferencev1alpha2.InferencePool,
|
||||
gatewayParent types.NamespacedName,
|
||||
services krt.Collection[*corev1.Service],
|
||||
existingParents []inferencev1alpha2.PoolStatus,
|
||||
routeList []*gateway.HTTPRoute,
|
||||
) inferencev1alpha2.PoolStatus {
|
||||
// Find existing status for this parent to preserve some conditions
|
||||
var existingConditions []metav1.Condition
|
||||
for _, existingParent := range existingParents {
|
||||
if string(existingParent.GatewayRef.Name) == gatewayParent.Name &&
|
||||
string(ptr.OrEmpty(existingParent.GatewayRef.Namespace)) == gatewayParent.Namespace {
|
||||
existingConditions = existingParent.Conditions
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Filter to only keep conditions we manage
|
||||
filteredConditions := filterUsedConditions(existingConditions,
|
||||
inferencev1alpha2.InferencePoolConditionAccepted,
|
||||
inferencev1alpha2.InferencePoolConditionResolvedRefs)
|
||||
|
||||
// Calculate Accepted status by checking HTTPRoute parent status
|
||||
acceptedStatus := calculateAcceptedStatus(pool, gatewayParent, routeList)
|
||||
|
||||
// Calculate ResolvedRefs status
|
||||
resolvedRefsStatus := calculateResolvedRefsStatus(pool, services)
|
||||
|
||||
// Build the final status
|
||||
return inferencev1alpha2.PoolStatus{
|
||||
GatewayRef: inferencev1alpha2.ParentGatewayReference{
|
||||
Group: (*inferencev1alpha2.Group)(&gvk.Gateway.Group),
|
||||
Kind: (*inferencev1alpha2.Kind)(&gvk.Gateway.Kind),
|
||||
Namespace: (*inferencev1alpha2.Namespace)(&gatewayParent.Namespace),
|
||||
Name: inferencev1alpha2.ObjectName(gatewayParent.Name),
|
||||
},
|
||||
Conditions: setConditions(pool.Generation, filteredConditions, map[string]*condition{
|
||||
string(inferencev1alpha2.InferencePoolConditionAccepted): acceptedStatus,
|
||||
string(inferencev1alpha2.InferencePoolConditionResolvedRefs): resolvedRefsStatus,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// calculateAcceptedStatus determines if the InferencePool is accepted by checking HTTPRoute parent status
|
||||
func calculateAcceptedStatus(
|
||||
pool *inferencev1alpha2.InferencePool,
|
||||
gatewayParent types.NamespacedName,
|
||||
routeList []*gateway.HTTPRoute,
|
||||
) *condition {
|
||||
// Check if any HTTPRoute references this InferencePool and has this gateway as an accepted parent
|
||||
for _, route := range routeList {
|
||||
// Only process routes that reference our InferencePool
|
||||
if !routeReferencesInferencePool(route, pool) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if this route has our gateway as a parent and if it's accepted
|
||||
for _, parentStatus := range route.Status.Parents {
|
||||
// Only consider parents managed by supported controllers
|
||||
if !supportedControllers.Contains(parentStatus.ControllerName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if this parent refers to our gateway
|
||||
gatewayNamespace := route.Namespace
|
||||
if ptr.OrEmpty(parentStatus.ParentRef.Namespace) != "" {
|
||||
gatewayNamespace = string(*parentStatus.ParentRef.Namespace)
|
||||
}
|
||||
|
||||
if string(parentStatus.ParentRef.Name) == gatewayParent.Name && gatewayNamespace == gatewayParent.Namespace {
|
||||
// Check if this parent is accepted
|
||||
for _, parentCondition := range parentStatus.Conditions {
|
||||
if parentCondition.Type == string(gatewayv1.RouteConditionAccepted) {
|
||||
if parentCondition.Status == metav1.ConditionTrue {
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
|
||||
status: metav1.ConditionTrue,
|
||||
message: "Referenced by an HTTPRoute accepted by the parentRef Gateway",
|
||||
}
|
||||
}
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolReasonHTTPRouteNotAccepted),
|
||||
status: metav1.ConditionFalse,
|
||||
message: fmt.Sprintf("Referenced HTTPRoute %s/%s not accepted by Gateway %s/%s: %s",
|
||||
route.Namespace, route.Name, gatewayParent.Namespace, gatewayParent.Name, parentCondition.Message),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no Accepted condition found, treat as unknown (parent is listed in status)
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
|
||||
status: metav1.ConditionUnknown,
|
||||
message: "Referenced by an HTTPRoute unknown parentRef Gateway status",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, no HTTPRoute was found that references this InferencePool with this gateway as parent
|
||||
// This shouldn't happen in normal operation since we only call this for known gateway parents
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolReasonHTTPRouteNotAccepted),
|
||||
status: metav1.ConditionFalse,
|
||||
message: fmt.Sprintf("No HTTPRoute found referencing this InferencePool with Gateway %s/%s as parent",
|
||||
gatewayParent.Namespace, gatewayParent.Name),
|
||||
}
|
||||
}
|
||||
|
||||
// calculateResolvedRefsStatus determines the states of the ExtensionRef
|
||||
// * if the kind is supported
|
||||
// * if the extensionRef is defined
|
||||
// * if the service exists in the same namespace as the InferencePool
|
||||
func calculateResolvedRefsStatus(
|
||||
pool *inferencev1alpha2.InferencePool,
|
||||
services krt.Collection[*corev1.Service],
|
||||
) *condition {
|
||||
// defaults to service
|
||||
if pool.Spec.ExtensionRef.Kind != nil && string(*pool.Spec.ExtensionRef.Kind) != gvk.Service.Kind {
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
|
||||
status: metav1.ConditionFalse,
|
||||
message: "Unsupported ExtensionRef kind " + string(*pool.Spec.ExtensionRef.Kind),
|
||||
}
|
||||
}
|
||||
if string(pool.Spec.ExtensionRef.Name) == "" {
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
|
||||
status: metav1.ConditionFalse,
|
||||
message: "ExtensionRef not defined",
|
||||
}
|
||||
}
|
||||
svc := ptr.Flatten(services.GetKey(fmt.Sprintf("%s/%s", pool.Namespace, pool.Spec.ExtensionRef.Name)))
|
||||
if svc == nil {
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
|
||||
status: metav1.ConditionFalse,
|
||||
message: "Referenced ExtensionRef not found " + string(pool.Spec.ExtensionRef.Name),
|
||||
}
|
||||
}
|
||||
return &condition{
|
||||
reason: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
|
||||
status: metav1.ConditionTrue,
|
||||
message: "Referenced ExtensionRef resolved successfully",
|
||||
}
|
||||
}
|
||||
|
||||
// isDefaultStatusParent checks if this is a default status parent entry
|
||||
func isDefaultStatusParent(parent inferencev1alpha2.PoolStatus) bool {
|
||||
return string(ptr.OrEmpty(parent.GatewayRef.Kind)) == "Status" && parent.GatewayRef.Name == "default"
|
||||
}
|
||||
|
||||
// isOurManagedGateway checks if a Gateway is managed by one of our supported controllers
|
||||
// This is used to identify stale parent entries that we previously added but are no longer referenced by HTTPRoutes
|
||||
func isOurManagedGateway(gateways krt.Collection[*gateway.Gateway], namespace, name string) bool {
|
||||
gtw := ptr.Flatten(gateways.GetKey(fmt.Sprintf("%s/%s", namespace, name)))
|
||||
if gtw == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := builtinClasses[gtw.Spec.GatewayClassName]
|
||||
return ok
|
||||
}
|
||||
|
||||
func filterUsedConditions(conditions []metav1.Condition, usedConditions ...inferencev1alpha2.InferencePoolConditionType) []metav1.Condition {
|
||||
var result []metav1.Condition
|
||||
for _, condition := range conditions {
|
||||
if slices.Contains(usedConditions, inferencev1alpha2.InferencePoolConditionType(condition.Type)) {
|
||||
result = append(result, condition)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// generateHash generates an 8-character SHA256 hash of the input string.
|
||||
func generateHash(input string, length int) string {
|
||||
hashBytes := sha256.Sum256([]byte(input))
|
||||
hashString := fmt.Sprintf("%x", hashBytes) // Convert to hexadecimal string
|
||||
return hashString[:length] // Truncate to desired length
|
||||
}
|
||||
|
||||
func InferencePoolServiceName(poolName string) (string, error) {
|
||||
ipSeparator := "-ip-"
|
||||
hash := generateHash(poolName, hashSize)
|
||||
svcName := poolName + ipSeparator + hash
|
||||
// Truncate if necessary to meet the Kubernetes naming constraints
|
||||
if len(svcName) > maxServiceNameLength {
|
||||
// Calculate the maximum allowed base name length
|
||||
maxBaseLength := maxServiceNameLength - len(ipSeparator) - hashSize
|
||||
if maxBaseLength < 0 {
|
||||
return "", fmt.Errorf("inference pool name: %s is too long", poolName)
|
||||
}
|
||||
|
||||
// Truncate the base name and reconstruct the service name
|
||||
truncatedBase := poolName[:maxBaseLength]
|
||||
svcName = truncatedBase + ipSeparator + hash
|
||||
}
|
||||
return svcName, nil
|
||||
}
|
||||
|
||||
func translateShadowServiceToService(existingLabels map[string]string, shadow shadowServiceInfo, extRef extRefInfo) *corev1.Service {
|
||||
// Create a new service object based on the shadow service info
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: shadow.key.Name,
|
||||
Namespace: shadow.key.Namespace,
|
||||
Labels: maps.MergeCopy(map[string]string{
|
||||
InferencePoolRefLabel: shadow.poolName,
|
||||
InferencePoolExtensionRefSvc: extRef.name,
|
||||
InferencePoolExtensionRefPort: strconv.Itoa(int(extRef.port)),
|
||||
InferencePoolExtensionRefFailureMode: extRef.failureMode,
|
||||
constants.InternalServiceSemantics: constants.ServiceSemanticsInferencePool,
|
||||
}, existingLabels),
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Selector: shadow.selector,
|
||||
Type: corev1.ServiceTypeClusterIP,
|
||||
ClusterIP: corev1.ClusterIPNone, // Headless service
|
||||
Ports: []corev1.ServicePort{ // adding dummy port, not used for anything
|
||||
{
|
||||
Protocol: "TCP",
|
||||
Port: int32(54321),
|
||||
TargetPort: intstr.FromInt(int(shadow.targetPort)),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
svc.SetOwnerReferences([]metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: gvk.InferencePool.GroupVersion(),
|
||||
Kind: gvk.InferencePool.Kind,
|
||||
Name: shadow.poolName,
|
||||
UID: shadow.poolUID,
|
||||
},
|
||||
})
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *Controller) reconcileShadowService(
|
||||
svcClient kclient.Client[*corev1.Service],
|
||||
inferencePools krt.Collection[InferencePool],
|
||||
servicesCollection krt.Collection[*corev1.Service],
|
||||
) func(key types.NamespacedName) error {
|
||||
return func(key types.NamespacedName) error {
|
||||
// Find the InferencePool that matches the key
|
||||
pool := inferencePools.GetKey(key.String())
|
||||
if pool == nil {
|
||||
// we'll generally ignore these scenarios, since the InferencePool may have been deleted
|
||||
log.Debugf("inferencepool no longer exists", key.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
// We found the InferencePool, now we need to translate it to a shadow Service
|
||||
// and check if it exists already
|
||||
existingService := ptr.Flatten(servicesCollection.GetKey(pool.shadowService.key.String()))
|
||||
|
||||
// Check if we can manage this service
|
||||
var existingLabels map[string]string
|
||||
if existingService != nil {
|
||||
existingLabels = existingService.GetLabels()
|
||||
canManage, _ := c.canManageShadowServiceForInference(existingService)
|
||||
if !canManage {
|
||||
log.Debugf("skipping service %s/%s, already managed by another controller", key.Namespace, key.Name)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
service := translateShadowServiceToService(existingLabels, pool.shadowService, pool.extRef)
|
||||
|
||||
var err error
|
||||
if existingService == nil {
|
||||
// Create the service if it doesn't exist
|
||||
_, err = svcClient.Create(service)
|
||||
} else {
|
||||
// TODO: Don't overwrite resources: https://github.com/istio/istio/issues/56667
|
||||
service.ResourceVersion = existingService.ResourceVersion
|
||||
_, err = svcClient.Update(service)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// canManage checks if a service should be managed by this controller
|
||||
func (c *Controller) canManageShadowServiceForInference(obj *corev1.Service) (bool, string) {
|
||||
if obj == nil {
|
||||
// No object exists, we can manage it
|
||||
return true, ""
|
||||
}
|
||||
|
||||
_, inferencePoolManaged := obj.GetLabels()[InferencePoolRefLabel]
|
||||
// We can manage if it has no manager or if we are the manager
|
||||
return inferencePoolManaged, obj.GetResourceVersion()
|
||||
}
|
||||
|
||||
func indexHTTPRouteByInferencePool(o *gateway.HTTPRoute) []string {
|
||||
var keys []string
|
||||
for _, rule := range o.Spec.Rules {
|
||||
for _, backendRef := range rule.BackendRefs {
|
||||
if isInferencePoolBackendRef(backendRef.BackendRef) {
|
||||
// If BackendRef.Namespace is not specified, the backend is in the same namespace as the HTTPRoute's
|
||||
backendRefNamespace := o.Namespace
|
||||
if ptr.OrEmpty(backendRef.BackendRef.Namespace) != "" {
|
||||
backendRefNamespace = string(*backendRef.BackendRef.Namespace)
|
||||
}
|
||||
key := backendRefNamespace + "/" + string(backendRef.Name)
|
||||
keys = append(keys, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
return keys
|
||||
}
|
||||
798
pkg/ingress/kube/gateway/istio/inferencepool_status_test.go
Normal file
798
pkg/ingress/kube/gateway/istio/inferencepool_status_test.go
Normal file
@@ -0,0 +1,798 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
|
||||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pilot/pkg/status"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/test"
|
||||
)
|
||||
|
||||
const (
|
||||
HigressController = constants.ManagedGatewayController
|
||||
DefaultTestNS = "default"
|
||||
GatewayTestNS = "gateway-ns"
|
||||
AppTestNS = "app-ns"
|
||||
EmptyTestNS = ""
|
||||
)
|
||||
|
||||
func TestInferencePoolStatusReconciliation(t *testing.T) {
|
||||
test.SetForTest(t, &features.EnableGatewayAPIInferenceExtension, true)
|
||||
testCases := []struct {
|
||||
name string
|
||||
givens []runtime.Object // Objects to create before the test
|
||||
targetPool *inferencev1alpha2.InferencePool // The InferencePool to check
|
||||
expectations func(t *testing.T, pool *inferencev1alpha2.InferencePoolStatus)
|
||||
}{
|
||||
//
|
||||
// Positive Test Scenarios
|
||||
//
|
||||
{
|
||||
name: "should add gateway parentRef to inferencepool status",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
WithRouteParentCondition(string(gatewayv1.RouteConditionAccepted), metav1.ConditionTrue, "Accepted", "Accepted"),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
|
||||
Type: string(inferencev1alpha2.InferencePoolConditionAccepted),
|
||||
Status: metav1.ConditionTrue,
|
||||
Reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
|
||||
Message: "Referenced by an HTTPRoute",
|
||||
}, "Expected condition with Accepted")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should add only 1 gateway parentRef to status for multiple routes on different gateways with different controllers",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("other")),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithParentRefAndStatus("gateway-2", DefaultTestNS, "other-controller"),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should keep the status of the gateway parentRefs from antoher controller",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("other-class")),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
NewHTTPRoute("route-2", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-2", DefaultTestNS, "other-class"),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithParentStatus("gateway-2", DefaultTestNS, WithAcceptedConditions())),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 2, "Expected two parent references")
|
||||
assert.ElementsMatch(t,
|
||||
[]string{"gateway-1", "gateway-2"},
|
||||
[]string{string(status.Parents[0].GatewayRef.Name), string(status.Parents[1].GatewayRef.Name)},
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should add multiple gateway parentRefs to status for multiple routes",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
NewHTTPRoute("route-2", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-2", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 2, "Expected two parent references")
|
||||
assert.ElementsMatch(t,
|
||||
[]string{"gateway-1", "gateway-2"},
|
||||
[]string{string(status.Parents[0].GatewayRef.Name), string(status.Parents[1].GatewayRef.Name)},
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should remove our status from previous reconciliation that is no longer referenced by any HTTPRoute",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS),
|
||||
WithParentStatus("gateway-2", DefaultTestNS,
|
||||
WithAcceptedConditions(),
|
||||
)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should update/recreate our status from previous reconciliation",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS),
|
||||
WithParentStatus("gateway-1", DefaultTestNS,
|
||||
WithAcceptedConditions(),
|
||||
)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
|
||||
require.Len(t, status.Parents[0].Conditions, 2, "Expected two conditions")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should keep others status from previous reconciliation",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewGateway("gateway-2", InNamespace(DefaultTestNS), WithGatewayClass("other-class")),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithParentStatus("gateway-2", DefaultTestNS, WithAcceptedConditions())),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 2, "Expected two parent references")
|
||||
assert.ElementsMatch(t,
|
||||
[]string{"gateway-1", "gateway-2"},
|
||||
[]string{string(status.Parents[0].GatewayRef.Name), string(status.Parents[1].GatewayRef.Name)},
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should remove default parent 'waiting for controller' status",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithParentStatus("default", DefaultTestNS, AsDefaultStatus())),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected two parent references")
|
||||
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should remove unknown condition types from controlled parents",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("gateway-1", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("route-1", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("gateway-1", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS),
|
||||
WithParentStatus("gateway-1", DefaultTestNS,
|
||||
WithAcceptedConditions(),
|
||||
WithConditions(metav1.ConditionUnknown, "X", "Y", "Dummy"),
|
||||
)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected two parent references")
|
||||
assert.Equal(t, "gateway-1", string(status.Parents[0].GatewayRef.Name))
|
||||
require.Len(t, status.Parents[0].Conditions, 2, "Expected two conditions")
|
||||
assert.ElementsMatch(t,
|
||||
[]string{string(inferencev1alpha2.InferencePoolConditionAccepted), string(inferencev1alpha2.InferencePoolConditionResolvedRefs)},
|
||||
[]string{status.Parents[0].Conditions[0].Type, status.Parents[0].Conditions[1].Type},
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should handle cross-namespace gateway references correctly",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(AppTestNS),
|
||||
WithParentRefAndStatus("main-gateway", GatewayTestNS, HigressController),
|
||||
WithBackendRef("test-pool", AppTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(AppTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, GatewayTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should handle cross-namespace httproute references correctly",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(AppTestNS),
|
||||
WithParentRefAndStatus("main-gateway", GatewayTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, GatewayTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should handle HTTPRoute in same namespace (empty)",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(AppTestNS),
|
||||
WithParentRefAndStatus("main-gateway", GatewayTestNS, HigressController),
|
||||
WithBackendRef("test-pool", EmptyTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(AppTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, GatewayTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should handle Gateway in same namespace (empty)",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(AppTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(AppTestNS),
|
||||
WithParentRefAndStatus("main-gateway", EmptyTestNS, HigressController),
|
||||
WithBackendRef("test-pool", AppTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(AppTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, AppTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should add only one parentRef for multiple routes on same gateway",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("route-a", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
NewHTTPRoute("route-b", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected only one parent reference for the same gateway")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should report ResolvedRef true when ExtensioNRef found",
|
||||
givens: []runtime.Object{
|
||||
NewService("test-epp", InNamespace(DefaultTestNS)),
|
||||
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithExtensionRef("Service", "test-epp")),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
require.Len(t, status.Parents[0].Conditions, 2, "Expected two condition")
|
||||
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
|
||||
Type: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
|
||||
Status: metav1.ConditionTrue,
|
||||
Reason: string(inferencev1alpha2.InferencePoolReasonResolvedRefs),
|
||||
Message: "Referenced ExtensionRef resolved",
|
||||
}, "Expected condition with InvalidExtensionRef")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should report HTTPRoute not accepted when parent gateway rejects HTTPRoute",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
WithRouteParentCondition(string(gatewayv1.RouteConditionAccepted), metav1.ConditionFalse, "GatewayNotReady", "Gateway not ready"),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
|
||||
Type: string(inferencev1alpha2.InferencePoolConditionAccepted),
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: string(inferencev1alpha2.InferencePoolReasonHTTPRouteNotAccepted),
|
||||
Message: "Referenced HTTPRoute default/test-route not accepted by Gateway default/main-gateway",
|
||||
}, "Expected condition with HTTPRouteNotAccepted")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should report unknown status when HTTPRoute parent status has no Accepted condition",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
// Note: No WithRouteParentCondition for Accepted - parent is listed but has no conditions
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
assert.Equal(t, "main-gateway", string(status.Parents[0].GatewayRef.Name))
|
||||
assert.Equal(t, DefaultTestNS, string(*status.Parents[0].GatewayRef.Namespace))
|
||||
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
|
||||
Type: string(inferencev1alpha2.InferencePoolConditionAccepted),
|
||||
Status: metav1.ConditionUnknown,
|
||||
Reason: string(inferencev1alpha2.InferencePoolReasonAccepted),
|
||||
Message: "Referenced by an HTTPRoute unknown parentRef Gateway status",
|
||||
}, "Expected condition with ConditionUnknown")
|
||||
},
|
||||
},
|
||||
|
||||
//
|
||||
// Negative Test Scenarios
|
||||
//
|
||||
{
|
||||
name: "should not add parentRef for gatewayclass not controlled by us",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass("other")),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, "other-controller"),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
assert.Empty(t, status.Parents, "ParentRefs should be empty")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should not add parentRef if httproute has no backendref",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(DefaultTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController)), // No BackendRef
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
assert.Empty(t, status.Parents, "ParentRefs should be empty")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should not add parentRef if httproute has no parentref",
|
||||
givens: []runtime.Object{
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithBackendRef("test-pool", DefaultTestNS)), // No ParentRef
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
assert.Empty(t, status.Parents, "ParentRefs should be empty")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should report ExtensionRef not found if no matching service found",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS)),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
require.Len(t, status.Parents[0].Conditions, 2, "Expected two condition")
|
||||
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
|
||||
Type: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
|
||||
Message: "Referenced ExtensionRef not found",
|
||||
}, "Expected condition with InvalidExtensionRef")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should report unsupported ExtensionRef if kind is not service",
|
||||
givens: []runtime.Object{
|
||||
NewGateway("main-gateway", InNamespace(GatewayTestNS), WithGatewayClass(constants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("main-gateway", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS)),
|
||||
},
|
||||
targetPool: NewInferencePool("test-pool", InNamespace(DefaultTestNS), WithExtensionRef("Gateway", "main-gateway")),
|
||||
expectations: func(t *testing.T, status *inferencev1alpha2.InferencePoolStatus) {
|
||||
require.Len(t, status.Parents, 1, "Expected one parent reference")
|
||||
require.Len(t, status.Parents[0].Conditions, 2, "Expected two condition")
|
||||
assertConditionContains(t, status.Parents[0].Conditions, metav1.Condition{
|
||||
Type: string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: string(inferencev1alpha2.InferencePoolReasonInvalidExtensionRef),
|
||||
Message: "Unsupported ExtensionRef kind",
|
||||
}, "Expected condition with InvalidExtensionRef")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
stop := test.NewStop(t)
|
||||
|
||||
controller := setupController(t,
|
||||
append(tc.givens, tc.targetPool)...,
|
||||
)
|
||||
|
||||
sq := &TestStatusQueue{
|
||||
state: map[status.Resource]any{},
|
||||
}
|
||||
statusSynced := controller.status.SetQueue(sq)
|
||||
for _, st := range statusSynced {
|
||||
st.WaitUntilSynced(stop)
|
||||
}
|
||||
|
||||
dumpOnFailure(t, krt.GlobalDebugHandler)
|
||||
|
||||
getInferencePoolStatus := func() *inferencev1alpha2.InferencePoolStatus {
|
||||
statuses := sq.Statuses()
|
||||
for _, status := range statuses {
|
||||
if pool, ok := status.(*inferencev1alpha2.InferencePoolStatus); ok {
|
||||
return pool
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
poolStatus := getInferencePoolStatus()
|
||||
assert.NotNil(t, poolStatus)
|
||||
|
||||
tc.expectations(t, poolStatus)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertConditionContains(t *testing.T, conditions []metav1.Condition, expected metav1.Condition, msgAndArgs ...interface{}) {
|
||||
t.Helper()
|
||||
|
||||
for _, condition := range conditions {
|
||||
if (expected.Type == "" || condition.Type == expected.Type) &&
|
||||
(expected.Status == "" || condition.Status == expected.Status) &&
|
||||
(expected.Reason == "" || condition.Reason == expected.Reason) &&
|
||||
(expected.Message == "" || strings.HasPrefix(condition.Message, expected.Message)) {
|
||||
return // Found matching condition
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, no matching condition was found
|
||||
assert.Fail(t, fmt.Sprintf("Expected condition with Type=%s, Status=%s, Reason=%s not found in conditions. Available conditions: %+v",
|
||||
expected.Type, expected.Status, expected.Reason, conditions), msgAndArgs...)
|
||||
}
|
||||
|
||||
// --- Mock Objects ---
|
||||
|
||||
// Option is a function that mutates an object.
|
||||
type Option func(client.Object)
|
||||
|
||||
type ParentOption func(*inferencev1alpha2.PoolStatus)
|
||||
|
||||
// --- Helper functions to mutate objects ---
|
||||
|
||||
func InNamespace(namespace string) Option {
|
||||
return func(obj client.Object) {
|
||||
obj.SetNamespace(namespace)
|
||||
}
|
||||
}
|
||||
|
||||
func WithController(name string) Option {
|
||||
return func(obj client.Object) {
|
||||
gw, ok := obj.(*gateway.GatewayClass)
|
||||
if ok {
|
||||
gw.Spec.ControllerName = gateway.GatewayController(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithGatewayClass(name string) Option {
|
||||
return func(obj client.Object) {
|
||||
gw, ok := obj.(*gateway.Gateway)
|
||||
if ok {
|
||||
gw.Spec.GatewayClassName = gateway.ObjectName(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithParentRef(name, namespace string) Option {
|
||||
return func(obj client.Object) {
|
||||
hr, ok := obj.(*gateway.HTTPRoute)
|
||||
if ok {
|
||||
namespaceName := gateway.Namespace(namespace)
|
||||
hr.Spec.ParentRefs = []gateway.ParentReference{
|
||||
{
|
||||
Name: gateway.ObjectName(name),
|
||||
Namespace: &namespaceName,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithParentRefAndStatus(name, namespace, controllerName string) Option {
|
||||
return func(obj client.Object) {
|
||||
hr, ok := obj.(*gateway.HTTPRoute)
|
||||
if ok {
|
||||
namespaceName := gateway.Namespace(namespace)
|
||||
if hr.Spec.ParentRefs == nil {
|
||||
hr.Spec.ParentRefs = []gateway.ParentReference{}
|
||||
}
|
||||
hr.Spec.ParentRefs = append(hr.Spec.ParentRefs, gateway.ParentReference{
|
||||
Name: gateway.ObjectName(name),
|
||||
Namespace: &namespaceName,
|
||||
})
|
||||
if hr.Status.Parents == nil {
|
||||
hr.Status.Parents = []gateway.RouteParentStatus{}
|
||||
}
|
||||
|
||||
parentStatusRef := &gateway.RouteParentStatus{
|
||||
ParentRef: gateway.ParentReference{
|
||||
Name: gateway.ObjectName(name),
|
||||
Namespace: &namespaceName,
|
||||
},
|
||||
ControllerName: gateway.GatewayController(controllerName),
|
||||
}
|
||||
hr.Status.Parents = append(hr.Status.Parents, *parentStatusRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithRouteParentCondition(conditionType string, status metav1.ConditionStatus, reason, message string) Option {
|
||||
return func(obj client.Object) {
|
||||
hr, ok := obj.(*gateway.HTTPRoute)
|
||||
if ok && len(hr.Status.Parents) > 0 {
|
||||
// Add condition to the last parent status (most recently added)
|
||||
lastParentIdx := len(hr.Status.Parents) - 1
|
||||
if hr.Status.Parents[lastParentIdx].Conditions == nil {
|
||||
hr.Status.Parents[lastParentIdx].Conditions = []metav1.Condition{}
|
||||
}
|
||||
hr.Status.Parents[lastParentIdx].Conditions = append(hr.Status.Parents[lastParentIdx].Conditions,
|
||||
metav1.Condition{
|
||||
Type: conditionType,
|
||||
Status: status,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
ObservedGeneration: 1,
|
||||
LastTransitionTime: metav1.NewTime(time.Now()),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithBackendRef(name, namespace string) Option {
|
||||
return func(obj client.Object) {
|
||||
hr, ok := obj.(*gateway.HTTPRoute)
|
||||
if ok {
|
||||
namespaceName := gateway.Namespace(namespace)
|
||||
if hr.Spec.Rules == nil {
|
||||
hr.Spec.Rules = []gateway.HTTPRouteRule{}
|
||||
}
|
||||
group := gateway.Group(gvk.InferencePool.Group)
|
||||
kind := gateway.Kind(gvk.InferencePool.Kind)
|
||||
hr.Spec.Rules = append(hr.Spec.Rules, gateway.HTTPRouteRule{
|
||||
BackendRefs: []gateway.HTTPBackendRef{
|
||||
{
|
||||
BackendRef: gateway.BackendRef{
|
||||
BackendObjectReference: gateway.BackendObjectReference{
|
||||
Name: gateway.ObjectName(name),
|
||||
Namespace: &namespaceName,
|
||||
Kind: &kind,
|
||||
Group: &group,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithParentStatus(gatewayName, namespace string, opt ...ParentOption) Option {
|
||||
return func(obj client.Object) {
|
||||
ip, ok := obj.(*inferencev1alpha2.InferencePool)
|
||||
if ok {
|
||||
if ip.Status.Parents == nil {
|
||||
ip.Status.Parents = []inferencev1alpha2.PoolStatus{}
|
||||
}
|
||||
poolStatus := inferencev1alpha2.PoolStatus{
|
||||
GatewayRef: inferencev1alpha2.ParentGatewayReference{
|
||||
Name: inferencev1alpha2.ObjectName(gatewayName),
|
||||
Namespace: (*inferencev1alpha2.Namespace)(&namespace),
|
||||
},
|
||||
}
|
||||
for _, opt := range opt {
|
||||
opt(&poolStatus)
|
||||
}
|
||||
ip.Status.Parents = append(ip.Status.Parents, poolStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AsDefaultStatus() ParentOption {
|
||||
return func(parentStatusRef *inferencev1alpha2.PoolStatus) {
|
||||
dName := "default"
|
||||
dKind := "Status"
|
||||
parentStatusRef.GatewayRef.Name = inferencev1alpha2.ObjectName(dName)
|
||||
parentStatusRef.GatewayRef.Kind = (*inferencev1alpha2.Kind)(&dKind)
|
||||
WithConditions(
|
||||
metav1.ConditionUnknown,
|
||||
string(inferencev1alpha2.InferencePoolConditionAccepted),
|
||||
string(inferencev1alpha2.InferencePoolReasonPending),
|
||||
"Waiting for controller",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func WithConditions(status metav1.ConditionStatus, conType, reason, message string) ParentOption {
|
||||
return func(parentStatusRef *inferencev1alpha2.PoolStatus) {
|
||||
if parentStatusRef.Conditions == nil {
|
||||
parentStatusRef.Conditions = []metav1.Condition{}
|
||||
}
|
||||
parentStatusRef.Conditions = append(parentStatusRef.Conditions,
|
||||
metav1.Condition{
|
||||
Type: conType,
|
||||
Status: status,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
ObservedGeneration: 1,
|
||||
LastTransitionTime: metav1.NewTime(time.Now()),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func WithAcceptedConditions() ParentOption {
|
||||
return func(parentStatusRef *inferencev1alpha2.PoolStatus) {
|
||||
WithConditions(
|
||||
metav1.ConditionTrue,
|
||||
string(inferencev1alpha2.InferencePoolConditionAccepted),
|
||||
string(inferencev1alpha2.InferencePoolReasonAccepted),
|
||||
"Accepted by the parentRef Gateway",
|
||||
)(parentStatusRef)
|
||||
WithConditions(
|
||||
metav1.ConditionTrue,
|
||||
string(inferencev1alpha2.InferencePoolConditionResolvedRefs),
|
||||
string(inferencev1alpha2.InferencePoolReasonResolvedRefs),
|
||||
"Resolved ExtensionRef",
|
||||
)(parentStatusRef)
|
||||
}
|
||||
}
|
||||
|
||||
func WithExtensionRef(kind, name string) Option {
|
||||
return func(obj client.Object) {
|
||||
ip, ok := obj.(*inferencev1alpha2.InferencePool)
|
||||
if ok {
|
||||
typedKind := inferencev1alpha2.Kind(kind)
|
||||
ip.Spec.EndpointPickerConfig.ExtensionRef = &inferencev1alpha2.Extension{
|
||||
ExtensionReference: inferencev1alpha2.ExtensionReference{
|
||||
Name: inferencev1alpha2.ObjectName(name),
|
||||
Kind: &typedKind,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Object Creation Functions ---
|
||||
|
||||
func NewGateway(name string, opts ...Option) *gateway.Gateway {
|
||||
gw := &gateway.Gateway{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: DefaultTestNS,
|
||||
},
|
||||
Spec: gateway.GatewaySpec{
|
||||
GatewayClassName: "istio",
|
||||
},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(gw)
|
||||
}
|
||||
return gw
|
||||
}
|
||||
|
||||
func NewHTTPRoute(name string, opts ...Option) *gateway.HTTPRoute {
|
||||
hr := &gateway.HTTPRoute{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: DefaultTestNS,
|
||||
},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(hr)
|
||||
}
|
||||
return hr
|
||||
}
|
||||
|
||||
func NewInferencePool(name string, opts ...Option) *inferencev1alpha2.InferencePool {
|
||||
ip := &inferencev1alpha2.InferencePool{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: DefaultTestNS,
|
||||
},
|
||||
Spec: inferencev1alpha2.InferencePoolSpec{
|
||||
Selector: map[inferencev1alpha2.LabelKey]inferencev1alpha2.LabelValue{
|
||||
"app": "test",
|
||||
},
|
||||
EndpointPickerConfig: inferencev1alpha2.EndpointPickerConfig{
|
||||
ExtensionRef: &inferencev1alpha2.Extension{
|
||||
ExtensionReference: inferencev1alpha2.ExtensionReference{
|
||||
Name: "endpoint-picker",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(ip)
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
func NewService(name string, opts ...Option) *corev1.Service {
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: DefaultTestNS,
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: []corev1.ServicePort{
|
||||
{
|
||||
Name: "http",
|
||||
Port: 80,
|
||||
TargetPort: intstr.FromInt(9002),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(svc)
|
||||
}
|
||||
return svc
|
||||
}
|
||||
85
pkg/ingress/kube/gateway/istio/inferencepool_test.go
Normal file
85
pkg/ingress/kube/gateway/istio/inferencepool_test.go
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
|
||||
|
||||
higressconstants "github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
"istio.io/istio/pilot/pkg/features"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/test/util/assert"
|
||||
)
|
||||
|
||||
func TestReconcileInferencePool(t *testing.T) {
|
||||
test.SetForTest(t, &features.EnableGatewayAPIInferenceExtension, true)
|
||||
pool := &inferencev1alpha2.InferencePool{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pool",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: inferencev1alpha2.InferencePoolSpec{
|
||||
TargetPortNumber: 8080,
|
||||
Selector: map[inferencev1alpha2.LabelKey]inferencev1alpha2.LabelValue{
|
||||
"app": "test",
|
||||
},
|
||||
EndpointPickerConfig: inferencev1alpha2.EndpointPickerConfig{
|
||||
ExtensionRef: &inferencev1alpha2.Extension{
|
||||
ExtensionReference: inferencev1alpha2.ExtensionReference{
|
||||
Name: "dummy",
|
||||
// Kind: &inferencev1alpha2.Kind(),
|
||||
PortNumber: ptr.Of(inferencev1alpha2.PortNumber(5421)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
controller := setupController(t,
|
||||
&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}},
|
||||
NewGateway("test-gw", InNamespace(DefaultTestNS), WithGatewayClass(higressconstants.DefaultGatewayClass)),
|
||||
NewHTTPRoute("test-route", InNamespace(DefaultTestNS),
|
||||
WithParentRefAndStatus("test-gw", DefaultTestNS, HigressController),
|
||||
WithBackendRef("test-pool", DefaultTestNS),
|
||||
),
|
||||
pool,
|
||||
)
|
||||
|
||||
dumpOnFailure(t, krt.GlobalDebugHandler)
|
||||
|
||||
// Verify the service was created
|
||||
var service *corev1.Service
|
||||
var err error
|
||||
assert.EventuallyEqual(t, func() bool {
|
||||
svcName := "test-pool-ip-" + generateHash("test-pool", hashSize)
|
||||
service, err = controller.client.Kube().CoreV1().Services("default").Get(t.Context(), svcName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Logf("Service %s not found yet: %v", svcName, err)
|
||||
return false
|
||||
}
|
||||
return service != nil
|
||||
}, true)
|
||||
|
||||
assert.Equal(t, service.ObjectMeta.Labels[constants.InternalServiceSemantics], constants.ServiceSemanticsInferencePool)
|
||||
assert.Equal(t, service.ObjectMeta.Labels[InferencePoolRefLabel], pool.Name)
|
||||
assert.Equal(t, service.OwnerReferences[0].Name, pool.Name)
|
||||
assert.Equal(t, service.Spec.Ports[0].TargetPort.IntVal, int32(8080))
|
||||
}
|
||||
@@ -21,6 +21,5 @@ import (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// CheckMain asserts that no goroutines are leaked after a test package exits.
|
||||
leak.CheckMain(m)
|
||||
}
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Updated based on Istio codebase by Higress
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"istio.io/istio/pilot/pkg/credentials"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
creds "istio.io/istio/pilot/pkg/model/credentials"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/util/sets"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
|
||||
"github.com/alibaba/higress/v2/pkg/config/constants"
|
||||
)
|
||||
|
||||
const (
|
||||
// Start - Updated by Higress
|
||||
defaultClassName = constants.DefaultGatewayClass
|
||||
gatewayAliasForAnnotationKey = "gateway.higress.io/alias-for"
|
||||
gatewayTLSTerminateModeKey = "gateway.higress.io/tls-terminate-mode"
|
||||
gatewayNameOverride = "gateway.higress.io/name-override"
|
||||
gatewaySAOverride = "gateway.higress.io/service-account"
|
||||
serviceTypeOverride = "networking.higress.io/service-type"
|
||||
// End - Updated by Higress
|
||||
)
|
||||
|
||||
// GatewayResources stores all gateway resources used for our conversion.
|
||||
type GatewayResources struct {
|
||||
GatewayClass []config.Config
|
||||
Gateway []config.Config
|
||||
HTTPRoute []config.Config
|
||||
TCPRoute []config.Config
|
||||
TLSRoute []config.Config
|
||||
ReferenceGrant []config.Config
|
||||
// Namespaces stores all namespace in the cluster, keyed by name
|
||||
Namespaces map[string]*corev1.Namespace
|
||||
// Credentials stores all credentials in the cluster
|
||||
Credentials credentials.Controller
|
||||
|
||||
// Start - Added by Higress
|
||||
DefaultGatewaySelector map[string]string
|
||||
// End - Added by Higress
|
||||
|
||||
// Domain for the cluster. Typically, cluster.local
|
||||
Domain string
|
||||
Context GatewayContext
|
||||
}
|
||||
|
||||
type Grants struct {
|
||||
AllowAll bool
|
||||
AllowedNames sets.String
|
||||
}
|
||||
|
||||
type AllowedReferences map[Reference]map[Reference]*Grants
|
||||
|
||||
func (refs AllowedReferences) SecretAllowed(resourceName string, namespace string) bool {
|
||||
p, err := creds.ParseResourceName(resourceName, "", "", "")
|
||||
if err != nil {
|
||||
log.Warnf("failed to parse resource name %q: %v", resourceName, err)
|
||||
return false
|
||||
}
|
||||
from := Reference{Kind: gvk.KubernetesGateway, Namespace: k8s.Namespace(namespace)}
|
||||
to := Reference{Kind: gvk.Secret, Namespace: k8s.Namespace(p.Namespace)}
|
||||
allow := refs[from][to]
|
||||
if allow == nil {
|
||||
return false
|
||||
}
|
||||
return allow.AllowAll || allow.AllowedNames.Contains(p.Name)
|
||||
}
|
||||
|
||||
func (refs AllowedReferences) BackendAllowed(
|
||||
k config.GroupVersionKind,
|
||||
backendName k8s.ObjectName,
|
||||
backendNamespace k8s.Namespace,
|
||||
routeNamespace string,
|
||||
) bool {
|
||||
from := Reference{Kind: k, Namespace: k8s.Namespace(routeNamespace)}
|
||||
to := Reference{Kind: gvk.Service, Namespace: backendNamespace}
|
||||
allow := refs[from][to]
|
||||
if allow == nil {
|
||||
return false
|
||||
}
|
||||
return allow.AllowAll || allow.AllowedNames.Contains(string(backendName))
|
||||
}
|
||||
|
||||
// IstioResources stores all outputs of our conversion
|
||||
type IstioResources struct {
|
||||
Gateway []config.Config
|
||||
VirtualService []config.Config
|
||||
// AllowedReferences stores all allowed references, from Reference -> to Reference(s)
|
||||
AllowedReferences AllowedReferences
|
||||
// ReferencedNamespaceKeys stores the label key of all namespace selections. This allows us to quickly
|
||||
// determine if a namespace update could have impacted any Gateways. See namespaceEvent.
|
||||
ReferencedNamespaceKeys sets.String
|
||||
|
||||
// ResourceReferences stores all resources referenced by gateway-api resources. This allows us to quickly
|
||||
// determine if a resource update could have impacted any Gateways.
|
||||
// key: referenced resources(e.g. secrets), value: gateway-api resources(e.g. gateways)
|
||||
ResourceReferences map[model.ConfigKey][]model.ConfigKey
|
||||
}
|
||||
|
||||
// Reference stores a reference to a namespaced GVK, as used by ReferencePolicy
|
||||
type Reference struct {
|
||||
Kind config.GroupVersionKind
|
||||
Namespace k8s.Namespace
|
||||
}
|
||||
74
pkg/ingress/kube/gateway/istio/references.go
Normal file
74
pkg/ingress/kube/gateway/istio/references.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gatewayalpha "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
|
||||
"istio.io/istio/pkg/config"
|
||||
schematypes "istio.io/istio/pkg/config/schema/kubetypes"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
)
|
||||
|
||||
// ReferenceSet stores a variety of different types of resource, and allows looking them up as Gateway API references.
|
||||
// This is merely a convenience to avoid needing to lookup up a bunch of types all over the place.
|
||||
type ReferenceSet struct {
|
||||
erasedCollections map[config.GroupVersionKind]func(name, namespace string) (any, bool)
|
||||
}
|
||||
|
||||
func (s ReferenceSet) LocalPolicyTargetRef(ref gatewayalpha.LocalPolicyTargetReference, localNamespace string) (any, error) {
|
||||
return s.internal(string(ref.Name), string(ref.Group), string(ref.Kind), localNamespace)
|
||||
}
|
||||
|
||||
func (s ReferenceSet) LocalPolicyRef(ref gatewayv1.LocalObjectReference, localNamespace string) (any, error) {
|
||||
return s.internal(string(ref.Name), string(ref.Group), string(ref.Kind), localNamespace)
|
||||
}
|
||||
|
||||
func (s ReferenceSet) internal(name, group, kind, localNamespace string) (any, error) {
|
||||
t := normalizeReference(&group, &kind, config.GroupVersionKind{})
|
||||
lookup, f := s.erasedCollections[t]
|
||||
if !f {
|
||||
return nil, fmt.Errorf("unsupported kind %v", kind)
|
||||
}
|
||||
if v, ok := lookup(name, localNamespace); ok {
|
||||
return v, nil
|
||||
}
|
||||
return nil, fmt.Errorf("reference %v/%v (of kind %v) not found", localNamespace, name, kind)
|
||||
}
|
||||
|
||||
func NewReferenceSet(opts ...func(r *ReferenceSet)) *ReferenceSet {
|
||||
r := &ReferenceSet{erasedCollections: make(map[config.GroupVersionKind]func(name, namespace string) (any, bool))}
|
||||
for _, opt := range opts {
|
||||
opt(r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func AddReference[T runtime.Object](c krt.Collection[T]) func(r *ReferenceSet) {
|
||||
return func(r *ReferenceSet) {
|
||||
g := schematypes.MustGVKFromType[T]()
|
||||
r.erasedCollections[g] = func(name, namespace string) (any, bool) {
|
||||
o := c.GetKey(namespace + "/" + name)
|
||||
if o == nil {
|
||||
return nil, false
|
||||
}
|
||||
return *o, true
|
||||
}
|
||||
}
|
||||
}
|
||||
159
pkg/ingress/kube/gateway/istio/references_collection.go
Normal file
159
pkg/ingress/kube/gateway/istio/references_collection.go
Normal file
@@ -0,0 +1,159 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
creds "istio.io/istio/pilot/pkg/model/credentials"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
)
|
||||
|
||||
// Reference stores a reference to a namespaced GVK, as used by ReferenceGrant
|
||||
type Reference struct {
|
||||
Kind config.GroupVersionKind
|
||||
Namespace gateway.Namespace
|
||||
}
|
||||
|
||||
func (refs Reference) String() string {
|
||||
return refs.Kind.String() + "/" + string(refs.Namespace)
|
||||
}
|
||||
|
||||
type ReferencePair struct {
|
||||
To, From Reference
|
||||
}
|
||||
|
||||
func (r ReferencePair) String() string {
|
||||
return fmt.Sprintf("%s->%s", r.From, r.To)
|
||||
}
|
||||
|
||||
type ReferenceGrants struct {
|
||||
collection krt.Collection[ReferenceGrant]
|
||||
index krt.Index[ReferencePair, ReferenceGrant]
|
||||
}
|
||||
|
||||
func ReferenceGrantsCollection(referenceGrants krt.Collection[*gateway.ReferenceGrant], opts krt.OptionsBuilder) krt.Collection[ReferenceGrant] {
|
||||
return krt.NewManyCollection(referenceGrants, func(ctx krt.HandlerContext, obj *gateway.ReferenceGrant) []ReferenceGrant {
|
||||
rp := obj.Spec
|
||||
results := make([]ReferenceGrant, 0, len(rp.From)*len(rp.To))
|
||||
for _, from := range rp.From {
|
||||
fromKey := Reference{
|
||||
Namespace: from.Namespace,
|
||||
}
|
||||
ref := normalizeReference(&from.Group, &from.Kind, config.GroupVersionKind{})
|
||||
switch ref {
|
||||
case gvk.KubernetesGateway, gvk.HTTPRoute, gvk.GRPCRoute, gvk.TLSRoute, gvk.TCPRoute, gvk.XListenerSet:
|
||||
fromKey.Kind = ref
|
||||
default:
|
||||
// Not supported type. Not an error; may be for another controller
|
||||
continue
|
||||
}
|
||||
for _, to := range rp.To {
|
||||
toKey := Reference{
|
||||
Namespace: gateway.Namespace(obj.Namespace),
|
||||
}
|
||||
|
||||
ref := normalizeReference(&to.Group, &to.Kind, config.GroupVersionKind{})
|
||||
switch ref {
|
||||
case gvk.Secret, gvk.Service, gvk.InferencePool:
|
||||
toKey.Kind = ref
|
||||
default:
|
||||
continue
|
||||
}
|
||||
rg := ReferenceGrant{
|
||||
Source: config.NamespacedName(obj),
|
||||
From: fromKey,
|
||||
To: toKey,
|
||||
AllowAll: false,
|
||||
AllowedName: "",
|
||||
}
|
||||
if to.Name != nil {
|
||||
rg.AllowedName = string(*to.Name)
|
||||
} else {
|
||||
rg.AllowAll = true
|
||||
}
|
||||
results = append(results, rg)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}, opts.WithName("ReferenceGrants")...)
|
||||
}
|
||||
|
||||
func BuildReferenceGrants(collection krt.Collection[ReferenceGrant]) ReferenceGrants {
|
||||
idx := krt.NewIndex(collection, "toFrom", func(o ReferenceGrant) []ReferencePair {
|
||||
return []ReferencePair{{
|
||||
To: o.To,
|
||||
From: o.From,
|
||||
}}
|
||||
})
|
||||
return ReferenceGrants{
|
||||
collection: collection,
|
||||
index: idx,
|
||||
}
|
||||
}
|
||||
|
||||
type ReferenceGrant struct {
|
||||
Source types.NamespacedName
|
||||
From Reference
|
||||
To Reference
|
||||
AllowAll bool
|
||||
AllowedName string
|
||||
}
|
||||
|
||||
func (g ReferenceGrant) ResourceName() string {
|
||||
return g.Source.String() + "/" + g.From.String() + "/" + g.To.String()
|
||||
}
|
||||
|
||||
func (refs ReferenceGrants) SecretAllowed(ctx krt.HandlerContext, kind config.GroupVersionKind, resourceName string, namespace string) bool {
|
||||
p, err := creds.ParseResourceName(resourceName, "", "", "")
|
||||
if err != nil {
|
||||
log.Warnf("failed to parse resource name %q: %v", resourceName, err)
|
||||
return false
|
||||
}
|
||||
from := Reference{Kind: kind, Namespace: gateway.Namespace(namespace)}
|
||||
to := Reference{Kind: gvk.Secret, Namespace: gateway.Namespace(p.Namespace)}
|
||||
pair := ReferencePair{From: from, To: to}
|
||||
grants := krt.FetchOrList(ctx, refs.collection, krt.FilterIndex(refs.index, pair))
|
||||
for _, g := range grants {
|
||||
if g.AllowAll || g.AllowedName == p.Name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (refs ReferenceGrants) BackendAllowed(ctx krt.HandlerContext,
|
||||
k config.GroupVersionKind,
|
||||
toGVK config.GroupVersionKind,
|
||||
backendName gateway.ObjectName,
|
||||
backendNamespace gateway.Namespace,
|
||||
routeNamespace string,
|
||||
) bool {
|
||||
from := Reference{Kind: k, Namespace: gateway.Namespace(routeNamespace)}
|
||||
to := Reference{Kind: toGVK, Namespace: backendNamespace}
|
||||
pair := ReferencePair{From: from, To: to}
|
||||
grants := krt.Fetch(ctx, refs.collection, krt.FilterIndex(refs.index, pair))
|
||||
for _, g := range grants {
|
||||
if g.AllowAll || g.AllowedName == string(backendName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
697
pkg/ingress/kube/gateway/istio/route_collections.go
Normal file
697
pkg/ingress/kube/gateway/istio/route_collections.go
Normal file
@@ -0,0 +1,697 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"iter"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
|
||||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
|
||||
gatewayalpha "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
|
||||
|
||||
istio "istio.io/api/networking/v1alpha3"
|
||||
networkingclient "istio.io/client-go/pkg/apis/networking/v1"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pkg/config"
|
||||
"istio.io/istio/pkg/config/constants"
|
||||
"istio.io/istio/pkg/config/gateway/kube"
|
||||
"istio.io/istio/pkg/config/schema/gvk"
|
||||
"istio.io/istio/pkg/kube/controllers"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/ptr"
|
||||
"istio.io/istio/pkg/slices"
|
||||
)
|
||||
|
||||
func HTTPRouteCollection(
|
||||
httpRoutes krt.Collection[*gateway.HTTPRoute],
|
||||
inputs RouteContextInputs,
|
||||
opts krt.OptionsBuilder,
|
||||
) RouteResult[*gateway.HTTPRoute, gateway.HTTPRouteStatus] {
|
||||
routeCount := gatewayRouteAttachmentCountCollection(inputs, httpRoutes, gvk.HTTPRoute, opts)
|
||||
status, baseVirtualServices := krt.NewStatusManyCollection(httpRoutes, func(krtctx krt.HandlerContext, obj *gateway.HTTPRoute) (
|
||||
*gateway.HTTPRouteStatus,
|
||||
[]RouteWithKey,
|
||||
) {
|
||||
ctx := inputs.WithCtx(krtctx)
|
||||
inferencePoolCfgPairs := []struct {
|
||||
name string
|
||||
cfg *inferencePoolConfig
|
||||
}{}
|
||||
status := obj.Status.DeepCopy()
|
||||
route := obj.Spec
|
||||
parentStatus, parentRefs, meshResult, gwResult := computeRoute(ctx, obj, func(mesh bool, obj *gateway.HTTPRoute) iter.Seq2[*istio.HTTPRoute, *ConfigError] {
|
||||
return func(yield func(*istio.HTTPRoute, *ConfigError) bool) {
|
||||
for n, r := range route.Rules {
|
||||
// split the rule to make sure each rule has up to one match
|
||||
matches := slices.Reference(r.Matches)
|
||||
if len(matches) == 0 {
|
||||
matches = append(matches, nil)
|
||||
}
|
||||
for _, m := range matches {
|
||||
if m != nil {
|
||||
r.Matches = []gateway.HTTPRouteMatch{*m}
|
||||
}
|
||||
istioRoute, ipCfg, configErr := convertHTTPRoute(ctx, r, obj, n, !mesh)
|
||||
if istioRoute != nil && ipCfg != nil && ipCfg.enableExtProc {
|
||||
inferencePoolCfgPairs = append(inferencePoolCfgPairs, struct {
|
||||
name string
|
||||
cfg *inferencePoolConfig
|
||||
}{name: istioRoute.Name, cfg: ipCfg})
|
||||
}
|
||||
if !yield(istioRoute, configErr) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// routeRuleToInferencePoolCfg stores inference pool configs discovered during route rule conversion,
|
||||
// keyed by the istio.HTTPRoute.Name.
|
||||
routeRuleToInferencePoolCfg := make(map[string]*inferencePoolConfig)
|
||||
for _, pair := range inferencePoolCfgPairs {
|
||||
routeRuleToInferencePoolCfg[pair.name] = pair.cfg
|
||||
}
|
||||
status.Parents = parentStatus
|
||||
|
||||
count := 0
|
||||
virtualServices := []RouteWithKey{}
|
||||
for _, parent := range filteredReferences(parentRefs) {
|
||||
// for gateway routes, build one VS per gateway+host
|
||||
routeKey := parent.InternalName
|
||||
vsHosts := hostnameToStringList(route.Hostnames)
|
||||
routes := gwResult.routes
|
||||
if parent.IsMesh() {
|
||||
routes = meshResult.routes
|
||||
// for mesh routes, build one VS per namespace/port->host
|
||||
routeKey = obj.Namespace
|
||||
if parent.OriginalReference.Port != nil {
|
||||
routes = augmentPortMatch(routes, *parent.OriginalReference.Port)
|
||||
routeKey += fmt.Sprintf("/%d", *parent.OriginalReference.Port)
|
||||
}
|
||||
ref := types.NamespacedName{
|
||||
Namespace: string(ptr.OrDefault(parent.OriginalReference.Namespace, gateway.Namespace(obj.Namespace))),
|
||||
Name: string(parent.OriginalReference.Name),
|
||||
}
|
||||
if parent.InternalKind == gvk.ServiceEntry {
|
||||
ses := ptr.Flatten(krt.FetchOne(ctx.Krt, ctx.ServiceEntries, krt.FilterKey(ref.String())))
|
||||
if ses != nil {
|
||||
vsHosts = ses.Spec.Hosts
|
||||
} else {
|
||||
// TODO: report an error
|
||||
vsHosts = []string{}
|
||||
}
|
||||
} else {
|
||||
vsHosts = []string{fmt.Sprintf("%s.%s.svc.%s",
|
||||
parent.OriginalReference.Name, ptr.OrDefault(parent.OriginalReference.Namespace, gateway.Namespace(obj.Namespace)), ctx.DomainSuffix)}
|
||||
}
|
||||
}
|
||||
if len(routes) == 0 {
|
||||
continue
|
||||
}
|
||||
// Create one VS per hostname with a single hostname.
|
||||
// This ensures we can treat each hostname independently, as the spec requires
|
||||
for _, h := range vsHosts {
|
||||
if !parent.hostnameAllowedByIsolation(h) {
|
||||
// TODO: standardize a status message for this upstream and report
|
||||
continue
|
||||
}
|
||||
name := fmt.Sprintf("%s-%d-%s", obj.Name, count, constants.KubernetesGatewayName)
|
||||
sortHTTPRoutes(routes)
|
||||
|
||||
// Populate Extra field for inference pool configs
|
||||
extraData := make(map[string]any)
|
||||
currentRouteInferenceConfigs := make(map[string]kube.InferencePoolRouteRuleConfig)
|
||||
for _, httpRule := range routes { // These are []*istio.HTTPRoute
|
||||
if ipCfg, found := routeRuleToInferencePoolCfg[httpRule.Name]; found {
|
||||
currentRouteInferenceConfigs[httpRule.Name] = kube.InferencePoolRouteRuleConfig{
|
||||
FQDN: ipCfg.endpointPickerDst,
|
||||
Port: ipCfg.endpointPickerPort,
|
||||
FailureModeAllow: ipCfg.endpointPickerFailureMode == string(inferencev1alpha2.FailOpen),
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(currentRouteInferenceConfigs) > 0 {
|
||||
extraData[constants.ConfigExtraPerRouteRuleInferencePoolConfigs] = currentRouteInferenceConfigs
|
||||
}
|
||||
|
||||
cfg := &config.Config{
|
||||
Meta: config.Meta{
|
||||
CreationTimestamp: obj.CreationTimestamp.Time,
|
||||
GroupVersionKind: gvk.VirtualService,
|
||||
Name: name,
|
||||
Annotations: routeMeta(obj),
|
||||
Namespace: obj.Namespace,
|
||||
Domain: ctx.DomainSuffix,
|
||||
},
|
||||
Spec: &istio.VirtualService{
|
||||
Hosts: []string{h},
|
||||
Gateways: []string{parent.InternalName},
|
||||
Http: routes,
|
||||
},
|
||||
Extra: extraData,
|
||||
}
|
||||
virtualServices = append(virtualServices, RouteWithKey{
|
||||
Config: cfg,
|
||||
Key: routeKey + "/" + h,
|
||||
})
|
||||
count++
|
||||
}
|
||||
}
|
||||
return status, virtualServices
|
||||
}, opts.WithName("HTTPRoute")...)
|
||||
|
||||
finalVirtualServices := mergeHTTPRoutes(baseVirtualServices, opts.WithName("HTTPRouteMerged")...)
|
||||
return RouteResult[*gateway.HTTPRoute, gateway.HTTPRouteStatus]{
|
||||
VirtualServices: finalVirtualServices,
|
||||
RouteAttachments: routeCount,
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
||||
type conversionResult[O any] struct {
|
||||
error *ConfigError
|
||||
routes []O
|
||||
}
|
||||
|
||||
func GRPCRouteCollection(
|
||||
grpcRoutes krt.Collection[*gatewayv1.GRPCRoute],
|
||||
inputs RouteContextInputs,
|
||||
opts krt.OptionsBuilder,
|
||||
) RouteResult[*gatewayv1.GRPCRoute, gatewayv1.GRPCRouteStatus] {
|
||||
routeCount := gatewayRouteAttachmentCountCollection(inputs, grpcRoutes, gvk.GRPCRoute, opts)
|
||||
status, baseVirtualServices := krt.NewStatusManyCollection(grpcRoutes, func(krtctx krt.HandlerContext, obj *gatewayv1.GRPCRoute) (
|
||||
*gatewayv1.GRPCRouteStatus,
|
||||
[]RouteWithKey,
|
||||
) {
|
||||
ctx := inputs.WithCtx(krtctx)
|
||||
// routeRuleToInferencePoolCfg stores inference pool configs discovered during route rule conversion.
|
||||
// Note: GRPCRoute currently doesn't have inference pool logic, but adding for consistency.
|
||||
routeRuleToInferencePoolCfg := make(map[string]*inferencePoolConfig)
|
||||
status := obj.Status.DeepCopy()
|
||||
route := obj.Spec
|
||||
parentStatus, parentRefs, meshResult, gwResult := computeRoute(ctx, obj, func(mesh bool, obj *gatewayv1.GRPCRoute) iter.Seq2[*istio.HTTPRoute, *ConfigError] {
|
||||
return func(yield func(*istio.HTTPRoute, *ConfigError) bool) {
|
||||
for n, r := range route.Rules {
|
||||
// split the rule to make sure each rule has up to one match
|
||||
matches := slices.Reference(r.Matches)
|
||||
if len(matches) == 0 {
|
||||
matches = append(matches, nil)
|
||||
}
|
||||
for _, m := range matches {
|
||||
if m != nil {
|
||||
r.Matches = []gatewayv1.GRPCRouteMatch{*m}
|
||||
}
|
||||
// GRPCRoute conversion currently doesn't return ipCfg.
|
||||
istioRoute, configErr := convertGRPCRoute(ctx, r, obj, n, !mesh)
|
||||
// Placeholder if GRPCRoute ever supports inference pools via ipCfg:
|
||||
// if istioRoute != nil && ipCfg != nil && ipCfg.enableExtProc {
|
||||
// routeRuleToInferencePoolCfg[istioRoute.Name] = ipCfg
|
||||
// }
|
||||
if !yield(istioRoute, configErr) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
status.Parents = parentStatus
|
||||
|
||||
count := 0
|
||||
virtualServices := []RouteWithKey{}
|
||||
for _, parent := range filteredReferences(parentRefs) {
|
||||
// for gateway routes, build one VS per gateway+host
|
||||
routeKey := parent.InternalName
|
||||
vsHosts := hostnameToStringList(route.Hostnames)
|
||||
routes := gwResult.routes
|
||||
if parent.IsMesh() {
|
||||
routes = meshResult.routes
|
||||
// for mesh routes, build one VS per namespace/port->host
|
||||
routeKey = obj.Namespace
|
||||
if parent.OriginalReference.Port != nil {
|
||||
routes = augmentPortMatch(routes, *parent.OriginalReference.Port)
|
||||
routeKey += fmt.Sprintf("/%d", *parent.OriginalReference.Port)
|
||||
}
|
||||
ref := types.NamespacedName{
|
||||
Namespace: string(ptr.OrDefault(parent.OriginalReference.Namespace, gateway.Namespace(obj.Namespace))),
|
||||
Name: string(parent.OriginalReference.Name),
|
||||
}
|
||||
if parent.InternalKind == gvk.ServiceEntry {
|
||||
ses := ptr.Flatten(krt.FetchOne(ctx.Krt, ctx.ServiceEntries, krt.FilterKey(ref.String())))
|
||||
if ses != nil {
|
||||
vsHosts = ses.Spec.Hosts
|
||||
} else {
|
||||
// TODO: report an error
|
||||
vsHosts = []string{}
|
||||
}
|
||||
} else {
|
||||
vsHosts = []string{fmt.Sprintf("%s.%s.svc.%s",
|
||||
parent.OriginalReference.Name, ptr.OrDefault(parent.OriginalReference.Namespace, gateway.Namespace(obj.Namespace)), ctx.DomainSuffix)}
|
||||
}
|
||||
}
|
||||
if len(routes) == 0 {
|
||||
continue
|
||||
}
|
||||
// Create one VS per hostname with a single hostname.
|
||||
// This ensures we can treat each hostname independently, as the spec requires
|
||||
for _, h := range vsHosts {
|
||||
if !parent.hostnameAllowedByIsolation(h) {
|
||||
// TODO: standardize a status message for this upstream and report
|
||||
continue
|
||||
}
|
||||
name := fmt.Sprintf("%s-%d-%s", obj.Name, count, constants.KubernetesGatewayName)
|
||||
sortHTTPRoutes(routes)
|
||||
|
||||
// Populate Extra field for inference pool configs (if GRPCRoute supports them)
|
||||
extraData := make(map[string]any)
|
||||
currentRouteInferenceConfigs := make(map[string]kube.InferencePoolRouteRuleConfig)
|
||||
for _, httpRule := range routes {
|
||||
if ipCfg, found := routeRuleToInferencePoolCfg[httpRule.Name]; found { // This map will be empty for GRPCRoute for now
|
||||
currentRouteInferenceConfigs[httpRule.Name] = kube.InferencePoolRouteRuleConfig{
|
||||
FQDN: ipCfg.endpointPickerDst,
|
||||
Port: ipCfg.endpointPickerPort,
|
||||
FailureModeAllow: ipCfg.endpointPickerFailureMode == string(inferencev1alpha2.FailOpen),
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(currentRouteInferenceConfigs) > 0 {
|
||||
extraData[constants.ConfigExtraPerRouteRuleInferencePoolConfigs] = currentRouteInferenceConfigs
|
||||
}
|
||||
|
||||
cfg := &config.Config{
|
||||
Meta: config.Meta{
|
||||
CreationTimestamp: obj.CreationTimestamp.Time,
|
||||
GroupVersionKind: gvk.VirtualService,
|
||||
Name: name,
|
||||
Annotations: routeMeta(obj),
|
||||
Namespace: obj.Namespace,
|
||||
Domain: ctx.DomainSuffix,
|
||||
},
|
||||
Spec: &istio.VirtualService{
|
||||
Hosts: []string{h},
|
||||
Gateways: []string{parent.InternalName},
|
||||
Http: routes,
|
||||
},
|
||||
Extra: extraData,
|
||||
}
|
||||
virtualServices = append(virtualServices, RouteWithKey{
|
||||
Config: cfg,
|
||||
Key: routeKey + "/" + h,
|
||||
})
|
||||
count++
|
||||
}
|
||||
}
|
||||
return status, virtualServices
|
||||
}, opts.WithName("GRPCRoute")...)
|
||||
|
||||
finalVirtualServices := mergeHTTPRoutes(baseVirtualServices, opts.WithName("GRPCRouteMerged")...)
|
||||
return RouteResult[*gatewayv1.GRPCRoute, gatewayv1.GRPCRouteStatus]{
|
||||
VirtualServices: finalVirtualServices,
|
||||
RouteAttachments: routeCount,
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
||||
func TCPRouteCollection(
|
||||
tcpRoutes krt.Collection[*gatewayalpha.TCPRoute],
|
||||
inputs RouteContextInputs,
|
||||
opts krt.OptionsBuilder,
|
||||
) RouteResult[*gatewayalpha.TCPRoute, gatewayalpha.TCPRouteStatus] {
|
||||
routeCount := gatewayRouteAttachmentCountCollection(inputs, tcpRoutes, gvk.TCPRoute, opts)
|
||||
status, virtualServices := krt.NewStatusManyCollection(tcpRoutes, func(krtctx krt.HandlerContext, obj *gatewayalpha.TCPRoute) (
|
||||
*gatewayalpha.TCPRouteStatus,
|
||||
[]*config.Config,
|
||||
) {
|
||||
ctx := inputs.WithCtx(krtctx)
|
||||
status := obj.Status.DeepCopy()
|
||||
route := obj.Spec
|
||||
parentStatus, parentRefs, meshResult, gwResult := computeRoute(ctx, obj,
|
||||
func(mesh bool, obj *gatewayalpha.TCPRoute) iter.Seq2[*istio.TCPRoute, *ConfigError] {
|
||||
return func(yield func(*istio.TCPRoute, *ConfigError) bool) {
|
||||
for _, r := range route.Rules {
|
||||
if !yield(convertTCPRoute(ctx, r, obj, !mesh)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
status.Parents = parentStatus
|
||||
|
||||
vs := []*config.Config{}
|
||||
count := 0
|
||||
for _, parent := range filteredReferences(parentRefs) {
|
||||
routes := gwResult.routes
|
||||
vsHosts := []string{"*"}
|
||||
if parent.IsMesh() {
|
||||
routes = meshResult.routes
|
||||
if parent.OriginalReference.Port != nil {
|
||||
routes = augmentTCPPortMatch(routes, *parent.OriginalReference.Port)
|
||||
}
|
||||
ref := types.NamespacedName{
|
||||
Namespace: string(ptr.OrDefault(parent.OriginalReference.Namespace, gateway.Namespace(obj.Namespace))),
|
||||
Name: string(parent.OriginalReference.Name),
|
||||
}
|
||||
if parent.InternalKind == gvk.ServiceEntry {
|
||||
ses := ptr.Flatten(krt.FetchOne(ctx.Krt, ctx.ServiceEntries, krt.FilterKey(ref.String())))
|
||||
if ses != nil {
|
||||
vsHosts = ses.Spec.Hosts
|
||||
} else {
|
||||
// TODO: report an error
|
||||
vsHosts = []string{}
|
||||
}
|
||||
} else {
|
||||
vsHosts = []string{fmt.Sprintf("%s.%s.svc.%s", ref.Name, ref.Namespace, ctx.DomainSuffix)}
|
||||
}
|
||||
}
|
||||
for _, host := range vsHosts {
|
||||
name := fmt.Sprintf("%s-tcp-%d-%s", obj.Name, count, constants.KubernetesGatewayName)
|
||||
// Create one VS per hostname with a single hostname.
|
||||
// This ensures we can treat each hostname independently, as the spec requires
|
||||
vs = append(vs, &config.Config{
|
||||
Meta: config.Meta{
|
||||
CreationTimestamp: obj.CreationTimestamp.Time,
|
||||
GroupVersionKind: gvk.VirtualService,
|
||||
Name: name,
|
||||
Annotations: routeMeta(obj),
|
||||
Namespace: obj.Namespace,
|
||||
Domain: ctx.DomainSuffix,
|
||||
},
|
||||
Spec: &istio.VirtualService{
|
||||
// We can use wildcard here since each listener can have at most one route bound to it, so we have
|
||||
// a single VS per Gateway.
|
||||
Hosts: []string{host},
|
||||
Gateways: []string{parent.InternalName},
|
||||
Tcp: routes,
|
||||
},
|
||||
})
|
||||
count++
|
||||
}
|
||||
}
|
||||
return status, vs
|
||||
}, opts.WithName("TCPRoute")...)
|
||||
|
||||
return RouteResult[*gatewayalpha.TCPRoute, gatewayalpha.TCPRouteStatus]{
|
||||
VirtualServices: virtualServices,
|
||||
RouteAttachments: routeCount,
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
||||
func TLSRouteCollection(
|
||||
tlsRoutes krt.Collection[*gatewayalpha.TLSRoute],
|
||||
inputs RouteContextInputs,
|
||||
opts krt.OptionsBuilder,
|
||||
) RouteResult[*gatewayalpha.TLSRoute, gatewayalpha.TLSRouteStatus] {
|
||||
routeCount := gatewayRouteAttachmentCountCollection(inputs, tlsRoutes, gvk.TLSRoute, opts)
|
||||
status, virtualServices := krt.NewStatusManyCollection(tlsRoutes, func(krtctx krt.HandlerContext, obj *gatewayalpha.TLSRoute) (
|
||||
*gatewayalpha.TLSRouteStatus,
|
||||
[]*config.Config,
|
||||
) {
|
||||
ctx := inputs.WithCtx(krtctx)
|
||||
status := obj.Status.DeepCopy()
|
||||
route := obj.Spec
|
||||
parentStatus, parentRefs, meshResult, gwResult := computeRoute(ctx,
|
||||
obj, func(mesh bool, obj *gatewayalpha.TLSRoute) iter.Seq2[*istio.TLSRoute, *ConfigError] {
|
||||
return func(yield func(*istio.TLSRoute, *ConfigError) bool) {
|
||||
for _, r := range route.Rules {
|
||||
if !yield(convertTLSRoute(ctx, r, obj, !mesh)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
status.Parents = parentStatus
|
||||
|
||||
count := 0
|
||||
vs := []*config.Config{}
|
||||
for _, parent := range filteredReferences(parentRefs) {
|
||||
routes := gwResult.routes
|
||||
vsHosts := hostnameToStringList(route.Hostnames)
|
||||
if parent.IsMesh() {
|
||||
routes = meshResult.routes
|
||||
ref := types.NamespacedName{
|
||||
Namespace: string(ptr.OrDefault(parent.OriginalReference.Namespace, gateway.Namespace(obj.Namespace))),
|
||||
Name: string(parent.OriginalReference.Name),
|
||||
}
|
||||
if parent.InternalKind == gvk.ServiceEntry {
|
||||
ses := ptr.Flatten(krt.FetchOne(ctx.Krt, ctx.ServiceEntries, krt.FilterKey(ref.String())))
|
||||
if ses != nil {
|
||||
vsHosts = ses.Spec.Hosts
|
||||
} else {
|
||||
// TODO: report an error
|
||||
vsHosts = []string{}
|
||||
}
|
||||
} else {
|
||||
vsHosts = []string{fmt.Sprintf("%s.%s.svc.%s", ref.Name, ref.Namespace, ctx.DomainSuffix)}
|
||||
}
|
||||
routes = augmentTLSPortMatch(routes, parent.OriginalReference.Port, vsHosts)
|
||||
}
|
||||
for _, host := range vsHosts {
|
||||
name := fmt.Sprintf("%s-tls-%d-%s", obj.Name, count, constants.KubernetesGatewayName)
|
||||
filteredRoutes := routes
|
||||
if parent.IsMesh() {
|
||||
filteredRoutes = compatibleRoutesForHost(routes, host)
|
||||
}
|
||||
// Create one VS per hostname with a single hostname.
|
||||
// This ensures we can treat each hostname independently, as the spec requires
|
||||
vs = append(vs, &config.Config{
|
||||
Meta: config.Meta{
|
||||
CreationTimestamp: obj.CreationTimestamp.Time,
|
||||
GroupVersionKind: gvk.VirtualService,
|
||||
Name: name,
|
||||
Annotations: routeMeta(obj),
|
||||
Namespace: obj.Namespace,
|
||||
Domain: ctx.DomainSuffix,
|
||||
},
|
||||
Spec: &istio.VirtualService{
|
||||
Hosts: []string{host},
|
||||
Gateways: []string{parent.InternalName},
|
||||
Tls: filteredRoutes,
|
||||
},
|
||||
})
|
||||
count++
|
||||
}
|
||||
}
|
||||
return status, vs
|
||||
}, opts.WithName("TLSRoute")...)
|
||||
return RouteResult[*gatewayalpha.TLSRoute, gatewayalpha.TLSRouteStatus]{
|
||||
VirtualServices: virtualServices,
|
||||
RouteAttachments: routeCount,
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
||||
// computeRoute holds the common route building logic shared amongst all types
|
||||
func computeRoute[T controllers.Object, O comparable](ctx RouteContext, obj T, translator func(
|
||||
mesh bool,
|
||||
obj T,
|
||||
) iter.Seq2[O, *ConfigError],
|
||||
) ([]gateway.RouteParentStatus, []routeParentReference, conversionResult[O], conversionResult[O]) {
|
||||
parentRefs := extractParentReferenceInfo(ctx, ctx.RouteParents, obj)
|
||||
|
||||
convertRules := func(mesh bool) conversionResult[O] {
|
||||
res := conversionResult[O]{}
|
||||
for vs, err := range translator(mesh, obj) {
|
||||
// This was a hard error
|
||||
if controllers.IsNil(vs) {
|
||||
res.error = err
|
||||
return conversionResult[O]{error: err}
|
||||
}
|
||||
// Got an error but also routes
|
||||
if err != nil {
|
||||
res.error = err
|
||||
}
|
||||
res.routes = append(res.routes, vs)
|
||||
}
|
||||
return res
|
||||
}
|
||||
meshResult, gwResult := buildMeshAndGatewayRoutes(parentRefs, convertRules)
|
||||
|
||||
rpResults := slices.Map(parentRefs, func(r routeParentReference) RouteParentResult {
|
||||
res := RouteParentResult{
|
||||
OriginalReference: r.OriginalReference,
|
||||
DeniedReason: r.DeniedReason,
|
||||
RouteError: gwResult.error,
|
||||
}
|
||||
if r.IsMesh() {
|
||||
res.RouteError = meshResult.error
|
||||
res.WaypointError = r.WaypointError
|
||||
}
|
||||
return res
|
||||
})
|
||||
parents := createRouteStatus(rpResults, obj.GetNamespace(), obj.GetGeneration(), GetCommonRouteStateParents(obj))
|
||||
return parents, parentRefs, meshResult, gwResult
|
||||
}
|
||||
|
||||
// RouteContext defines a common set of inputs to a route collection. This should be built once per route translation and
|
||||
// not shared outside of that.
|
||||
// The embedded RouteContextInputs is typically based into a collection, then translated to a RouteContext with RouteContextInputs.WithCtx().
|
||||
type RouteContext struct {
|
||||
Krt krt.HandlerContext
|
||||
RouteContextInputs
|
||||
}
|
||||
|
||||
func (r RouteContext) LookupHostname(hostname string, namespace string, kind string) *model.Service {
|
||||
if c := r.internalContext.Get(r.Krt).Load(); c != nil {
|
||||
return c.GetService(hostname, namespace, kind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RouteContextInputs struct {
|
||||
Grants ReferenceGrants
|
||||
RouteParents RouteParents
|
||||
DomainSuffix string
|
||||
Services krt.Collection[*corev1.Service]
|
||||
Namespaces krt.Collection[*corev1.Namespace]
|
||||
ServiceEntries krt.Collection[*networkingclient.ServiceEntry]
|
||||
InferencePools krt.Collection[*inferencev1alpha2.InferencePool]
|
||||
internalContext krt.RecomputeProtected[*atomic.Pointer[GatewayContext]]
|
||||
}
|
||||
|
||||
func (i RouteContextInputs) WithCtx(krtctx krt.HandlerContext) RouteContext {
|
||||
return RouteContext{
|
||||
Krt: krtctx,
|
||||
RouteContextInputs: i,
|
||||
}
|
||||
}
|
||||
|
||||
type RouteWithKey struct {
|
||||
*config.Config
|
||||
Key string
|
||||
}
|
||||
|
||||
func (r RouteWithKey) ResourceName() string {
|
||||
return config.NamespacedName(r.Config).String()
|
||||
}
|
||||
|
||||
func (r RouteWithKey) Equals(o RouteWithKey) bool {
|
||||
return r.Config.Equals(o.Config)
|
||||
}
|
||||
|
||||
// buildMeshAndGatewayRoutes contains common logic to build a set of routes with mesh and/or gateway semantics
|
||||
func buildMeshAndGatewayRoutes[T any](parentRefs []routeParentReference, convertRules func(mesh bool) T) (T, T) {
|
||||
var meshResult, gwResult T
|
||||
needMesh, needGw := parentTypes(parentRefs)
|
||||
if needMesh {
|
||||
meshResult = convertRules(true)
|
||||
}
|
||||
if needGw {
|
||||
gwResult = convertRules(false)
|
||||
}
|
||||
return meshResult, gwResult
|
||||
}
|
||||
|
||||
// RouteResult holds the result of a route collection
|
||||
type RouteResult[I controllers.Object, IStatus any] struct {
|
||||
// VirtualServices are the primary output that configures the internal routing logic
|
||||
VirtualServices krt.Collection[*config.Config]
|
||||
// RouteAttachments holds information about parent attachment to routes, used for computed the `attachedRoutes` count.
|
||||
RouteAttachments krt.Collection[RouteAttachment]
|
||||
// Status stores the status reports for the incoming object
|
||||
Status krt.StatusCollection[I, IStatus]
|
||||
}
|
||||
|
||||
type RouteAttachment struct {
|
||||
From TypedResource
|
||||
// To is assumed to be a Gateway
|
||||
To types.NamespacedName
|
||||
ListenerName string
|
||||
}
|
||||
|
||||
func (r RouteAttachment) ResourceName() string {
|
||||
return r.From.Kind.String() + "/" + r.From.Name.String() + "/" + r.To.String() + "/" + r.ListenerName
|
||||
}
|
||||
|
||||
func (r RouteAttachment) Equals(other RouteAttachment) bool {
|
||||
return r.From == other.From && r.To == other.To && r.ListenerName == other.ListenerName
|
||||
}
|
||||
|
||||
// gatewayRouteAttachmentCountCollection holds the generic logic to determine the parents a route is attached to, used for
|
||||
// computing the aggregated `attachedRoutes` status in Gateway.
|
||||
func gatewayRouteAttachmentCountCollection[T controllers.Object](
|
||||
inputs RouteContextInputs,
|
||||
col krt.Collection[T],
|
||||
kind config.GroupVersionKind,
|
||||
opts krt.OptionsBuilder,
|
||||
) krt.Collection[RouteAttachment] {
|
||||
return krt.NewManyCollection(col, func(krtctx krt.HandlerContext, obj T) []RouteAttachment {
|
||||
ctx := inputs.WithCtx(krtctx)
|
||||
from := TypedResource{
|
||||
Kind: kind,
|
||||
Name: config.NamespacedName(obj),
|
||||
}
|
||||
|
||||
parentRefs := extractParentReferenceInfo(ctx, inputs.RouteParents, obj)
|
||||
return slices.MapFilter(filteredReferences(parentRefs), func(e routeParentReference) *RouteAttachment {
|
||||
if e.ParentKey.Kind != gvk.KubernetesGateway {
|
||||
return nil
|
||||
}
|
||||
return &RouteAttachment{
|
||||
From: from,
|
||||
To: types.NamespacedName{
|
||||
Name: e.ParentKey.Name,
|
||||
Namespace: e.ParentKey.Namespace,
|
||||
},
|
||||
ListenerName: string(e.ParentSection),
|
||||
}
|
||||
})
|
||||
}, opts.WithName(kind.Kind+"/count")...)
|
||||
}
|
||||
|
||||
// mergeHTTPRoutes merges HTTProutes by key. Gateway API has semantics for the ordering of `match` rules, that merges across resource.
|
||||
// So we merge everything (by key) following that ordering logic, and sort into a linear list (how VirtualService semantics work).
|
||||
func mergeHTTPRoutes(baseVirtualServices krt.Collection[RouteWithKey], opts ...krt.CollectionOption) krt.Collection[*config.Config] {
|
||||
idx := krt.NewIndex(baseVirtualServices, "key", func(o RouteWithKey) []string {
|
||||
return []string{o.Key}
|
||||
}).AsCollection(opts...)
|
||||
finalVirtualServices := krt.NewCollection(idx, func(ctx krt.HandlerContext, object krt.IndexObject[string, RouteWithKey]) **config.Config {
|
||||
configs := object.Objects
|
||||
if len(configs) == 1 {
|
||||
base := configs[0].Config
|
||||
nm := base.Meta.DeepCopy()
|
||||
// When dealing with a merge, we MUST take into account the merge key into the name.
|
||||
// Otherwise, we end up with broken state, where two inputs map to the same output which is not allowed by krt.
|
||||
// Because a lot of code assumes the object key is 'namespace/name', and the key always has slashes, we also translate the /
|
||||
nm.Name = strings.ReplaceAll(object.Key, "/", "~")
|
||||
return ptr.Of(&config.Config{
|
||||
Meta: nm,
|
||||
Spec: base.Spec,
|
||||
Status: base.Status,
|
||||
Extra: base.Extra,
|
||||
})
|
||||
}
|
||||
sortRoutesByCreationTime(configs)
|
||||
base := configs[0].DeepCopy()
|
||||
baseVS := base.Spec.(*istio.VirtualService)
|
||||
for _, config := range configs[1:] {
|
||||
thisVS := config.Spec.(*istio.VirtualService)
|
||||
baseVS.Http = append(baseVS.Http, thisVS.Http...)
|
||||
// append parents
|
||||
base.Annotations[constants.InternalParentNames] = fmt.Sprintf("%s,%s",
|
||||
base.Annotations[constants.InternalParentNames], config.Annotations[constants.InternalParentNames])
|
||||
}
|
||||
sortHTTPRoutes(baseVS.Http)
|
||||
base.Name = strings.ReplaceAll(object.Key, "/", "~")
|
||||
return ptr.Of(&base)
|
||||
}, opts...)
|
||||
return finalVirtualServices
|
||||
}
|
||||
106
pkg/ingress/kube/gateway/istio/status_test.go
Normal file
106
pkg/ingress/kube/gateway/istio/status_test.go
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright Istio Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package istio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"istio.io/istio/pilot/pkg/networking/core"
|
||||
"istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
|
||||
"istio.io/istio/pilot/pkg/status"
|
||||
"istio.io/istio/pkg/kube"
|
||||
"istio.io/istio/pkg/kube/krt"
|
||||
"istio.io/istio/pkg/slices"
|
||||
"istio.io/istio/pkg/test"
|
||||
"istio.io/istio/pkg/test/util/assert"
|
||||
)
|
||||
|
||||
func TestStatusCollections(t *testing.T) {
|
||||
stop := test.NewStop(t)
|
||||
fetch := func(q *TestStatusQueue) []string {
|
||||
return slices.Sort(slices.Map(q.Statuses(), func(e any) string {
|
||||
return *(e.(*string))
|
||||
}))
|
||||
}
|
||||
|
||||
type Status = krt.ObjectWithStatus[*v1.ConfigMap, string]
|
||||
c := setupControllerWithoutGatewayClasses(t)
|
||||
obj1 := Status{
|
||||
Obj: &v1.ConfigMap{},
|
||||
Status: "hello world",
|
||||
}
|
||||
fakeCol := krt.NewStaticCollection[Status](nil, []Status{obj1}, krt.WithStop(stop))
|
||||
status.RegisterStatus(c.status, fakeCol, func(i *v1.ConfigMap) string {
|
||||
return ""
|
||||
})
|
||||
|
||||
sq1 := &TestStatusQueue{state: map[status.Resource]any{}}
|
||||
setAndWait(t, c, sq1)
|
||||
assert.Equal(t, fetch(sq1), []string{"hello world"})
|
||||
|
||||
c.status.UnsetQueue()
|
||||
|
||||
// We should not get an update on the un-registered queue
|
||||
fakeCol.UpdateObject(Status{
|
||||
Obj: &v1.ConfigMap{},
|
||||
Status: "hello world2",
|
||||
})
|
||||
assert.Equal(t, fetch(sq1), []string{"hello world"})
|
||||
|
||||
// New queue should send new events, including existing state
|
||||
sq2 := &TestStatusQueue{state: map[status.Resource]any{}}
|
||||
setAndWait(t, c, sq2)
|
||||
assert.Equal(t, fetch(sq2), []string{"hello world2"})
|
||||
// And any new state
|
||||
fakeCol.UpdateObject(Status{
|
||||
Obj: &v1.ConfigMap{},
|
||||
Status: "hello world3",
|
||||
})
|
||||
// New event, so this is eventually consistent
|
||||
assert.EventuallyEqual(t, func() []string {
|
||||
return fetch(sq2)
|
||||
}, []string{"hello world3"})
|
||||
}
|
||||
|
||||
func setAndWait(t test.Failer, c *Controller, q status.Queue) {
|
||||
stop := test.NewStop(t)
|
||||
for _, syncer := range c.status.SetQueue(q) {
|
||||
syncer.WaitUntilSynced(stop)
|
||||
}
|
||||
}
|
||||
|
||||
func setupControllerWithoutGatewayClasses(t *testing.T, objs ...runtime.Object) *Controller {
|
||||
kc := kube.NewFakeClient(objs...)
|
||||
setupClientCRDs(t, kc)
|
||||
stop := test.NewStop(t)
|
||||
controller := NewController(
|
||||
kc,
|
||||
func(class schema.GroupVersionResource, stop <-chan struct{}) bool {
|
||||
return false
|
||||
},
|
||||
controller.Options{KrtDebugger: krt.GlobalDebugHandler},
|
||||
nil)
|
||||
kc.RunAndWait(stop)
|
||||
go controller.Run(stop)
|
||||
cg := core.NewConfigGenTest(t, core.TestOptions{})
|
||||
controller.Reconcile(cg.PushContext())
|
||||
kube.WaitForCacheSync("test", stop, controller.HasSynced)
|
||||
|
||||
return controller
|
||||
}
|
||||
@@ -15,14 +15,7 @@
|
||||
package istio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"istio.io/istio/pkg/fuzz"
|
||||
"sigs.k8s.io/gateway-api/pkg/features"
|
||||
)
|
||||
|
||||
func FuzzConvertResources(f *testing.F) {
|
||||
fuzz.Fuzz(f, func(fg fuzz.Helper) {
|
||||
r := fuzz.Struct[GatewayResources](fg)
|
||||
convertResources(r)
|
||||
})
|
||||
}
|
||||
var SupportedFeatures = features.AllFeatures
|
||||
@@ -1,65 +0,0 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: third-party-gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: third-party-gatewayclass
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
annotations:
|
||||
gateway.higress.io/alias-for: third-party-gateway
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: third-party-gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["first.domain.example", "another.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
22
pkg/ingress/kube/gateway/istio/testdata/backend-lb-policy.status.yaml.golden
vendored
Normal file
22
pkg/ingress/kube/gateway/istio/testdata/backend-lb-policy.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: gateway.networking.x-k8s.io/v1alpha1
|
||||
kind: XBackendTrafficPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: lb-policy
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: echo
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: 'Configuration is valid, but Istio does not support the following fields:
|
||||
sessionPersistence'
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
24
pkg/ingress/kube/gateway/istio/testdata/backend-lb-policy.yaml
vendored
Normal file
24
pkg/ingress/kube/gateway/istio/testdata/backend-lb-policy.yaml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
apiVersion: gateway.networking.x-k8s.io/v1alpha1
|
||||
kind: XBackendTrafficPolicy
|
||||
metadata:
|
||||
name: lb-policy
|
||||
namespace: default
|
||||
spec:
|
||||
targetRefs:
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: echo
|
||||
retryConstraint:
|
||||
minRetryRate:
|
||||
interval: "1s"
|
||||
count: 5
|
||||
budget:
|
||||
percent: 30
|
||||
interval: "10s"
|
||||
|
||||
sessionPersistence:
|
||||
sessionName: foo
|
||||
absoluteTimeout: 1h
|
||||
type: Cookie
|
||||
cookieConfig:
|
||||
lifetimeType: Permanent
|
||||
16
pkg/ingress/kube/gateway/istio/testdata/backend-lb-policy.yaml.golden
vendored
Normal file
16
pkg/ingress/kube/gateway/istio/testdata/backend-lb-policy.yaml.golden
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: XBackendTrafficPolicy/default.lb-policy
|
||||
creationTimestamp: null
|
||||
name: echo-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
host: echo.default.svc.domain.suffix
|
||||
trafficPolicy:
|
||||
loadBalancer: {}
|
||||
retryBudget:
|
||||
minRetryConcurrency: 5
|
||||
percent: 30
|
||||
---
|
||||
140
pkg/ingress/kube/gateway/istio/testdata/backend-tls-policy.status.yaml.golden
vendored
Normal file
140
pkg/ingress/kube/gateway/istio/testdata/backend-tls-policy.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: bad-configmap-type
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: foo-svc
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: 'Certificate reference invalid: unsupported kind UnknownKind'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Accepted
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: bad-service
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: does-not-exist
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: 'targetRefs invalid: reference default/does-not-exist (of kind Service)
|
||||
not found'
|
||||
reason: TargetNotFound
|
||||
status: "False"
|
||||
type: Accepted
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: existing-status
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: httpbin
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: hello
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
controllerName: example.com/some-other-controller
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: httpbin
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Configuration is valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: malformed-configmap
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: httpbin-other
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: 'Certificate reference invalid: found secret, but didn''t have expected
|
||||
keys cacert or ca.crt; found: not-ca.crt'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Accepted
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tls-upstream-echo
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: echo
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Configuration is valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: unknown-configmap
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: httpbin-second
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: 'Certificate reference invalid: reference default/does-not-exist (of
|
||||
kind ConfigMap) not found'
|
||||
reason: Invalid
|
||||
status: "False"
|
||||
type: Accepted
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
114
pkg/ingress/kube/gateway/istio/testdata/backend-tls-policy.yaml
vendored
Normal file
114
pkg/ingress/kube/gateway/istio/testdata/backend-tls-policy.yaml
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
name: tls-upstream-echo
|
||||
namespace: default
|
||||
spec:
|
||||
targetRefs:
|
||||
- kind: Service
|
||||
name: echo
|
||||
group: ""
|
||||
validation:
|
||||
caCertificateRefs:
|
||||
- kind: ConfigMap
|
||||
name: auth-cert
|
||||
group: ""
|
||||
hostname: auth.example.com
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
name: existing-status
|
||||
namespace: default
|
||||
spec:
|
||||
targetRefs:
|
||||
- kind: Service
|
||||
name: httpbin
|
||||
group: ""
|
||||
validation:
|
||||
caCertificateRefs:
|
||||
- kind: ConfigMap
|
||||
name: auth-cert
|
||||
group: ""
|
||||
hostname: auth.example.com
|
||||
status:
|
||||
ancestors:
|
||||
- ancestorRef:
|
||||
group: ""
|
||||
kind: Service
|
||||
name: httpbin
|
||||
conditions:
|
||||
- lastTransitionTime: 2000-01-01T01:01:01Z
|
||||
message: hello
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
controllerName: example.com/some-other-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
name: bad-service
|
||||
namespace: default
|
||||
spec:
|
||||
targetRefs:
|
||||
- kind: Service
|
||||
name: does-not-exist
|
||||
group: ""
|
||||
validation:
|
||||
caCertificateRefs:
|
||||
- kind: ConfigMap
|
||||
name: auth-cert
|
||||
group: ""
|
||||
hostname: auth.example.com
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
name: unknown-configmap
|
||||
namespace: default
|
||||
spec:
|
||||
targetRefs:
|
||||
- kind: Service
|
||||
name: httpbin-second
|
||||
group: ""
|
||||
validation:
|
||||
caCertificateRefs:
|
||||
- kind: ConfigMap
|
||||
name: does-not-exist
|
||||
group: ""
|
||||
hostname: auth.example.com
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
name: malformed-configmap
|
||||
namespace: default
|
||||
spec:
|
||||
targetRefs:
|
||||
- kind: Service
|
||||
name: httpbin-other
|
||||
group: ""
|
||||
validation:
|
||||
caCertificateRefs:
|
||||
- kind: ConfigMap
|
||||
name: malformed
|
||||
group: ""
|
||||
hostname: auth.example.com
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha3
|
||||
kind: BackendTLSPolicy
|
||||
metadata:
|
||||
name: bad-configmap-type
|
||||
namespace: default
|
||||
spec:
|
||||
targetRefs:
|
||||
- kind: Service
|
||||
name: foo-svc
|
||||
group: ""
|
||||
validation:
|
||||
caCertificateRefs:
|
||||
- kind: UnknownKind
|
||||
name: blah
|
||||
group: ""
|
||||
hostname: auth.example.com
|
||||
80
pkg/ingress/kube/gateway/istio/testdata/backend-tls-policy.yaml.golden
vendored
Normal file
80
pkg/ingress/kube/gateway/istio/testdata/backend-tls-policy.yaml.golden
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: BackendTLSPolicy/default.tls-upstream-echo
|
||||
creationTimestamp: null
|
||||
name: echo-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
host: echo.default.svc.domain.suffix
|
||||
trafficPolicy:
|
||||
tls:
|
||||
credentialName: configmap://default/auth-cert
|
||||
mode: SIMPLE
|
||||
sni: auth.example.com
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: BackendTLSPolicy/default.bad-configmap-type
|
||||
creationTimestamp: null
|
||||
name: foo-svc-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
host: foo-svc.default.svc.domain.suffix
|
||||
trafficPolicy:
|
||||
tls:
|
||||
credentialName: invalid://
|
||||
mode: SIMPLE
|
||||
sni: auth.example.com
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: BackendTLSPolicy/default.existing-status
|
||||
creationTimestamp: null
|
||||
name: httpbin-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
trafficPolicy:
|
||||
tls:
|
||||
credentialName: configmap://default/auth-cert
|
||||
mode: SIMPLE
|
||||
sni: auth.example.com
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: BackendTLSPolicy/default.malformed-configmap
|
||||
creationTimestamp: null
|
||||
name: httpbin-other-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
host: httpbin-other.default.svc.domain.suffix
|
||||
trafficPolicy:
|
||||
tls:
|
||||
credentialName: invalid://
|
||||
mode: SIMPLE
|
||||
sni: auth.example.com
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: BackendTLSPolicy/default.unknown-configmap
|
||||
creationTimestamp: null
|
||||
name: httpbin-second-istio-autogenerated-k8s-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
host: httpbin-second.default.svc.domain.suffix
|
||||
trafficPolicy:
|
||||
tls:
|
||||
credentialName: invalid://
|
||||
mode: SIMPLE
|
||||
sni: auth.example.com
|
||||
---
|
||||
@@ -1,21 +1,21 @@
|
||||
# the same as pilot/pkg/config/kube/gateway/testdata/route-precedence.yaml
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
name: istio
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
namespace: istio-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
- value: istio-ingressgateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
gatewayClassName: istio
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
@@ -28,7 +28,7 @@ spec:
|
||||
matchLabels:
|
||||
istio.io/test-name-part: allowed
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
@@ -36,7 +36,7 @@ metadata:
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
namespace: istio-system
|
||||
- kind: Mesh
|
||||
name: istio
|
||||
hostnames: ["a.domain.example", "b.domain.example"]
|
||||
@@ -60,7 +60,7 @@ spec:
|
||||
- name: svc2
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
@@ -68,7 +68,7 @@ metadata:
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
namespace: istio-system
|
||||
- kind: Mesh
|
||||
name: istio
|
||||
hostnames: ["a.domain.example"]
|
||||
@@ -106,7 +106,7 @@ spec:
|
||||
- name: svc3
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
@@ -114,7 +114,7 @@ metadata:
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
namespace: istio-system
|
||||
hostnames: ["a.domain.example", "b.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
|
||||
@@ -3,7 +3,6 @@ kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
@@ -22,8 +21,8 @@ metadata:
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
- type: Hostname
|
||||
value: higress-gateway.higress-system.svc.domain.suffix
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
@@ -62,6 +61,8 @@ status:
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: GRPCRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
@@ -88,6 +89,8 @@ status:
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: GRPCRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
@@ -109,7 +112,7 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
@@ -134,7 +137,7 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
@@ -37,7 +37,7 @@ spec:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: banana
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
@@ -51,7 +51,7 @@ spec:
|
||||
- name: httpbin-apple
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
|
||||
@@ -2,6 +2,7 @@ apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/apple.higress-system
|
||||
creationTimestamp: null
|
||||
@@ -20,6 +21,7 @@ apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/banana.higress-system
|
||||
creationTimestamp: null
|
||||
@@ -41,7 +43,7 @@ metadata:
|
||||
internal.istio.io/parents: HTTPRoute/http.apple
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-apple~*
|
||||
namespace: apple
|
||||
spec:
|
||||
gateways:
|
||||
@@ -63,7 +65,7 @@ metadata:
|
||||
internal.istio.io/parents: HTTPRoute/http.banana
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-banana~*
|
||||
namespace: banana
|
||||
spec:
|
||||
gateways:
|
||||
|
||||
253
pkg/ingress/kube/gateway/istio/testdata/deployment/cluster-ip.yaml
vendored
Normal file
253
pkg/ingress/kube/gateway/istio/testdata/deployment/cluster-ip.yaml
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations:
|
||||
networking.istio.io/service-type: ClusterIP
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
networking.istio.io/service-type: ClusterIP
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
networking.istio.io/service-type: ClusterIP
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
networking.istio.io/service-type: ClusterIP
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
- appProtocol: http
|
||||
name: http
|
||||
port: 80
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: ClusterIP
|
||||
---
|
||||
245
pkg/ingress/kube/gateway/istio/testdata/deployment/copy-labels-annotations-disabled-infra-nil.yaml
vendored
Normal file
245
pkg/ingress/kube/gateway/istio/testdata/deployment/copy-labels-annotations-disabled-infra-nil.yaml
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
253
pkg/ingress/kube/gateway/istio/testdata/deployment/copy-labels-annotations-disabled-infra-set.yaml
vendored
Normal file
253
pkg/ingress/kube/gateway/istio/testdata/deployment/copy-labels-annotations-disabled-infra-set.yaml
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations:
|
||||
should: see-infra-annotation
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see-infra-label
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
should: see-infra-annotation
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see-infra-label
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
should: see-infra-annotation
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
should: see-infra-label
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
should: see-infra-annotation
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see-infra-label
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
253
pkg/ingress/kube/gateway/istio/testdata/deployment/copy-labels-annotations-enabled-infra-nil.yaml
vendored
Normal file
253
pkg/ingress/kube/gateway/istio/testdata/deployment/copy-labels-annotations-enabled-infra-nil.yaml
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations:
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
should: see
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
245
pkg/ingress/kube/gateway/istio/testdata/deployment/custom-class.yaml
vendored
Normal file
245
pkg/ingress/kube/gateway/istio/testdata/deployment/custom-class.yaml
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-custom
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-custom
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-custom
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-custom
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-custom
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-custom
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-custom
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
300
pkg/ingress/kube/gateway/istio/testdata/deployment/customizations.yaml
vendored
Normal file
300
pkg/ingress/kube/gateway/istio/testdata/deployment/customizations.yaml
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
name: namespace-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
cm-annotation: cm-annotation-value
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
name: namespace-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
spec:
|
||||
replicas: 4
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: namespace-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: namespace-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 222m
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: namespace-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
name: namespace-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
type: LoadBalancer
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
name: namespace-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
spec:
|
||||
maxReplicas: 2
|
||||
minReplicas: 2
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: namespace-istio
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
name: namespace-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
spec:
|
||||
minAvailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
---
|
||||
@@ -0,0 +1,257 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
istio.io/enable-inference-extproc: "true"
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
istio.io/enable-inference-extproc: "true"
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
istio.io/enable-inference-extproc: "true"
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
istio.io/enable-inference-extproc: "true"
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
6
pkg/ingress/kube/gateway/istio/testdata/deployment/illegal_customizations.yaml
vendored
Normal file
6
pkg/ingress/kube/gateway/istio/testdata/deployment/illegal_customizations.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
253
pkg/ingress/kube/gateway/istio/testdata/deployment/infrastructure-labels-annotations.yaml
vendored
Normal file
253
pkg/ingress/kube/gateway/istio/testdata/deployment/infrastructure-labels-annotations.yaml
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
fizz: buzz
|
||||
labels:
|
||||
foo: bar
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
254
pkg/ingress/kube/gateway/istio/testdata/deployment/istio-east-west.yaml
vendored
Normal file
254
pkg/ingress/kube/gateway/istio/testdata/deployment/istio-east-west.yaml
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-eastwest-controller
|
||||
gateway.networking.k8s.io/gateway-name: eastwestgateway
|
||||
topology.istio.io/network: network-1
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-eastwest-controller
|
||||
gateway.networking.k8s.io/gateway-name: eastwestgateway
|
||||
topology.istio.io/network: network-1
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: eastwestgateway
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-eastwest-controller
|
||||
gateway.networking.k8s.io/gateway-name: eastwestgateway
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: eastwestgateway
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
topology.istio.io/network: network-1
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- waypoint
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --serviceCluster
|
||||
- eastwestgateway.$(POD_NAMESPACE)
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: ISTIO_META_SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NETWORK
|
||||
value: network-1
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: eastwestgateway
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/istio-system/deployments/eastwestgateway
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/istio
|
||||
name: istiod-ca-cert
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
serviceAccountName: eastwestgateway
|
||||
terminationGracePeriodSeconds: 2
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: go-proxy-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- emptyDir: {}
|
||||
name: go-proxy-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: istio-ca
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
- configMap:
|
||||
name: istio-ca-root-cert
|
||||
name: istiod-ca-cert
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
networking.istio.io/traffic-distribution: PreferClose
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-eastwest-controller
|
||||
gateway.networking.k8s.io/gateway-name: eastwestgateway
|
||||
topology.istio.io/network: network-1
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
uid: ""
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
- appProtocol: all
|
||||
name: mesh
|
||||
port: 15008
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: eastwestgateway
|
||||
type: LoadBalancer
|
||||
---
|
||||
256
pkg/ingress/kube/gateway/istio/testdata/deployment/istio-upgrade-to-1.24.yaml
vendored
Normal file
256
pkg/ingress/kube/gateway/istio/testdata/deployment/istio-upgrade-to-1.24.yaml
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: test-upgrade
|
||||
topology.istio.io/network: network-1
|
||||
name: test-upgrade
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: test-upgrade
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: test-upgrade
|
||||
topology.istio.io/network: network-1
|
||||
name: test-upgrade
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: test-upgrade
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: test-upgrade
|
||||
istio.io/gateway-name: test-upgrade
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: test-upgrade
|
||||
istio.io/dataplane-mode: none
|
||||
istio.io/gateway-name: test-upgrade
|
||||
service.istio.io/canonical-name: test-upgrade
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
topology.istio.io/network: network-1
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- waypoint
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --serviceCluster
|
||||
- test-upgrade.$(POD_NAMESPACE)
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: ISTIO_META_SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NETWORK
|
||||
value: network-1
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: test-upgrade
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/test-upgrade
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/istio
|
||||
name: istiod-ca-cert
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
serviceAccountName: test-upgrade
|
||||
terminationGracePeriodSeconds: 2
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: go-proxy-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- emptyDir: {}
|
||||
name: go-proxy-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: istio-ca
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
- configMap:
|
||||
name: istio-ca-root-cert
|
||||
name: istiod-ca-cert
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
networking.istio.io/traffic-distribution: PreferClose
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: test-upgrade
|
||||
topology.istio.io/network: network-1
|
||||
name: test-upgrade
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: test-upgrade
|
||||
uid: ""
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
- appProtocol: all
|
||||
name: mesh
|
||||
port: 15008
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: test-upgrade
|
||||
type: ClusterIP
|
||||
---
|
||||
245
pkg/ingress/kube/gateway/istio/testdata/deployment/kube-gateway-ambient-redirect-infra.yaml
vendored
Normal file
245
pkg/ingress/kube/gateway/istio/testdata/deployment/kube-gateway-ambient-redirect-infra.yaml
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
245
pkg/ingress/kube/gateway/istio/testdata/deployment/kube-gateway-ambient-redirect.yaml
vendored
Normal file
245
pkg/ingress/kube/gateway/istio/testdata/deployment/kube-gateway-ambient-redirect.yaml
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: ambient
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
246
pkg/ingress/kube/gateway/istio/testdata/deployment/manual-ip.yaml
vendored
Normal file
246
pkg/ingress/kube/gateway/istio/testdata/deployment/manual-ip.yaml
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
loadBalancerIP: 1.2.3.4
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
245
pkg/ingress/kube/gateway/istio/testdata/deployment/manual-sa.yaml
vendored
Normal file
245
pkg/ingress/kube/gateway/istio/testdata/deployment/manual-sa.yaml
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: custom-sa
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: custom-sa
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
257
pkg/ingress/kube/gateway/istio/testdata/deployment/multinetwork.yaml
vendored
Normal file
257
pkg/ingress/kube/gateway/istio/testdata/deployment/multinetwork.yaml
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
topology.istio.io/network: network-1
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
topology.istio.io/network: network-1
|
||||
name: default
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
topology.istio.io/network: network-1
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_NETWORK
|
||||
value: network-1
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
|
||||
value: network-1
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
topology.istio.io/network: network-1
|
||||
name: default
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
- appProtocol: http
|
||||
name: http
|
||||
port: 80
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
245
pkg/ingress/kube/gateway/istio/testdata/deployment/proxy-config-crd.yaml
vendored
Normal file
245
pkg/ingress/kube/gateway/istio/testdata/deployment/proxy-config-crd.yaml
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{"image":{"imageType":"distroless"}}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test-distroless
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
253
pkg/ingress/kube/gateway/istio/testdata/deployment/simple.yaml
vendored
Normal file
253
pkg/ingress/kube/gateway/istio/testdata/deployment/simple.yaml
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations:
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: default-istio
|
||||
service.istio.io/canonical-revision: latest
|
||||
should: see
|
||||
sidecar.istio.io/inject: "false"
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- router
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: ISTIO_META_POD_PORTS
|
||||
value: '[]'
|
||||
- name: ISTIO_META_APP_CONTAINERS
|
||||
value: ""
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: default-istio
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/default-istio
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/credential-uds
|
||||
name: credential-socket
|
||||
- mountPath: /var/run/secrets/workload-spiffe-credentials
|
||||
name: workload-certs
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
serviceAccountName: default-istio
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir: {}
|
||||
name: credential-socket
|
||||
- emptyDir: {}
|
||||
name: workload-certs
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: <no value>
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
should: see
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-gateway-controller
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
istio.io/dataplane-mode: none
|
||||
should: see
|
||||
name: default-istio
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: default
|
||||
uid: null
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: default
|
||||
type: LoadBalancer
|
||||
---
|
||||
254
pkg/ingress/kube/gateway/istio/testdata/deployment/waypoint-no-network-label.yaml
vendored
Normal file
254
pkg/ingress/kube/gateway/istio/testdata/deployment/waypoint-no-network-label.yaml
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
topology.istio.io/network: network-1
|
||||
name: namespace
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
topology.istio.io/network: network-1
|
||||
name: namespace
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: namespace
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
topology.istio.io/network: network-1
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- waypoint
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --serviceCluster
|
||||
- namespace.$(POD_NAMESPACE)
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: ISTIO_META_SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NETWORK
|
||||
value: network-1
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: namespace
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/istio
|
||||
name: istiod-ca-cert
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
serviceAccountName: namespace
|
||||
terminationGracePeriodSeconds: 2
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: go-proxy-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- emptyDir: {}
|
||||
name: go-proxy-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: istio-ca
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
- configMap:
|
||||
name: istio-ca-root-cert
|
||||
name: istiod-ca-cert
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
networking.istio.io/traffic-distribution: PreferClose
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
topology.istio.io/network: network-1
|
||||
name: namespace
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
- appProtocol: all
|
||||
name: mesh
|
||||
port: 15008
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
type: ClusterIP
|
||||
---
|
||||
254
pkg/ingress/kube/gateway/istio/testdata/deployment/waypoint.yaml
vendored
Normal file
254
pkg/ingress/kube/gateway/istio/testdata/deployment/waypoint.yaml
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
gateway.istio.io/controller-version: "5"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
topology.istio.io/network: network-1
|
||||
name: namespace
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
topology.istio.io/network: network-1
|
||||
name: namespace
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
istio.io/rev: default
|
||||
prometheus.io/path: /stats/prometheus
|
||||
prometheus.io/port: "15020"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
istio.io/dataplane-mode: none
|
||||
service.istio.io/canonical-name: namespace
|
||||
service.istio.io/canonical-revision: latest
|
||||
sidecar.istio.io/inject: "false"
|
||||
topology.istio.io/network: network-1
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- proxy
|
||||
- waypoint
|
||||
- --domain
|
||||
- $(POD_NAMESPACE).svc.<no value>
|
||||
- --serviceCluster
|
||||
- namespace.$(POD_NAMESPACE)
|
||||
- --proxyLogLevel
|
||||
- <nil>
|
||||
- --proxyComponentLogLevel
|
||||
- <nil>
|
||||
- --log_output_level
|
||||
- <nil>
|
||||
env:
|
||||
- name: ISTIO_META_SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: ISTIO_META_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: PILOT_CERT_PROVIDER
|
||||
value: <no value>
|
||||
- name: CA_ADDR
|
||||
value: istiod-<no value>.<no value>.svc:15012
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: INSTANCE_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: SERVICE_ACCOUNT
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.serviceAccountName
|
||||
- name: HOST_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: ISTIO_CPU_LIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: PROXY_CONFIG
|
||||
value: |
|
||||
{}
|
||||
- name: GOMEMLIMIT
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
- name: GOMAXPROCS
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.cpu
|
||||
- name: ISTIO_META_CLUSTER_ID
|
||||
value: Kubernetes
|
||||
- name: ISTIO_META_NETWORK
|
||||
value: network-1
|
||||
- name: ISTIO_META_INTERCEPTION_MODE
|
||||
value: REDIRECT
|
||||
- name: ISTIO_META_WORKLOAD_NAME
|
||||
value: namespace
|
||||
- name: ISTIO_META_OWNER
|
||||
value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace
|
||||
- name: ISTIO_META_MESH_ID
|
||||
value: cluster.local
|
||||
- name: TRUST_DOMAIN
|
||||
value: cluster.local
|
||||
image: test/proxyv2:test
|
||||
name: istio-proxy
|
||||
ports:
|
||||
- containerPort: 15020
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: 15021
|
||||
name: status-port
|
||||
protocol: TCP
|
||||
- containerPort: 15090
|
||||
name: http-envoy-prom
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 4
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 1337
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1337
|
||||
startupProbe:
|
||||
failureThreshold: 30
|
||||
httpGet:
|
||||
path: /healthz/ready
|
||||
port: 15021
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: /var/run/secrets/workload-spiffe-uds
|
||||
name: workload-socket
|
||||
- mountPath: /var/run/secrets/istio
|
||||
name: istiod-ca-cert
|
||||
- mountPath: /var/lib/istio/data
|
||||
name: istio-data
|
||||
- mountPath: /etc/istio/proxy
|
||||
name: istio-envoy
|
||||
- mountPath: /var/run/secrets/tokens
|
||||
name: istio-token
|
||||
- mountPath: /etc/istio/pod
|
||||
name: istio-podinfo
|
||||
serviceAccountName: namespace
|
||||
terminationGracePeriodSeconds: 2
|
||||
volumes:
|
||||
- emptyDir: {}
|
||||
name: workload-socket
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: istio-envoy
|
||||
- emptyDir:
|
||||
medium: Memory
|
||||
name: go-proxy-envoy
|
||||
- emptyDir: {}
|
||||
name: istio-data
|
||||
- emptyDir: {}
|
||||
name: go-proxy-data
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
path: labels
|
||||
- fieldRef:
|
||||
fieldPath: metadata.annotations
|
||||
path: annotations
|
||||
name: istio-podinfo
|
||||
- name: istio-token
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: istio-ca
|
||||
expirationSeconds: 43200
|
||||
path: istio-token
|
||||
- configMap:
|
||||
name: istio-ca-root-cert
|
||||
name: istiod-ca-cert
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
networking.istio.io/traffic-distribution: PreferClose
|
||||
labels:
|
||||
gateway.istio.io/managed: istio.io-mesh-controller
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
topology.istio.io/network: network-1
|
||||
name: namespace
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
name: namespace
|
||||
uid: ""
|
||||
spec:
|
||||
ipFamilyPolicy: PreferDualStack
|
||||
ports:
|
||||
- appProtocol: tcp
|
||||
name: status-port
|
||||
port: 15021
|
||||
protocol: TCP
|
||||
- appProtocol: all
|
||||
name: mesh
|
||||
port: 15008
|
||||
protocol: TCP
|
||||
selector:
|
||||
gateway.networking.k8s.io/gateway-name: namespace
|
||||
type: ClusterIP
|
||||
---
|
||||
93
pkg/ingress/kube/gateway/istio/testdata/east-west-ambient.status.yaml.golden
vendored
Normal file
93
pkg/ingress/kube/gateway/istio/testdata/east-west-ambient.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: hostname "eastwestgateway.istio-system.svc.domain.suffix"
|
||||
not found'
|
||||
reason: AddressNotUsable
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: mesh
|
||||
supportedKinds: []
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: invalid
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: hostname "invalid.istio-system.svc.domain.suffix"
|
||||
not found'
|
||||
reason: AddressNotUsable
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Expected a single listener on port 15008 with protocol "HBONE" and
|
||||
TLS.Mode == Terminate
|
||||
reason: UnsupportedProtocol
|
||||
status: "False"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: mesh
|
||||
supportedKinds: []
|
||||
---
|
||||
31
pkg/ingress/kube/gateway/istio/testdata/east-west-ambient.yaml
vendored
Normal file
31
pkg/ingress/kube/gateway/istio/testdata/east-west-ambient.yaml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
labels:
|
||||
topology.istio.io/network: "network-1"
|
||||
spec:
|
||||
gatewayClassName: istio-east-west
|
||||
listeners:
|
||||
- name: mesh
|
||||
port: 15008
|
||||
protocol: HBONE
|
||||
tls:
|
||||
mode: Terminate # represents double-HBONE
|
||||
options:
|
||||
gateway.istio.io/tls-terminate-mode: ISTIO_MUTUAL
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: invalid
|
||||
namespace: istio-system
|
||||
labels:
|
||||
topology.istio.io/network: "network-1"
|
||||
spec:
|
||||
gatewayClassName: istio-east-west
|
||||
listeners:
|
||||
- name: mesh
|
||||
port: 15008
|
||||
protocol: HBONE # No TLS mode terminate
|
||||
0
pkg/ingress/kube/gateway/istio/testdata/east-west-ambient.yaml.golden
vendored
Normal file
0
pkg/ingress/kube/gateway/istio/testdata/east-west-ambient.yaml.golden
vendored
Normal file
152
pkg/ingress/kube/gateway/istio/testdata/eastwest-labelport.status.yaml.golden
vendored
Normal file
152
pkg/ingress/kube/gateway/istio/testdata/eastwest-labelport.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: hostname "eastwestgateway-istio.istio-system.svc.domain.suffix"
|
||||
not found'
|
||||
reason: AddressNotUsable
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: istiod-grpc
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: istiod-webhook
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: cross-network
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
sectionName: istiod-grpc
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
sectionName: istiod-webhook
|
||||
---
|
||||
57
pkg/ingress/kube/gateway/istio/testdata/eastwest-labelport.yaml
vendored
Normal file
57
pkg/ingress/kube/gateway/istio/testdata/eastwest-labelport.yaml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
labels:
|
||||
topology.istio.io/network: "network-1"
|
||||
networking.istio.io/gatewayPort: "35443"
|
||||
spec:
|
||||
gatewayClassName: istio
|
||||
listeners:
|
||||
- name: istiod-grpc
|
||||
port: 15012
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
- name: istiod-webhook
|
||||
port: 15017
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
- name: cross-network
|
||||
hostname: "*.local"
|
||||
port: 35443
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-grpc
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15012
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-webhook
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15017
|
||||
109
pkg/ingress/kube/gateway/istio/testdata/eastwest-labelport.yaml.golden
vendored
Normal file
109
pkg/ingress/kube/gateway/istio/testdata/eastwest-labelport.yaml.golden
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/cross-network.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-cross-network
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*.local
|
||||
port:
|
||||
name: default
|
||||
number: 35443
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: AUTO_PASSTHROUGH
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/istiod-grpc.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*
|
||||
port:
|
||||
name: default
|
||||
number: 15012
|
||||
protocol: TLS
|
||||
tls: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/istiod-webhook.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*
|
||||
port:
|
||||
name: default
|
||||
number: 15017
|
||||
protocol: TLS
|
||||
tls: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/eastwestgateway-grpc.istio-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-grpc-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: istio-system
|
||||
spec:
|
||||
gateways:
|
||||
- istio-system/eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
|
||||
hosts:
|
||||
- '*'
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- '*'
|
||||
route:
|
||||
- destination:
|
||||
host: istiod.istio-system.svc.domain.suffix
|
||||
port:
|
||||
number: 15012
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/eastwestgateway-webhook.istio-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-webhook-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: istio-system
|
||||
spec:
|
||||
gateways:
|
||||
- istio-system/eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
|
||||
hosts:
|
||||
- '*'
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- '*'
|
||||
route:
|
||||
- destination:
|
||||
host: istiod.istio-system.svc.domain.suffix
|
||||
port:
|
||||
number: 15017
|
||||
---
|
||||
43
pkg/ingress/kube/gateway/istio/testdata/eastwest-remote.status.yaml.golden
vendored
Normal file
43
pkg/ingress/kube/gateway/istio/testdata/eastwest-remote.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.1.1.1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: This Gateway is remote; Istio will not program it
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents: []
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents: []
|
||||
---
|
||||
50
pkg/ingress/kube/gateway/istio/testdata/eastwest-remote.yaml
vendored
Normal file
50
pkg/ingress/kube/gateway/istio/testdata/eastwest-remote.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
labels:
|
||||
topology.istio.io/network: "network-1"
|
||||
spec:
|
||||
addresses:
|
||||
- value: 1.1.1.1
|
||||
type: IPAddress
|
||||
gatewayClassName: istio-remote
|
||||
listeners:
|
||||
- name: cross-network
|
||||
hostname: "*.local"
|
||||
port: 15443
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
---
|
||||
# These routes should be ignored since this is an istio-remote gateway!
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-grpc
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15012
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-webhook
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15017
|
||||
0
pkg/ingress/kube/gateway/istio/testdata/eastwest-remote.yaml.golden
vendored
Normal file
0
pkg/ingress/kube/gateway/istio/testdata/eastwest-remote.yaml.golden
vendored
Normal file
152
pkg/ingress/kube/gateway/istio/testdata/eastwest-tlsoption.status.yaml.golden
vendored
Normal file
152
pkg/ingress/kube/gateway/istio/testdata/eastwest-tlsoption.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: hostname "eastwestgateway-istio.istio-system.svc.domain.suffix"
|
||||
not found'
|
||||
reason: AddressNotUsable
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: istiod-grpc
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: istiod-webhook
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: cross-network
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
sectionName: istiod-grpc
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
sectionName: istiod-webhook
|
||||
---
|
||||
58
pkg/ingress/kube/gateway/istio/testdata/eastwest-tlsoption.yaml
vendored
Normal file
58
pkg/ingress/kube/gateway/istio/testdata/eastwest-tlsoption.yaml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
labels:
|
||||
topology.istio.io/network: "network-1"
|
||||
spec:
|
||||
gatewayClassName: istio
|
||||
listeners:
|
||||
- name: istiod-grpc
|
||||
port: 15012
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
- name: istiod-webhook
|
||||
port: 15017
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
- name: cross-network
|
||||
hostname: "*.local"
|
||||
port: 35443
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
options:
|
||||
gateway.istio.io/listener-protocol: auto-passthrough
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-grpc
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15012
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-webhook
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15017
|
||||
109
pkg/ingress/kube/gateway/istio/testdata/eastwest-tlsoption.yaml.golden
vendored
Normal file
109
pkg/ingress/kube/gateway/istio/testdata/eastwest-tlsoption.yaml.golden
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/cross-network.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-cross-network
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*.local
|
||||
port:
|
||||
name: default
|
||||
number: 35443
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: AUTO_PASSTHROUGH
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/istiod-grpc.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*
|
||||
port:
|
||||
name: default
|
||||
number: 15012
|
||||
protocol: TLS
|
||||
tls: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/istiod-webhook.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*
|
||||
port:
|
||||
name: default
|
||||
number: 15017
|
||||
protocol: TLS
|
||||
tls: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/eastwestgateway-grpc.istio-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-grpc-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: istio-system
|
||||
spec:
|
||||
gateways:
|
||||
- istio-system/eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
|
||||
hosts:
|
||||
- '*'
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- '*'
|
||||
route:
|
||||
- destination:
|
||||
host: istiod.istio-system.svc.domain.suffix
|
||||
port:
|
||||
number: 15012
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/eastwestgateway-webhook.istio-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-webhook-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: istio-system
|
||||
spec:
|
||||
gateways:
|
||||
- istio-system/eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
|
||||
hosts:
|
||||
- '*'
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- '*'
|
||||
route:
|
||||
- destination:
|
||||
host: istiod.istio-system.svc.domain.suffix
|
||||
port:
|
||||
number: 15017
|
||||
---
|
||||
152
pkg/ingress/kube/gateway/istio/testdata/eastwest.status.yaml.golden
vendored
Normal file
152
pkg/ingress/kube/gateway/istio/testdata/eastwest.status.yaml.golden
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: 'Failed to assign to any requested addresses: hostname "eastwestgateway-istio.istio-system.svc.domain.suffix"
|
||||
not found'
|
||||
reason: AddressNotUsable
|
||||
status: "False"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: istiod-grpc
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
- attachedRoutes: 1
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: istiod-webhook
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
- attachedRoutes: 0
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: NoConflicts
|
||||
status: "False"
|
||||
type: Conflicted
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: Programmed
|
||||
status: "True"
|
||||
type: Programmed
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
name: cross-network
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: TLSRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
sectionName: istiod-grpc
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
kind: Gateway
|
||||
name: eastwestgateway
|
||||
sectionName: istiod-webhook
|
||||
---
|
||||
56
pkg/ingress/kube/gateway/istio/testdata/eastwest.yaml
vendored
Normal file
56
pkg/ingress/kube/gateway/istio/testdata/eastwest.yaml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: eastwestgateway
|
||||
namespace: istio-system
|
||||
labels:
|
||||
topology.istio.io/network: "network-1"
|
||||
spec:
|
||||
gatewayClassName: istio
|
||||
listeners:
|
||||
- name: istiod-grpc
|
||||
port: 15012
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
- name: istiod-webhook
|
||||
port: 15017
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
- name: cross-network
|
||||
hostname: "*.local"
|
||||
port: 15443
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: Passthrough
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-grpc
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-grpc
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15012
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
kind: TLSRoute
|
||||
metadata:
|
||||
name: eastwestgateway-webhook
|
||||
namespace: istio-system
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: eastwestgateway
|
||||
kind: Gateway
|
||||
sectionName: istiod-webhook
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: istiod
|
||||
port: 15017
|
||||
109
pkg/ingress/kube/gateway/istio/testdata/eastwest.yaml.golden
vendored
Normal file
109
pkg/ingress/kube/gateway/istio/testdata/eastwest.yaml.golden
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/cross-network.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-cross-network
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*.local
|
||||
port:
|
||||
name: default
|
||||
number: 15443
|
||||
protocol: TLS
|
||||
tls:
|
||||
mode: AUTO_PASSTHROUGH
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/istiod-grpc.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*
|
||||
port:
|
||||
name: default
|
||||
number: 15012
|
||||
protocol: TLS
|
||||
tls: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: eastwestgateway-istio.istio-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/eastwestgateway/istiod-webhook.istio-system
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
|
||||
namespace: istio-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- istio-system/*
|
||||
port:
|
||||
name: default
|
||||
number: 15017
|
||||
protocol: TLS
|
||||
tls: {}
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/eastwestgateway-grpc.istio-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-grpc-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: istio-system
|
||||
spec:
|
||||
gateways:
|
||||
- istio-system/eastwestgateway-istio-autogenerated-k8s-gateway-istiod-grpc
|
||||
hosts:
|
||||
- '*'
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- '*'
|
||||
route:
|
||||
- destination:
|
||||
host: istiod.istio-system.svc.domain.suffix
|
||||
port:
|
||||
number: 15012
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: TLSRoute/eastwestgateway-webhook.istio-system
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: eastwestgateway-webhook-tls-0-istio-autogenerated-k8s-gateway
|
||||
namespace: istio-system
|
||||
spec:
|
||||
gateways:
|
||||
- istio-system/eastwestgateway-istio-autogenerated-k8s-gateway-istiod-webhook
|
||||
hosts:
|
||||
- '*'
|
||||
tls:
|
||||
- match:
|
||||
- sniHosts:
|
||||
- '*'
|
||||
route:
|
||||
- destination:
|
||||
host: istiod.istio-system.svc.domain.suffix
|
||||
port:
|
||||
number: 15017
|
||||
---
|
||||
@@ -3,7 +3,6 @@ kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
@@ -15,14 +14,6 @@ status:
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: third-party-gateway
|
||||
namespace: higress-system
|
||||
spec: null
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: gateway
|
||||
@@ -30,8 +21,8 @@ metadata:
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
- type: Hostname
|
||||
value: higress-gateway.higress-system.svc.domain.suffix
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
@@ -69,13 +60,13 @@ status:
|
||||
name: default
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
kind: GRPCRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: GRPCRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http
|
||||
name: grpc
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
@@ -91,8 +82,8 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: third-party-gateway
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
63
pkg/ingress/kube/gateway/istio/testdata/grpc.yaml
vendored
Normal file
63
pkg/ingress/kube/gateway/istio/testdata/grpc.yaml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
spec:
|
||||
addresses:
|
||||
- value: higress-gateway
|
||||
type: Hostname
|
||||
gatewayClassName: higress
|
||||
listeners:
|
||||
- name: default
|
||||
hostname: "*.domain.example"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
kinds:
|
||||
- kind: GRPCRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: GRPCRoute
|
||||
metadata:
|
||||
name: grpc
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["first.domain.example", "another.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- method:
|
||||
service: "foo"
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
filters:
|
||||
- type: RequestHeaderModifier
|
||||
requestHeaderModifier:
|
||||
add:
|
||||
- name: my-added-header
|
||||
value: added-value
|
||||
remove: [my-removed-header]
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
- matches:
|
||||
- method:
|
||||
type: RegularExpression
|
||||
method: "bar"
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
105
pkg/ingress/kube/gateway/istio/testdata/grpc.yaml.golden
vendored
Normal file
105
pkg/ingress/kube/gateway/istio/testdata/grpc.yaml.golden
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
name: gateway-istio-autogenerated-k8s-gateway-default
|
||||
namespace: higress-system
|
||||
spec:
|
||||
servers:
|
||||
- hosts:
|
||||
- '*/*.domain.example'
|
||||
port:
|
||||
name: default
|
||||
number: 80
|
||||
protocol: HTTP
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: GRPCRoute/grpc.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~another.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- another.domain.example
|
||||
http:
|
||||
- headers:
|
||||
request:
|
||||
add:
|
||||
my-added-header: added-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /foo/
|
||||
name: GRPC/default/grpc
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
regex: /[^/]+/bar
|
||||
name: GRPC/default/grpc
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: GRPCRoute/grpc.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~first.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- first.domain.example
|
||||
http:
|
||||
- headers:
|
||||
request:
|
||||
add:
|
||||
my-added-header: added-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /foo/
|
||||
name: GRPC/default/grpc
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
regex: /[^/]+/bar
|
||||
name: GRPC/default/grpc
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
@@ -1,9 +1,26 @@
|
||||
apiVersion: inference.networking.x-k8s.io/v1alpha2
|
||||
kind: InferencePool
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: infpool-gen
|
||||
namespace: default
|
||||
spec: null
|
||||
status: {}
|
||||
---
|
||||
apiVersion: inference.networking.x-k8s.io/v1alpha2
|
||||
kind: InferencePool
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: infpool-gen2
|
||||
namespace: default
|
||||
spec: null
|
||||
status: {}
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: higress
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
conditions:
|
||||
@@ -22,8 +39,8 @@ metadata:
|
||||
spec: null
|
||||
status:
|
||||
addresses:
|
||||
- type: IPAddress
|
||||
value: 1.2.3.4
|
||||
- type: Hostname
|
||||
value: higress-gateway.higress-system.svc.domain.suffix
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Resource accepted
|
||||
@@ -36,7 +53,7 @@ status:
|
||||
status: "True"
|
||||
type: Programmed
|
||||
listeners:
|
||||
- attachedRoutes: 6
|
||||
- attachedRoutes: 11
|
||||
conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: No errors found
|
||||
@@ -62,6 +79,8 @@ status:
|
||||
supportedKinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: GRPCRoute
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
@@ -83,7 +102,7 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
@@ -108,7 +127,107 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http-retry-request
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http-route-cors
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http-timeout-backend-request
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: http-timeout-request
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
@@ -133,7 +252,7 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
@@ -158,7 +277,32 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: multiple-inferencepool-backend-refs
|
||||
namespace: default
|
||||
spec: null
|
||||
status:
|
||||
parents:
|
||||
- conditions:
|
||||
- lastTransitionTime: fake
|
||||
message: Route was valid
|
||||
reason: Accepted
|
||||
status: "True"
|
||||
type: Accepted
|
||||
- lastTransitionTime: fake
|
||||
message: All references resolved
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
@@ -183,7 +327,7 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
@@ -208,7 +352,7 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
@@ -233,7 +377,7 @@ status:
|
||||
reason: ResolvedRefs
|
||||
status: "True"
|
||||
type: ResolvedRefs
|
||||
controllerName: higress.io/gateway-controller
|
||||
controllerName: istio.io/gateway-controller
|
||||
parentRef:
|
||||
name: gateway
|
||||
namespace: higress-system
|
||||
|
||||
229
pkg/ingress/kube/gateway/istio/testdata/http.yaml
vendored
229
pkg/ingress/kube/gateway/istio/testdata/http.yaml
vendored
@@ -1,11 +1,11 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: higress
|
||||
spec:
|
||||
controllerName: higress.io/gateway-controller
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gateway
|
||||
@@ -24,7 +24,7 @@ spec:
|
||||
namespaces:
|
||||
from: All
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http
|
||||
@@ -60,7 +60,7 @@ spec:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http2
|
||||
@@ -86,7 +86,7 @@ spec:
|
||||
- name: httpbin-wildcard
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: redirect
|
||||
@@ -106,7 +106,7 @@ spec:
|
||||
type: ReplaceFullPath
|
||||
replaceFullPath: /replace-full
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: redirect-prefix-replace
|
||||
@@ -131,7 +131,7 @@ spec:
|
||||
type: ReplacePrefixMatch
|
||||
replacePrefixMatch: /replacement
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: rewrite
|
||||
@@ -141,11 +141,11 @@ spec:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- matches:
|
||||
- name: route1
|
||||
matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /prefix-original
|
||||
name: prefix-path-rewrite
|
||||
filters:
|
||||
- type: URLRewrite
|
||||
urlRewrite:
|
||||
@@ -156,11 +156,23 @@ spec:
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /prefix-to-be-removed
|
||||
filters:
|
||||
- type: URLRewrite
|
||||
urlRewrite:
|
||||
path:
|
||||
type: ReplacePrefixMatch
|
||||
replacePrefixMatch: ""
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /full-original
|
||||
name: full-path-rewrite
|
||||
filters:
|
||||
- type: URLRewrite
|
||||
urlRewrite:
|
||||
@@ -172,7 +184,7 @@ spec:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: mirror
|
||||
@@ -185,14 +197,23 @@ spec:
|
||||
- filters:
|
||||
- type: RequestMirror
|
||||
requestMirror:
|
||||
fraction:
|
||||
numerator: 4
|
||||
denominator: 8
|
||||
backendRef:
|
||||
name: httpbin-mirror
|
||||
port: 80
|
||||
- type: RequestMirror
|
||||
requestMirror:
|
||||
percent: 80
|
||||
backendRef:
|
||||
name: httpbin-second
|
||||
port: 80
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1alpha2
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http-not-selected
|
||||
@@ -209,4 +230,186 @@ spec:
|
||||
value: /get
|
||||
backendRefs:
|
||||
- name: httpbin-bad
|
||||
port: 80
|
||||
port: 80
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http-timeout-request
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["timeout.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /get
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
timeouts:
|
||||
request: 1ms
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http-timeout-backend-request
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["timeout-backend.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /get
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
timeouts:
|
||||
request: 2ms
|
||||
backendRequest: 1ms
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http-retry-request
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["retry.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /explicit
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
retry:
|
||||
attempts: 3
|
||||
backoff: 3ms
|
||||
codes:
|
||||
- 503
|
||||
- 429
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /empty
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
retry: {}
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /disable
|
||||
backendRefs:
|
||||
- name: httpbin
|
||||
port: 80
|
||||
retry:
|
||||
attempts: 0
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http-route-cors
|
||||
namespace: default
|
||||
spec:
|
||||
hostnames:
|
||||
- "cors.domain.example"
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
rules:
|
||||
- backendRefs:
|
||||
- kind: Service
|
||||
name: httpbin
|
||||
port: 80
|
||||
filters:
|
||||
- cors:
|
||||
allowCredentials: true
|
||||
allowOrigins:
|
||||
# - '*' # This will be allowed in the future, probably https://github.com/kubernetes-sigs/gateway-api/issues/3648#issuecomment-2735208553
|
||||
# - '*.com'
|
||||
- "https://example.com"
|
||||
allowMethods:
|
||||
- GET
|
||||
- HEAD
|
||||
- POST
|
||||
allowHeaders:
|
||||
- Accept
|
||||
- Accept-Language
|
||||
- Content-Language
|
||||
- Content-Type
|
||||
- Range
|
||||
type: CORS
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: multiple-inferencepool-backend-refs
|
||||
namespace: default
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
namespace: higress-system
|
||||
hostnames: ["infpool-multi.domain.example"]
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /infpool
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value
|
||||
type: Exact
|
||||
backendRefs:
|
||||
- name: infpool-gen
|
||||
group: inference.networking.x-k8s.io
|
||||
kind: InferencePool
|
||||
port: 80
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /infpool
|
||||
headers:
|
||||
- name: my-header
|
||||
value: some-value-2
|
||||
type: Exact
|
||||
backendRefs:
|
||||
- name: infpool-gen2
|
||||
group: inference.networking.x-k8s.io
|
||||
kind: InferencePool
|
||||
port: 80
|
||||
---
|
||||
apiVersion: inference.networking.x-k8s.io/v1alpha2
|
||||
kind: InferencePool
|
||||
metadata:
|
||||
name: infpool-gen
|
||||
namespace: default
|
||||
spec:
|
||||
targetPortNumber: 8000
|
||||
selector:
|
||||
app: vllm-llama3-8b-instruct
|
||||
extensionRef:
|
||||
name: vllm-llama3-8b-instruct-epp
|
||||
---
|
||||
apiVersion: inference.networking.x-k8s.io/v1alpha2
|
||||
kind: InferencePool
|
||||
metadata:
|
||||
name: infpool-gen2
|
||||
namespace: default
|
||||
spec:
|
||||
targetPortNumber: 8000
|
||||
selector:
|
||||
app: vllm-llama3-8b-instruct
|
||||
extensionRef:
|
||||
name: vllm-llama3-8b-instruct-epp
|
||||
|
||||
@@ -2,6 +2,7 @@ apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/gateway-semantics: gateway
|
||||
internal.istio.io/gateway-service: higress-gateway.higress-system.svc.domain.suffix
|
||||
internal.istio.io/parents: Gateway/gateway/default.higress-system
|
||||
creationTimestamp: null
|
||||
@@ -20,40 +21,79 @@ apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/parents: HTTPRoute/mirror.default,HTTPRoute/redirect.default,HTTPRoute/rewrite.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-0-istio-autogenerated-k8s-gateway
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~*
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- first.domain.example
|
||||
- '*'
|
||||
http:
|
||||
- headers:
|
||||
request:
|
||||
add:
|
||||
my-added-header: added-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
response:
|
||||
add:
|
||||
my-added-resp-header: added-resp-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /get
|
||||
name: default/http
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /prefix-to-be-removed
|
||||
name: default/rewrite
|
||||
rewrite:
|
||||
uri: /
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /prefix-original
|
||||
name: default/rewrite
|
||||
rewrite:
|
||||
authority: new.example.com
|
||||
uri: /replacement
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /full-original
|
||||
name: default/rewrite
|
||||
rewrite:
|
||||
authority: new.example.com
|
||||
uriRegexRewrite:
|
||||
match: /.*
|
||||
rewrite: /replacement
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- mirrors:
|
||||
- destination:
|
||||
host: httpbin-mirror.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
percentage:
|
||||
value: 50
|
||||
- destination:
|
||||
host: httpbin-second.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
percentage:
|
||||
value: 80
|
||||
name: default/mirror
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- name: default/redirect
|
||||
redirect:
|
||||
port: 8080
|
||||
redirectCode: 302
|
||||
scheme: https
|
||||
uri: /replace-full
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
@@ -62,7 +102,7 @@ metadata:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http-1-istio-autogenerated-k8s-gateway
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~another.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
@@ -96,12 +136,199 @@ spec:
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http-route-cors.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~cors.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- cors.domain.example
|
||||
http:
|
||||
- corsPolicy:
|
||||
allowCredentials: true
|
||||
allowHeaders:
|
||||
- Accept
|
||||
- Accept-Language
|
||||
- Content-Language
|
||||
- Content-Type
|
||||
- Range
|
||||
allowMethods:
|
||||
- GET
|
||||
- HEAD
|
||||
- POST
|
||||
allowOrigins:
|
||||
- exact: https://example.com
|
||||
name: default/http-route-cors
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~first.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- first.domain.example
|
||||
http:
|
||||
- headers:
|
||||
request:
|
||||
add:
|
||||
my-added-header: added-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
response:
|
||||
add:
|
||||
my-added-resp-header: added-resp-value
|
||||
remove:
|
||||
- my-removed-header
|
||||
match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /get
|
||||
name: default/http
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/multiple-inferencepool-backend-refs.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~infpool-multi.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- infpool-multi.domain.example
|
||||
http:
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value
|
||||
uri:
|
||||
prefix: /infpool
|
||||
name: default/multiple-inferencepool-backend-refs
|
||||
route:
|
||||
- destination:
|
||||
host: infpool-gen-ip-6580eb2c.default.svc.domain.suffix
|
||||
- match:
|
||||
- headers:
|
||||
my-header:
|
||||
exact: some-value-2
|
||||
uri:
|
||||
prefix: /infpool
|
||||
name: default/multiple-inferencepool-backend-refs
|
||||
route:
|
||||
- destination:
|
||||
host: infpool-gen2-ip-97b729d1.default.svc.domain.suffix
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/redirect-prefix-replace.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~redirect.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- redirect.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /original
|
||||
name: default/redirect-prefix-replace
|
||||
redirect:
|
||||
port: 8080
|
||||
redirectCode: 302
|
||||
scheme: https
|
||||
uri: '%PREFIX()%/replacement'
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http-retry-request.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~retry.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- retry.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /explicit
|
||||
name: default/http-retry-request
|
||||
retries:
|
||||
attempts: 3
|
||||
backoff: 0.003s
|
||||
retryOn: connect-failure,refused-stream,unavailable,cancelled,503,429
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /disable
|
||||
name: default/http-retry-request
|
||||
retries: {}
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /empty
|
||||
name: default/http-retry-request
|
||||
retries:
|
||||
attempts: 2
|
||||
retryOn: connect-failure,refused-stream,unavailable,cancelled
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/http2.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: http2-0-istio-autogenerated-k8s-gateway
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~second.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
@@ -132,82 +359,51 @@ apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/mirror.default,HTTPRoute/redirect.default,HTTPRoute/rewrite.default
|
||||
internal.istio.io/parents: HTTPRoute/http-timeout-backend-request.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: mirror-0-istio-autogenerated-k8s-gateway
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~timeout-backend.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- '*'
|
||||
- timeout-backend.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /prefix-original
|
||||
name: default/rewrite
|
||||
rewrite:
|
||||
authority: new.example.com
|
||||
uri: /replacement
|
||||
prefix: /get
|
||||
name: default/http-timeout-backend-request
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /full-original
|
||||
name: default/rewrite
|
||||
rewrite:
|
||||
authority: new.example.com
|
||||
uriRegexRewrite:
|
||||
match: /.*
|
||||
rewrite: /replacement
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- mirror:
|
||||
host: httpbin-mirror.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
name: default/mirror
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
- name: default/redirect
|
||||
redirect:
|
||||
port: 8080
|
||||
redirectCode: 302
|
||||
scheme: https
|
||||
uri: /replace-full
|
||||
timeout: 0.001s
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
annotations:
|
||||
internal.istio.io/parents: HTTPRoute/redirect-prefix-replace.default
|
||||
internal.istio.io/parents: HTTPRoute/http-timeout-request.default
|
||||
internal.istio.io/route-semantics: gateway
|
||||
creationTimestamp: null
|
||||
name: redirect-prefix-replace-0-istio-autogenerated-k8s-gateway
|
||||
name: higress-system~gateway-istio-autogenerated-k8s-gateway-default~timeout.domain.example
|
||||
namespace: default
|
||||
spec:
|
||||
gateways:
|
||||
- higress-system/gateway-istio-autogenerated-k8s-gateway-default
|
||||
hosts:
|
||||
- redirect.domain.example
|
||||
- timeout.domain.example
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /original
|
||||
name: default/redirect-prefix-replace
|
||||
redirect:
|
||||
port: 8080
|
||||
redirectCode: 302
|
||||
scheme: https
|
||||
uri: '%PREFIX()%/replacement'
|
||||
prefix: /get
|
||||
name: default/http-timeout-request
|
||||
route:
|
||||
- destination:
|
||||
host: httpbin.default.svc.domain.suffix
|
||||
port:
|
||||
number: 80
|
||||
timeout: 0.001s
|
||||
---
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user