mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-26 15:54:08 +00:00
Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2fe0b9fdc | ||
|
|
217a71e598 | ||
|
|
bbbdd0d299 | ||
|
|
f89622eec7 | ||
|
|
8401ff4d85 | ||
|
|
17b7edca9e | ||
|
|
773149aa53 | ||
|
|
a8b652e59d | ||
|
|
36f217e258 | ||
|
|
c298c0eb06 | ||
|
|
8aabc9f789 | ||
|
|
af1ce628d1 | ||
|
|
707ae396ce | ||
|
|
c0e906629e | ||
|
|
90e601a51e | ||
|
|
2139c813ad | ||
|
|
d6ad578070 | ||
|
|
2758afb1b2 | ||
|
|
70e6c9a49f | ||
|
|
2d46bb300f | ||
|
|
6fbeb6887f | ||
|
|
e533898192 | ||
|
|
72d5c2f0a5 | ||
|
|
e8428e704c | ||
|
|
56bc3b02e9 | ||
|
|
af1fb9a0fd | ||
|
|
8b7950cf61 | ||
|
|
a5de74ec1e | ||
|
|
3aa94842fb | ||
|
|
1a934e1618 | ||
|
|
721c75e44a | ||
|
|
d598d0a6fd | ||
|
|
4a9ecd9ce7 | ||
|
|
a27261bd14 | ||
|
|
0b6092cf2b | ||
|
|
aebccf90d0 | ||
|
|
3f5b5e6593 | ||
|
|
b5a9925042 | ||
|
|
c79f03fe92 | ||
|
|
fedcca1c7b | ||
|
|
b601d28afd | ||
|
|
7d72fa904c | ||
|
|
4d6fa58c0f | ||
|
|
26123cf671 | ||
|
|
ad9cda63c9 | ||
|
|
011e1f1445 | ||
|
|
974d3e88bf | ||
|
|
ef9b6f3cc1 | ||
|
|
144e96df31 | ||
|
|
5ee9c8b38c | ||
|
|
d3ce7ad118 | ||
|
|
a1145f21fe | ||
|
|
edf3be272e | ||
|
|
b4f9db4af8 | ||
|
|
78c0b2c04e | ||
|
|
5d42a3b507 | ||
|
|
1588736b4e | ||
|
|
27965fb8aa | ||
|
|
262daacb63 | ||
|
|
fb17af5e75 | ||
|
|
5122eb575b | ||
|
|
d93e292142 | ||
|
|
f9e15c55ad | ||
|
|
af7f623cba | ||
|
|
d487012468 | ||
|
|
fc8888cb4d | ||
|
|
9558cb8491 | ||
|
|
bde50df3e5 | ||
|
|
dba2676cd9 | ||
|
|
8ee02c6506 | ||
|
|
0751c15ee5 | ||
|
|
1a16e52e36 | ||
|
|
853a077107 | ||
|
|
c5d9f69c9c | ||
|
|
e0f162e47d | ||
|
|
d9fcebb9e8 | ||
|
|
c48ded1994 |
35
.github/actions/deploy-current-branch/README.md
vendored
Normal file
35
.github/actions/deploy-current-branch/README.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# Deploy Current Branch Action
|
||||
|
||||
This GitHub composite action builds a Docker image from the current branch commit and deploys it to a KubeVela cluster for development testing.
|
||||
|
||||
## What it does
|
||||
|
||||
- Generates a unique image tag from the latest commit hash
|
||||
- Builds and loads the Docker image into a KinD cluster
|
||||
- Applies KubeVela CRDs for upgrade safety
|
||||
- Upgrades the KubeVela Helm release to use the local development image
|
||||
- Verifies deployment status and the running image version
|
||||
|
||||
## Usage
|
||||
|
||||
```yaml
|
||||
- name: Deploy Current Branch
|
||||
uses: ./path/to/this/action
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Docker, Helm, kubectl, and KinD must be available in your runner environment
|
||||
- Kubernetes cluster access
|
||||
- `charts/vela-core/crds` directory with CRDs
|
||||
- Valid Helm chart at `charts/vela-core`
|
||||
|
||||
## Steps performed
|
||||
|
||||
1. **Generate commit hash for image tag**
|
||||
2. **Build & load Docker image into KinD**
|
||||
3. **Pre-apply chart CRDs**
|
||||
4. **Upgrade KubeVela using local image**
|
||||
5. **Verify deployment and image version**
|
||||
|
||||
---
|
||||
89
.github/actions/deploy-current-branch/action.yaml
vendored
Normal file
89
.github/actions/deploy-current-branch/action.yaml
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
name: 'Deploy Current Branch'
|
||||
description: 'Builds Docker image from current branch commit and deploys it to KubeVela cluster for development testing'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Git Commit Hash Generation
|
||||
# Generate unique image tag from current branch's latest commit
|
||||
# ========================================================================
|
||||
- name: Get commit hash
|
||||
id: commit_hash
|
||||
shell: bash
|
||||
run: |
|
||||
COMMIT_HASH="git-$(git rev-parse --short HEAD)"
|
||||
echo "Using commit hash: $COMMIT_HASH"
|
||||
echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_ENV
|
||||
|
||||
# ========================================================================
|
||||
# Docker Image Build and Cluster Loading
|
||||
# Build development image from current code and load into KinD cluster
|
||||
# ========================================================================
|
||||
- name: Build and load Docker image
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Building development image: vela-core-test:${{ env.COMMIT_HASH }}"
|
||||
|
||||
mkdir -p $HOME/tmp/
|
||||
|
||||
docker build --no-cache \
|
||||
-t vela-core-test:${{ env.COMMIT_HASH }} \
|
||||
-f Dockerfile .
|
||||
|
||||
echo "Loading image into KinD cluster..."
|
||||
TMPDIR=$HOME/tmp/ kind load docker-image vela-core-test:${{ env.COMMIT_HASH }}
|
||||
|
||||
# ========================================================================
|
||||
# Custom Resource Definitions Application
|
||||
# Pre-apply CRDs to ensure upgrade compatibility and prevent conflicts
|
||||
# ========================================================================
|
||||
- name: Pre-apply CRDs from target chart (upgrade-safe)
|
||||
shell: bash
|
||||
run: |
|
||||
CRD_DIR="charts/vela-core/crds"
|
||||
|
||||
echo "Applying CRDs idempotently..."
|
||||
kubectl apply -f "${CRD_DIR}"
|
||||
|
||||
# ========================================================================
|
||||
# KubeVela Helm Chart Upgrade
|
||||
# Upgrade existing installation to use locally built development image
|
||||
# ========================================================================
|
||||
- name: Upgrade KubeVela to development image
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Upgrading KubeVela to development version..."
|
||||
helm upgrade kubevela ./charts/vela-core \
|
||||
--namespace vela-system \
|
||||
--set image.repository=vela-core-test \
|
||||
--set image.tag=${{ env.COMMIT_HASH }} \
|
||||
--set image.pullPolicy=IfNotPresent \
|
||||
--timeout 5m \
|
||||
--wait \
|
||||
--debug
|
||||
|
||||
# ========================================================================
|
||||
# Deployment Status Verification
|
||||
# Verify successful upgrade and confirm correct image deployment
|
||||
# ========================================================================
|
||||
- name: Verify deployment status
|
||||
shell: bash
|
||||
run: |
|
||||
echo "=== DEPLOYMENT VERIFICATION ==="
|
||||
echo "Verifying upgrade to local development image..."
|
||||
|
||||
echo "--- Pod Status ---"
|
||||
kubectl get pods -n vela-system
|
||||
|
||||
echo "--- Deployment Rollout ---"
|
||||
kubectl rollout status deployment/kubevela-vela-core \
|
||||
-n vela-system \
|
||||
--timeout=300s
|
||||
|
||||
echo "--- Deployed Image Version ---"
|
||||
kubectl get deployment kubevela-vela-core \
|
||||
-n vela-system \
|
||||
-o yaml | grep "image:" | head -1
|
||||
|
||||
echo "Deployment verification completed successfully!"
|
||||
32
.github/actions/deploy-latest-release/README.md
vendored
Normal file
32
.github/actions/deploy-latest-release/README.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# Install Latest KubeVela Release Action
|
||||
|
||||
This GitHub composite action installs the latest stable KubeVela release from the official Helm repository and verifies its deployment status.
|
||||
|
||||
## What it does
|
||||
|
||||
- Discovers the latest stable KubeVela release tag from GitHub
|
||||
- Adds and updates the official KubeVela Helm chart repository
|
||||
- Installs KubeVela into the `vela-system` namespace (using Helm)
|
||||
- Verifies pod status and deployment rollout for successful installation
|
||||
|
||||
## Usage
|
||||
|
||||
```yaml
|
||||
- name: Install Latest KubeVela Release
|
||||
uses: ./path/to/this/action
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Helm, kubectl, jq, and curl must be available in your runner environment
|
||||
- Kubernetes cluster access
|
||||
|
||||
## Steps performed
|
||||
|
||||
1. **Release Tag Discovery:** Fetches latest stable tag (without `v` prefix)
|
||||
2. **Helm Repo Setup:** Adds/updates KubeVela Helm chart repo
|
||||
3. **Install KubeVela:** Installs latest release in the `vela-system` namespace
|
||||
4. **Status Verification:** Checks pod status and rollout for readiness
|
||||
|
||||
---
|
||||
|
||||
68
.github/actions/deploy-latest-release/action.yaml
vendored
Normal file
68
.github/actions/deploy-latest-release/action.yaml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: 'Install Latest KubeVela Release'
|
||||
description: 'Installs the latest stable KubeVela release from official Helm repository with status verification'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Latest Release Tag Discovery
|
||||
# Fetch current stable release version from GitHub API
|
||||
# ========================================================================
|
||||
- name: Get latest KubeVela release tag (no v prefix)
|
||||
id: get_latest_tag
|
||||
shell: bash
|
||||
run: |
|
||||
TAG=$(curl -s https://api.github.com/repos/kubevela/kubevela/releases/latest | \
|
||||
jq -r ".tag_name" | \
|
||||
awk '{sub(/^v/, ""); print}')
|
||||
echo "LATEST_TAG=$TAG" >> $GITHUB_ENV
|
||||
echo "Discovered latest release: $TAG"
|
||||
|
||||
# ========================================================================
|
||||
# Helm Repository Configuration
|
||||
# Add and update official KubeVela chart repository
|
||||
# ========================================================================
|
||||
- name: Add KubeVela Helm repo
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Adding KubeVela Helm repository..."
|
||||
helm repo add kubevela https://kubevela.github.io/charts
|
||||
helm repo update
|
||||
echo "Helm repository configuration completed"
|
||||
|
||||
# ========================================================================
|
||||
# KubeVela Stable Release Installation
|
||||
# Deploy latest stable version to vela-system namespace
|
||||
# ========================================================================
|
||||
- name: Install KubeVela ${{ env.LATEST_TAG }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Installing KubeVela version: ${{ env.LATEST_TAG }}"
|
||||
helm install \
|
||||
--create-namespace \
|
||||
-n vela-system \
|
||||
kubevela kubevela/vela-core \
|
||||
--version ${{ env.LATEST_TAG }} \
|
||||
--timeout 10m \
|
||||
--wait
|
||||
echo "KubeVela installation completed"
|
||||
|
||||
# ========================================================================
|
||||
# Installation Status Verification
|
||||
# Verify successful deployment and readiness of KubeVela components
|
||||
# ========================================================================
|
||||
- name: Post-install status
|
||||
shell: bash
|
||||
run: |
|
||||
echo "=== INSTALLATION VERIFICATION ==="
|
||||
echo "Verifying KubeVela deployment status..."
|
||||
|
||||
echo "--- Pod Status ---"
|
||||
kubectl get pods -n vela-system
|
||||
|
||||
echo "--- Deployment Rollout ---"
|
||||
kubectl rollout status deployment/kubevela-vela-core \
|
||||
-n vela-system \
|
||||
--timeout=300s
|
||||
|
||||
echo "KubeVela installation verification completed successfully!"
|
||||
51
.github/actions/e2e-test/README.md
vendored
Normal file
51
.github/actions/e2e-test/README.md
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# Kubevela K8s Upgrade E2E Test Action
|
||||
|
||||
A comprehensive GitHub composite action for running KubeVela Kubernetes upgrade end-to-end (E2E) tests with complete environment setup, multiple test suites, and failure diagnostics.
|
||||
|
||||
|
||||
> **Note**: This action requires the `GO_VERSION` environment variable to be set in your workflow.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```yaml
|
||||
name: E2E Tests
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
e2e-tests:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GO_VERSION: '1.23.8'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run KubeVela E2E Tests
|
||||
uses: ./.github/actions/upgrade-e2e-test
|
||||
```
|
||||
|
||||
## Test Flow Diagram
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Environment │ │ E2E Environment │ │ Test Execution │
|
||||
│ Setup │───▶│ Preparation │───▶│ (3 Suites) │
|
||||
│ │ │ │ │ │
|
||||
│ • Install tools │ │ • Cleanup │ │ • API tests │
|
||||
│ • Setup Go │ │ • Core setup │ │ • Addon tests │
|
||||
│ • Dependencies │ │ • Helm tests │ │ • General tests │
|
||||
│ • Build project │ │ │ │ │
|
||||
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Diagnostics │
|
||||
│ (On Failure) │
|
||||
│ │
|
||||
│ • Cluster logs │
|
||||
│ • System events │
|
||||
│ • Test artifacts│
|
||||
└─────────────────┘
|
||||
```
|
||||
96
.github/actions/e2e-test/action.yaml
vendored
Normal file
96
.github/actions/e2e-test/action.yaml
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
name: 'Kubevela K8s Upgrade e2e Test'
|
||||
description: 'Runs Kubevela K8s upgrade e2e tests, uploads coverage, and collects diagnostics on failure.'
|
||||
|
||||
inputs:
|
||||
codecov-token:
|
||||
description: 'Codecov token for uploading coverage reports'
|
||||
required: false
|
||||
default: ''
|
||||
codecov-enable:
|
||||
description: 'Enable codecov coverage upload'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Environment Setup
|
||||
# ========================================================================
|
||||
- name: Configure environment setup
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
- name: Build project
|
||||
shell: bash
|
||||
run: make
|
||||
|
||||
# ========================================================================
|
||||
# E2E Test Environment Preparation
|
||||
# ========================================================================
|
||||
- name: Prepare e2e environment
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Preparing e2e test environment..."
|
||||
make e2e-cleanup
|
||||
make e2e-setup-core
|
||||
|
||||
echo "Running Helm tests..."
|
||||
helm test -n vela-system kubevela --timeout 5m
|
||||
|
||||
# ========================================================================
|
||||
# E2E Test Execution
|
||||
# ========================================================================
|
||||
- name: Run API e2e tests
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Running API e2e tests..."
|
||||
make e2e-api-test
|
||||
|
||||
- name: Run addon e2e tests
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Running addon e2e tests..."
|
||||
make e2e-addon-test
|
||||
|
||||
- name: Run general e2e tests
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Running general e2e tests..."
|
||||
make e2e-test
|
||||
|
||||
- name: Upload coverage report
|
||||
if: ${{ inputs.codecov-enable == 'true' }}
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24
|
||||
with:
|
||||
token: ${{ inputs.codecov-token }}
|
||||
files: ./coverage.txt
|
||||
flags: core-unittests
|
||||
name: codecov-umbrella
|
||||
fail_ci_if_error: false
|
||||
|
||||
# ========================================================================
|
||||
# Failure Diagnostics
|
||||
# ========================================================================
|
||||
- name: Collect failure diagnostics
|
||||
if: failure()
|
||||
shell: bash
|
||||
run: |
|
||||
echo "=== FAILURE DIAGNOSTICS ==="
|
||||
echo "Collecting diagnostic information for debugging..."
|
||||
|
||||
echo "--- Cluster Status ---"
|
||||
kubectl get nodes -o wide || true
|
||||
kubectl get pods -A || true
|
||||
|
||||
echo "--- KubeVela System Logs ---"
|
||||
kubectl logs -n vela-system -l app.kubernetes.io/name=vela-core --tail=100 || true
|
||||
|
||||
echo "--- Recent Events ---"
|
||||
kubectl get events -A --sort-by='.lastTimestamp' --field-selector type!=Normal || true
|
||||
|
||||
echo "--- Helm Release Status ---"
|
||||
helm list -A || true
|
||||
helm status kubevela -n vela-system || true
|
||||
|
||||
echo "--- Test Artifacts ---"
|
||||
find . -name "*.log" -type f -exec echo "=== {} ===" \; -exec cat {} \; || true
|
||||
67
.github/actions/env-setup/README.md
vendored
Normal file
67
.github/actions/env-setup/README.md
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# Kubevela Test Environment Setup Action
|
||||
|
||||
A GitHub Actions composite action that sets up a complete testing environment for Kubevela projects with Go, Kubernetes tools, and the Ginkgo testing framework.
|
||||
|
||||
## Features
|
||||
|
||||
- 🛠️ **System Dependencies**: Installs essential build tools (make, gcc, jq, curl, etc.)
|
||||
- ☸️ **Kubernetes Tools**: Sets up kubectl and Helm for cluster operations
|
||||
- 🐹 **Go Environment**: Configurable Go version with module caching
|
||||
- 📦 **Dependency Management**: Downloads and verifies Go module dependencies
|
||||
- 🧪 **Testing Framework**: Installs Ginkgo v2 for BDD-style testing
|
||||
|
||||
## Usage
|
||||
|
||||
```yaml
|
||||
- name: Setup Kubevela Test Environment
|
||||
uses: ./path/to/this/action
|
||||
with:
|
||||
go-version: '1.23.8' # Optional: Go version (default: 1.23.8)
|
||||
```
|
||||
|
||||
### Example Workflow
|
||||
|
||||
```yaml
|
||||
name: Kubevela Tests
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Test Environment
|
||||
uses: ./path/to/this/action
|
||||
with:
|
||||
go-version: '1.21'
|
||||
|
||||
- name: Run Tests
|
||||
run: |
|
||||
ginkgo -r ./tests/e2e/
|
||||
```
|
||||
|
||||
## Inputs
|
||||
|
||||
| Input | Description | Required | Default | Usage |
|
||||
|-------|-------------|----------|---------|-------|
|
||||
| `go-version` | Go version to install and use | No | `1.23.8` | Specify Go version for your project |
|
||||
|
||||
## What This Action Installs
|
||||
|
||||
### System Tools
|
||||
- **make**: Build automation tool
|
||||
- **gcc**: GNU Compiler Collection
|
||||
- **jq**: JSON processor for shell scripts
|
||||
- **ca-certificates**: SSL/TLS certificates
|
||||
- **curl**: HTTP client for downloads
|
||||
- **gnupg**: GNU Privacy Guard for security
|
||||
|
||||
### Kubernetes Ecosystem
|
||||
- **kubectl**: Kubernetes command-line tool (latest stable)
|
||||
- **helm**: Kubernetes package manager (latest stable)
|
||||
|
||||
### Go Development
|
||||
- **Go Runtime**: Specified version with module caching enabled
|
||||
- **Go Modules**: Downloaded and verified dependencies
|
||||
- **Ginkgo v2.14.0**: BDD testing framework for Go
|
||||
72
.github/actions/env-setup/action.yaml
vendored
Normal file
72
.github/actions/env-setup/action.yaml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: 'Kubevela Test Environment Setup'
|
||||
description: 'Sets up complete testing environment for Kubevela with Go, Kubernetes tools, and Ginkgo framework for E2E testing.'
|
||||
|
||||
inputs:
|
||||
go-version:
|
||||
description: 'Go version to use for testing'
|
||||
required: false
|
||||
default: '1.23.8'
|
||||
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Environment Setup
|
||||
# ========================================================================
|
||||
- name: Install system dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
# Update package manager and install essential tools
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
make \
|
||||
gcc \
|
||||
jq \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg
|
||||
|
||||
- name: Install kubectl and helm
|
||||
shell: bash
|
||||
run: |
|
||||
# Detect architecture
|
||||
ARCH=$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')
|
||||
|
||||
# Install kubectl
|
||||
echo "Installing kubectl for architecture: $ARCH"
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${ARCH}/kubectl"
|
||||
chmod +x kubectl
|
||||
sudo mv kubectl /usr/local/bin/
|
||||
|
||||
# Install helm using the official script (more reliable)
|
||||
echo "Installing Helm using official script..."
|
||||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
chmod 700 get_helm.sh
|
||||
./get_helm.sh
|
||||
rm get_helm.sh
|
||||
|
||||
# Verify installations
|
||||
echo "Verifying installations..."
|
||||
kubectl version --client
|
||||
helm version
|
||||
|
||||
|
||||
- name: Setup Go environment
|
||||
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
cache: true
|
||||
|
||||
- name: Download Go dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
# Download and cache Go module dependencies
|
||||
go mod download
|
||||
go mod verify
|
||||
|
||||
- name: Install Ginkgo testing framework
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Installing Ginkgo testing framework..."
|
||||
go install github.com/onsi/ginkgo/v2/ginkgo@v2.14.0
|
||||
35
.github/actions/multicluster-test/README.md
vendored
Normal file
35
.github/actions/multicluster-test/README.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# Kubevela K8s Upgrade Multicluster E2E Test Action
|
||||
|
||||
A comprehensive GitHub Actions composite action for running Kubevela Kubernetes upgrade multicluster end-to-end tests with automated coverage reporting and failure diagnostics.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
```yaml
|
||||
name: Kubevela Multicluster E2E Tests
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
multicluster-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Multicluster E2E Tests
|
||||
uses: ./.github/actions/multicluster-test
|
||||
with:
|
||||
codecov-enable: 'true'
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
```
|
||||
|
||||
## Inputs
|
||||
|
||||
| Input | Description | Required | Default | Type |
|
||||
|-------|-------------|----------|---------|------|
|
||||
| `codecov-token` | Codecov token for uploading coverage reports | No | `''` | string |
|
||||
| `codecov-enable` | Enable codecov coverage upload | No | `'false'` | string |
|
||||
76
.github/actions/multicluster-test/action.yaml
vendored
Normal file
76
.github/actions/multicluster-test/action.yaml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
name: 'Kubevela K8s Upgrade Multicluster E2E Test'
|
||||
description: 'Runs Kubevela Kubernetes upgrade multicluster end-to-end tests, uploads coverage, and collects diagnostics on failure.'
|
||||
author: 'viskumar_gwre'
|
||||
|
||||
inputs:
|
||||
codecov-token:
|
||||
description: 'Codecov token for uploading coverage reports'
|
||||
required: false
|
||||
default: ''
|
||||
codecov-enable:
|
||||
description: 'Enable codecov coverage upload'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Environment Setup
|
||||
# ========================================================================
|
||||
- name: Configure environment setup
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
# ========================================================================
|
||||
# E2E Test Execution
|
||||
# ========================================================================
|
||||
- name: Prepare e2e test environment
|
||||
shell: bash
|
||||
run: |
|
||||
# Build CLI tools and prepare test environment
|
||||
echo "Building KubeVela CLI..."
|
||||
make vela-cli
|
||||
|
||||
echo "Cleaning up previous test artifacts..."
|
||||
make e2e-cleanup
|
||||
|
||||
echo "Setting up core authentication for e2e tests..."
|
||||
make e2e-setup-core-auth
|
||||
|
||||
- name: Execute multicluster upgrade e2e tests
|
||||
shell: bash
|
||||
run: |
|
||||
# Add built CLI to PATH and run multicluster tests
|
||||
export PATH=$(pwd)/bin:$PATH
|
||||
|
||||
echo "Running e2e multicluster upgrade tests..."
|
||||
make e2e-multicluster-test
|
||||
|
||||
- name: Upload coverage report
|
||||
if: ${{ inputs.codecov-enable == 'true' }}
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24
|
||||
with:
|
||||
token: ${{ inputs.codecov-token }}
|
||||
files: /tmp/e2e-profile.out,/tmp/e2e_multicluster_test.out
|
||||
flags: e2e-multicluster-test
|
||||
name: codecov-umbrella
|
||||
|
||||
# ========================================================================
|
||||
# Failure Diagnostics
|
||||
# ========================================================================
|
||||
- name: Collect failure diagnostics
|
||||
if: failure()
|
||||
shell: bash
|
||||
run: |
|
||||
echo "=== FAILURE DIAGNOSTICS ==="
|
||||
echo "Collecting diagnostic information for debugging..."
|
||||
|
||||
echo "--- Cluster Status ---"
|
||||
kubectl get nodes -o wide || true
|
||||
kubectl get pods -A || true
|
||||
|
||||
echo "--- KubeVela System Logs ---"
|
||||
kubectl logs -n vela-system -l app.kubernetes.io/name=vela-core --tail=100 || true
|
||||
|
||||
echo "--- Recent Events ---"
|
||||
kubectl get events -A --sort-by='.lastTimestamp' --field-selector type!=Normal || true
|
||||
78
.github/actions/setup-kind-cluster/README.md
vendored
Normal file
78
.github/actions/setup-kind-cluster/README.md
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# Setup Kind Cluster Action
|
||||
|
||||
A GitHub Action that sets up a Kubernetes testing environment using Kind (Kubernetes in Docker) for E2E testing.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Input | Description | Required | Default |
|
||||
|-------|-------------|----------|---------|
|
||||
| `k8s-version` | Kubernetes version for the kind cluster | No | `v1.31.9` |
|
||||
|
||||
## Quick Start
|
||||
|
||||
```yaml
|
||||
name: E2E Tests
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.21'
|
||||
|
||||
- name: Setup Kind Cluster
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
k8s-version: 'v1.31.9'
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
kubectl cluster-info
|
||||
make test-e2e
|
||||
```
|
||||
|
||||
## What it does
|
||||
|
||||
1. **Installs Kind CLI** - Downloads Kind v0.29.0 using Go
|
||||
2. **Cleans up** - Removes any existing Kind clusters
|
||||
3. **Creates cluster** - Spins up Kubernetes v1.31.9 cluster
|
||||
4. **Sets up environment** - Configures KUBECONFIG for kubectl access
|
||||
5. **Loads images** - Builds and loads Docker images using `make image-load`
|
||||
|
||||
## File Structure
|
||||
|
||||
Save as `.github/actions/setup-kind-cluster/action.yaml`:
|
||||
|
||||
```yaml
|
||||
name: 'SetUp kind cluster'
|
||||
description: 'Sets up complete testing environment for Kubevela with Go, Kubernetes tools, and Ginkgo framework for E2E testing.'
|
||||
|
||||
inputs:
|
||||
k8s-version:
|
||||
description: 'Kubernetes version for the kind cluster'
|
||||
required: false
|
||||
default: 'v1.31.9'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Kind cluster Setup
|
||||
# ========================================================================
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.29.0
|
||||
kind delete cluster || true
|
||||
kind create cluster --image=kindest/node:${{ inputs.k8s-version }}
|
||||
shell: bash
|
||||
|
||||
- name: Load image
|
||||
run: |
|
||||
mkdir -p $HOME/tmp/
|
||||
TMPDIR=$HOME/tmp/ make image-load
|
||||
shell: bash
|
||||
```
|
||||
36
.github/actions/setup-kind-cluster/action.yaml
vendored
Normal file
36
.github/actions/setup-kind-cluster/action.yaml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: 'SetUp kind cluster'
|
||||
description: 'Sets up a KinD (Kubernetes in Docker) cluster with configurable Kubernetes version and optional cluster naming for testing and development workflows.'
|
||||
inputs:
|
||||
k8s-version:
|
||||
description: 'Kubernetes version for the kind cluster'
|
||||
required: false
|
||||
default: 'v1.31.9'
|
||||
name:
|
||||
description: 'Name of the kind cluster'
|
||||
required: false
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Kind cluster Setup
|
||||
# ========================================================================
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.29.0
|
||||
if [ -n "${{ inputs.name }}" ]; then
|
||||
kind delete cluster --name="${{ inputs.name }}" || true
|
||||
kind create cluster --name="${{ inputs.name }}" --image=kindest/node:${{ inputs.k8s-version }}
|
||||
kind export kubeconfig --internal --name="${{ inputs.name }}" --kubeconfig /tmp/${{ inputs.name }}.kubeconfig
|
||||
else
|
||||
kind delete cluster || true
|
||||
kind create cluster --image=kindest/node:${{ inputs.k8s-version }}
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Load image
|
||||
run: |
|
||||
if [ -z "${{ inputs.name }}" ]; then
|
||||
mkdir -p $HOME/tmp/
|
||||
TMPDIR=$HOME/tmp/ make image-load
|
||||
fi
|
||||
shell: bash
|
||||
34
.github/actions/unit-test/README.md
vendored
Normal file
34
.github/actions/unit-test/README.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# Kubevela K8s Upgrade Unit Test Action
|
||||
|
||||
A comprehensive GitHub composite action for running KubeVela Kubernetes upgrade unit tests with coverage reporting and failure diagnostics.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Input | Description | Required | Default |
|
||||
|-------|-------------|----------|---------|
|
||||
| `codecov-token` | Codecov token for uploading coverage reports | ❌ | `''` |
|
||||
| `codecov-enable` | Enable Codecov coverage upload (`'true'` or `'false'`) | ❌ | `'false'` |
|
||||
| `go-version` | Go version to use for testing | ❌ | `'1.23.8'` |
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```yaml
|
||||
name: Unit Tests with Coverage
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run KubeVela Unit Tests
|
||||
uses: viskumar_gwre/kubevela-k8s-upgrade-unit-test-action@v1
|
||||
with:
|
||||
codecov-enable: 'true'
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
go-version: '1.23.8'
|
||||
```
|
||||
67
.github/actions/unit-test/action.yaml
vendored
Normal file
67
.github/actions/unit-test/action.yaml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: 'Kubevela K8s Upgrade Unit Test'
|
||||
description: 'Runs Kubevela K8s upgrade unit tests, uploads coverage, and collects diagnostics on failure.'
|
||||
|
||||
inputs:
|
||||
codecov-token:
|
||||
description: 'Codecov token for uploading coverage reports'
|
||||
required: false
|
||||
default: ''
|
||||
codecov-enable:
|
||||
description: 'Enable codecov coverage upload'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Environment Setup
|
||||
# ========================================================================
|
||||
- name: Configure environment setup
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
# ========================================================================
|
||||
# Unit Test Execution
|
||||
# ========================================================================
|
||||
- name: Run unit tests
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Running unit tests..."
|
||||
make test
|
||||
|
||||
- name: Upload coverage report
|
||||
if: ${{ inputs.codecov-enable == 'true' }}
|
||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24
|
||||
with:
|
||||
token: ${{ inputs.codecov-token }}
|
||||
files: ./coverage.txt
|
||||
flags: core-unittests
|
||||
name: codecov-umbrella
|
||||
fail_ci_if_error: false
|
||||
|
||||
# ========================================================================
|
||||
# Failure Diagnostics
|
||||
# ========================================================================
|
||||
- name: Collect failure diagnostics
|
||||
if: failure()
|
||||
shell: bash
|
||||
run: |
|
||||
echo "=== FAILURE DIAGNOSTICS ==="
|
||||
echo "Collecting diagnostic information for debugging..."
|
||||
|
||||
echo "--- Go Environment ---"
|
||||
go version || true
|
||||
go env || true
|
||||
|
||||
echo "--- Cluster Status ---"
|
||||
kubectl get nodes -o wide || true
|
||||
kubectl get pods -A || true
|
||||
|
||||
echo "--- KubeVela System Logs ---"
|
||||
kubectl logs -n vela-system -l app.kubernetes.io/name=vela-core --tail=100 || true
|
||||
|
||||
echo "--- Recent Events ---"
|
||||
kubectl get events -A --sort-by='.lastTimestamp' --field-selector type!=Normal || true
|
||||
|
||||
echo "--- Test Artifacts ---"
|
||||
find . -name "*.log" -o -name "*test*.xml" -o -name "coverage.*" | head -20 || true
|
||||
4
.github/workflows/back-port.yml
vendored
4
.github/workflows/back-port.yml
vendored
@@ -17,12 +17,12 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Open Backport PR
|
||||
uses: zeebe-io/backport-action@08bafb375e6e9a9a2b53a744b987e5d81a133191
|
||||
uses: zeebe-io/backport-action@0193454f0c5947491d348f33a275c119f30eb736
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_workspace: ${{ github.workspace }}
|
||||
|
||||
4
.github/workflows/chart.yml
vendored
4
.github/workflows/chart.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
HELM_CHART_NAME: vela-core
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
- name: Get git revision
|
||||
id: vars
|
||||
shell: bash
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
with:
|
||||
version: v3.4.0
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Generate helm doc
|
||||
|
||||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -26,12 +26,12 @@ jobs:
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
|
||||
uses: github/codeql-action/init@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
|
||||
uses: github/codeql-action/autobuild@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
|
||||
uses: github/codeql-action/analyze@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
|
||||
|
||||
6
.github/workflows/core-api-test.yml
vendored
6
.github/workflows/core-api-test.yml
vendored
@@ -16,10 +16,10 @@ jobs:
|
||||
core-api-test:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Go 1.22
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
- name: Set up Go 1.23.8
|
||||
uses: actions/setup-go@v5
|
||||
env:
|
||||
GO_VERSION: '1.22'
|
||||
GO_VERSION: '1.23.8'
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
id: go
|
||||
|
||||
12
.github/workflows/definition-lint.yml
vendored
12
.github/workflows/definition-lint.yml
vendored
@@ -16,26 +16,26 @@ permissions:
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.22'
|
||||
GO_VERSION: '1.23.8'
|
||||
|
||||
jobs:
|
||||
definition-doc:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.19.0
|
||||
kind create cluster
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
name: linter
|
||||
|
||||
- name: Definition Doc generate check
|
||||
run: |
|
||||
|
||||
76
.github/workflows/e2e-multicluster-test.yml
vendored
76
.github/workflows/e2e-multicluster-test.yml
vendored
@@ -18,7 +18,7 @@ permissions:
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.22'
|
||||
GO_VERSION: '1.23.8'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -44,70 +44,40 @@ jobs:
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
k8s-version: ["v1.29"]
|
||||
k8s-version: ["v1.31.9"]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install make gcc jq ca-certificates curl gnupg -y
|
||||
sudo snap install kubectl --classic
|
||||
sudo snap install helm --classic
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
- name: Setup worker cluster kinD
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
name: worker
|
||||
k8s-version: ${{ matrix.k8s-version }}
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.24.0
|
||||
kind delete cluster --name worker || true
|
||||
kind create cluster --name worker --image=kindest/node:v1.29.8
|
||||
kind export kubeconfig --internal --name worker --kubeconfig /tmp/worker.kubeconfig
|
||||
kind delete cluster || true
|
||||
kind create cluster --image=kindest/node:v1.29.8
|
||||
|
||||
- name: Load image
|
||||
run: |
|
||||
mkdir -p $HOME/tmp/
|
||||
TMPDIR=$HOME/tmp/ make image-load
|
||||
|
||||
- name: Cleanup for e2e tests
|
||||
run: |
|
||||
make vela-cli
|
||||
make e2e-cleanup
|
||||
make e2e-setup-core-auth
|
||||
|
||||
- name: Run e2e multicluster tests
|
||||
run: |
|
||||
export PATH=$(pwd)/bin:$PATH
|
||||
make e2e-multicluster-test
|
||||
|
||||
- name: Stop kubevela, get profile
|
||||
run: |
|
||||
make end-e2e-core-shards
|
||||
|
||||
- name: Upload coverage report
|
||||
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
|
||||
- name: Setup master cluster kinD
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: /tmp/e2e-profile.out,/tmp/e2e_multicluster_test.out
|
||||
flags: e2e-multicluster-test
|
||||
name: codecov-umbrella
|
||||
k8s-version: ${{ matrix.k8s-version }}
|
||||
|
||||
- name: Run upgrade multicluster tests
|
||||
uses: ./.github/actions/multicluster-test
|
||||
with:
|
||||
codecov-enable: true
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Clean e2e profile
|
||||
run: rm /tmp/e2e-profile.out
|
||||
run: |
|
||||
if [ -f /tmp/e2e-profile.out ]; then
|
||||
rm /tmp/e2e-profile.out
|
||||
echo "E2E profile cleaned"
|
||||
else
|
||||
echo "E2E profile not found, skipping cleanup"
|
||||
fi
|
||||
|
||||
- name: Cleanup image
|
||||
if: ${{ always() }}
|
||||
|
||||
78
.github/workflows/e2e-test.yml
vendored
78
.github/workflows/e2e-test.yml
vendored
@@ -18,7 +18,7 @@ permissions:
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.22'
|
||||
GO_VERSION: '1.23.8'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -44,77 +44,35 @@ jobs:
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
k8s-version: ["v1.29"]
|
||||
k8s-version: ["v1.31"]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install make gcc jq ca-certificates curl gnupg -y
|
||||
sudo snap install kubectl --classic
|
||||
sudo snap install helm --classic
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.24.0
|
||||
kind delete cluster || true
|
||||
kind create cluster --image=kindest/node:v1.29.8
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
|
||||
- name: Get Ginkgo
|
||||
run: |
|
||||
go install github.com/onsi/ginkgo/v2/ginkgo@v2.14.0
|
||||
|
||||
- name: Load image
|
||||
run: |
|
||||
mkdir -p $HOME/tmp/
|
||||
TMPDIR=$HOME/tmp/ make image-load
|
||||
|
||||
- name: Run Make
|
||||
run: make
|
||||
|
||||
- name: Prepare for e2e tests
|
||||
run: |
|
||||
make e2e-cleanup
|
||||
make e2e-setup-core
|
||||
helm test -n vela-system kubevela --timeout 5m
|
||||
|
||||
- name: Run api e2e tests
|
||||
run: make e2e-api-test
|
||||
|
||||
- name: Run addons e2e tests
|
||||
run: make e2e-addon-test
|
||||
|
||||
- name: Run e2e tests
|
||||
run: make e2e-test
|
||||
|
||||
- name: Stop kubevela, get profile
|
||||
run: make end-e2e
|
||||
|
||||
- name: Upload coverage report
|
||||
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
|
||||
# ========================================================================
|
||||
# E2E Test Execution
|
||||
# ========================================================================
|
||||
- name: Run upgrade e2e tests
|
||||
uses: ./.github/actions/e2e-test
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: /tmp/e2e-profile.out
|
||||
flags: e2etests
|
||||
name: codecov-umbrella
|
||||
codecov-enable: true
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Clean e2e profile
|
||||
run: rm /tmp/e2e-profile.out
|
||||
run: |
|
||||
if [ -f /tmp/e2e-profile.out ]; then
|
||||
rm /tmp/e2e-profile.out
|
||||
echo "E2E profile cleaned"
|
||||
else
|
||||
echo "E2E profile not found, skipping cleanup"
|
||||
fi
|
||||
|
||||
- name: Cleanup image
|
||||
if: ${{ always() }}
|
||||
|
||||
77
.github/workflows/go.yml
vendored
77
.github/workflows/go.yml
vendored
@@ -11,16 +11,15 @@ on:
|
||||
- master
|
||||
- release-*
|
||||
|
||||
permissions: # added using https://github.com/step-security/secure-workflows
|
||||
permissions: # added using https://github.com/step-security/secure-workflows
|
||||
contents: read
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.22'
|
||||
GOLANGCI_VERSION: 'v1.54.2'
|
||||
GO_VERSION: "1.23.8"
|
||||
GOLANGCI_VERSION: "v1.60.1"
|
||||
|
||||
jobs:
|
||||
|
||||
detect-noop:
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
@@ -44,12 +43,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -64,17 +63,17 @@ jobs:
|
||||
needs: detect-noop
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
|
||||
steps:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -83,7 +82,7 @@ jobs:
|
||||
# version, but we prefer this action because it leaves 'annotations' (i.e.
|
||||
# it comments on PRs to point out linter violations).
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: ${{ env.GOLANGCI_VERSION }}
|
||||
|
||||
@@ -94,32 +93,20 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Setup Env
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: "14"
|
||||
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
|
||||
with:
|
||||
path: .work/pkg
|
||||
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: ${{ runner.os }}-pkg-
|
||||
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.19.0
|
||||
kind delete cluster --name kind || true
|
||||
kind create cluster --name kind --image=kindest/node:v1.26.4 --kubeconfig ~/.kube/config
|
||||
- name: Setup kinD
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
|
||||
- name: Run cross-build
|
||||
run: make cross-build
|
||||
@@ -128,7 +115,7 @@ jobs:
|
||||
run: |
|
||||
export PATH=$(pwd)/bin/:$PATH
|
||||
make check-diff
|
||||
|
||||
|
||||
- name: Cleanup binary
|
||||
run: make build-cleanup
|
||||
|
||||
@@ -139,17 +126,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .work/pkg
|
||||
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
|
||||
@@ -170,15 +157,15 @@ jobs:
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435
|
||||
- name: Build Test for vela core
|
||||
uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
@@ -190,15 +177,15 @@ jobs:
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
- name: Build Test for CLI
|
||||
uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435
|
||||
- name: Build Test for CLI
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.cli
|
||||
file: Dockerfile.cli
|
||||
8
.github/workflows/issue-commands.yml
vendored
8
.github/workflows/issue-commands.yml
vendored
@@ -25,15 +25,15 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
|
||||
with:
|
||||
node-version: '14'
|
||||
cache: 'npm'
|
||||
node-version: "14"
|
||||
cache: "npm"
|
||||
cache-dependency-path: ./actions/package-lock.json
|
||||
- name: Install Dependencies
|
||||
run: npm ci --production --prefix ./actions
|
||||
- name: Run Commands
|
||||
uses: ./actions/commands
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.GH_KUBEVELA_COMMAND_WORKFLOW }}
|
||||
configPath: issue-commands
|
||||
|
||||
backport:
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Open Backport PR
|
||||
uses: zeebe-io/backport-action@08bafb375e6e9a9a2b53a744b987e5d81a133191
|
||||
uses: zeebe-io/backport-action@0193454f0c5947491d348f33a275c119f30eb736
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_workspace: ${{ github.workspace }}
|
||||
|
||||
198
.github/workflows/registry.yml
vendored
198
.github/workflows/registry.yml
vendored
@@ -1,23 +1,45 @@
|
||||
name: Registry
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- "v*"
|
||||
- 'v*'
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
publish-core-images:
|
||||
publish-vela-images:
|
||||
name: Build and Push Vela Images
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
contents: write
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
vela_core_image: ${{ steps.meta-vela-core.outputs.image }}
|
||||
vela_core_digest: ${{ steps.meta-vela-core.outputs.digest }}
|
||||
vela_core_dockerhub_image: ${{ steps.meta-vela-core.outputs.dockerhub_image }}
|
||||
vela_cli_image: ${{ steps.meta-vela-cli.outputs.image }}
|
||||
vela_cli_digest: ${{ steps.meta-vela-cli.outputs.digest }}
|
||||
vela_cli_dockerhub_image: ${{ steps.meta-vela-cli.outputs.dockerhub_image }}
|
||||
steps:
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
- name: Get the version
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.1
|
||||
|
||||
- name: Install Crane
|
||||
uses: imjasonh/setup-crane@00c9e93efa4e1138c9a7a5c594acd6c75a2fbf0c # v0.1
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # main
|
||||
with:
|
||||
cosign-release: 'v2.5.0'
|
||||
|
||||
- name: Get the image version
|
||||
id: get_version
|
||||
run: |
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
@@ -25,34 +47,41 @@ jobs:
|
||||
VERSION=latest
|
||||
fi
|
||||
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get git revision
|
||||
id: vars
|
||||
shell: bash
|
||||
run: |
|
||||
echo "git_revision=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
- name: Login ghcr.io
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login docker.io
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
|
||||
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
with:
|
||||
driver-opts: image=moby/buildkit:master
|
||||
|
||||
- uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
|
||||
name: Build & Pushing vela-core for Dockerhub, GHCR
|
||||
- name: Build & Push Vela Core for Dockerhub, GHCR
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
labels: |-
|
||||
labels: |
|
||||
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
@@ -61,16 +90,55 @@ jobs:
|
||||
GITVERSION=git-${{ steps.vars.outputs.git_revision }}
|
||||
VERSION=${{ steps.get_version.outputs.VERSION }}
|
||||
GOPROXY=https://proxy.golang.org
|
||||
tags: |-
|
||||
tags: |
|
||||
docker.io/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
|
||||
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
- uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
|
||||
name: Build & Pushing CLI for Dockerhub, GHCR
|
||||
- name: Get Vela Core Image Digest
|
||||
id: meta-vela-core
|
||||
run: |
|
||||
GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/oamdev/vela-core
|
||||
DOCKER_IMAGE=docker.io/oamdev/vela-core
|
||||
TAG=${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
DIGEST=$(crane digest $GHCR_IMAGE:$TAG)
|
||||
|
||||
echo "image=$GHCR_IMAGE" >> $GITHUB_OUTPUT
|
||||
echo "dockerhub_image=$DOCKER_IMAGE" >> $GITHUB_OUTPUT
|
||||
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate SBOM for Vela Core Image
|
||||
id: generate_vela_core_sbom
|
||||
uses: anchore/sbom-action@v0.17.0
|
||||
with:
|
||||
image: ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
|
||||
registry-username: ${{ github.actor }}
|
||||
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
||||
format: spdx-json
|
||||
artifact-name: sbom-vela-core.spdx.json
|
||||
output-file: ${{ github.workspace }}/sbom-vela-core.spdx.json
|
||||
|
||||
- name: Sign Vela Core Image and Attest SBOM
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 'true'
|
||||
run: |
|
||||
echo "signing vela core images..."
|
||||
cosign sign --yes ghcr.io/${{ github.repository_owner }}/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
|
||||
cosign sign --yes docker.io/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
|
||||
|
||||
echo "attesting SBOM against the vela core image..."
|
||||
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-core.spdx.json --type spdx \
|
||||
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
|
||||
|
||||
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-core.spdx.json --type spdx \
|
||||
docker.io/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
|
||||
|
||||
- name: Build & Push Vela CLI for Dockerhub, GHCR
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.cli
|
||||
labels: |-
|
||||
labels: |
|
||||
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
@@ -79,6 +147,100 @@ jobs:
|
||||
GITVERSION=git-${{ steps.vars.outputs.git_revision }}
|
||||
VERSION=${{ steps.get_version.outputs.VERSION }}
|
||||
GOPROXY=https://proxy.golang.org
|
||||
tags: |-
|
||||
tags: |
|
||||
docker.io/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
|
||||
ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
- name: Get Vela CLI Image Digest
|
||||
id: meta-vela-cli
|
||||
run: |
|
||||
GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli
|
||||
DOCKER_IMAGE=docker.io/oamdev/vela-cli
|
||||
TAG=${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
DIGEST=$(crane digest $GHCR_IMAGE:$TAG)
|
||||
|
||||
echo "image=$GHCR_IMAGE" >> $GITHUB_OUTPUT
|
||||
echo "dockerhub_image=$DOCKER_IMAGE" >> $GITHUB_OUTPUT
|
||||
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate SBOM for Vela CLI Image
|
||||
id: generate_sbom
|
||||
uses: anchore/sbom-action@v0.17.0
|
||||
with:
|
||||
image: ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
|
||||
registry-username: ${{ github.actor }}
|
||||
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
||||
format: spdx-json
|
||||
artifact-name: sbom-vela-cli.spdx.json
|
||||
output-file: ${{ github.workspace }}/sbom-vela-cli.spdx.json
|
||||
|
||||
- name: Sign Vela CLI Image and Attest SBOM
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 'true'
|
||||
run: |
|
||||
echo "signing vela CLI images..."
|
||||
cosign sign --yes ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
|
||||
cosign sign --yes docker.io/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
|
||||
|
||||
echo "attesting SBOM against the vela cli image..."
|
||||
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-cli.spdx.json --type spdx \
|
||||
ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
|
||||
|
||||
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-cli.spdx.json --type spdx \
|
||||
docker.io/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
|
||||
|
||||
- name: Publish SBOMs as release artifacts
|
||||
uses: anchore/sbom-action/publish-sbom@v0.17.0
|
||||
|
||||
provenance-ghcr:
|
||||
name: Generate and Push Provenance to GCHR
|
||||
needs: publish-vela-images
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: 'Vela Core Image'
|
||||
image: ${{ needs.publish-vela-images.outputs.vela_core_image }}
|
||||
digest: ${{ needs.publish-vela-images.outputs.vela_core_digest }}
|
||||
- name: 'Vela CLI Image'
|
||||
image: ${{ needs.publish-vela-images.outputs.vela_cli_image }}
|
||||
digest: ${{ needs.publish-vela-images.outputs.vela_cli_digest }}
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
actions: read
|
||||
packages: write
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 # has to be sem var
|
||||
with:
|
||||
image: ${{ matrix.image }}
|
||||
digest: ${{ matrix.digest }}
|
||||
registry-username: ${{ github.actor }}
|
||||
secrets:
|
||||
registry-password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
provenance-dockerhub:
|
||||
name: Generate and Push Provenance to DockerHub
|
||||
needs: publish-vela-images
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: 'Vela Core Image'
|
||||
image: ${{ needs.publish-vela-images.outputs.vela_core_dockerhub_image }}
|
||||
digest: ${{ needs.publish-vela-images.outputs.vela_core_digest }}
|
||||
- name: 'Vela CLI Image'
|
||||
image: ${{ needs.publish-vela-images.outputs.vela_cli_dockerhub_image }}
|
||||
digest: ${{ needs.publish-vela-images.outputs.vela_cli_digest }}
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
packages: write
|
||||
actions: read
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
|
||||
with:
|
||||
image: ${{ matrix.image }}
|
||||
digest: ${{ matrix.digest }}
|
||||
secrets:
|
||||
registry-username: ${{ secrets.DOCKER_USERNAME }}
|
||||
registry-password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
89
.github/workflows/release.yml
vendored
89
.github/workflows/release.yml
vendored
@@ -4,13 +4,15 @@ on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
workflow_dispatch: { }
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
goreleaser:
|
||||
name: goreleaser
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
@@ -20,27 +22,83 @@ jobs:
|
||||
pull-requests: read
|
||||
repository-projects: read
|
||||
statuses: read
|
||||
runs-on: ubuntu-22.04
|
||||
name: goreleaser
|
||||
id-token: write
|
||||
outputs:
|
||||
hashes: ${{ steps.hash.outputs.hashes }}
|
||||
steps:
|
||||
- name: Check disk (before)
|
||||
run: |
|
||||
df -h
|
||||
sudo du -sh /usr/local/lib/android /usr/share/dotnet /opt/ghc || true
|
||||
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: insightsengineering/disk-space-reclaimer@v1
|
||||
with:
|
||||
# this might remove tools that are actually needed,
|
||||
# if set to "true" but frees about 6 GB
|
||||
tools-cache: false
|
||||
# all of these default to true, but feel free to set to
|
||||
# "false" if necessary for your workflow
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: true
|
||||
swap-storage: true
|
||||
docker-images: true
|
||||
|
||||
# Extra prune in case your job builds/pulls images
|
||||
- name: Deep Docker prune
|
||||
run: |
|
||||
docker system prune -af || true
|
||||
docker builder prune -af || true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: git fetch --force --tags
|
||||
|
||||
- name: Get Git tags
|
||||
run: git fetch --force --tags
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: 1.22
|
||||
go-version: 1.23.8
|
||||
cache: true
|
||||
- uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@main
|
||||
with:
|
||||
cosign-release: "v2.5.0"
|
||||
|
||||
- name: Install syft
|
||||
uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: 1.14.1
|
||||
args: release --rm-dist --timeout 60m
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Generate hashes
|
||||
id: hash
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
set -euo pipefail
|
||||
HASHES=$(find dist -type f -exec sha256sum {} \; | base64 -w0)
|
||||
echo "hashes=$HASHES" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Check disk (after)
|
||||
run: df -h
|
||||
|
||||
upload-plugin-homebrew:
|
||||
name: upload-sha256sums
|
||||
needs: goreleaser
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') }}
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
@@ -50,10 +108,6 @@ jobs:
|
||||
pull-requests: read
|
||||
repository-projects: read
|
||||
statuses: read
|
||||
needs: build
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') }}
|
||||
name: upload-sha256sums
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
@@ -67,3 +121,16 @@ jobs:
|
||||
tag: ${{ github.ref }}
|
||||
revision: ${{ github.sha }}
|
||||
force: false
|
||||
|
||||
provenance-vela-bins:
|
||||
name: generate provenance for binaries
|
||||
needs: [goreleaser]
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
actions: read
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 # has to be sem var
|
||||
with:
|
||||
base64-subjects: "${{ needs.goreleaser.outputs.hashes }}"
|
||||
upload-assets: true
|
||||
|
||||
4
.github/workflows/scorecards.yml
vendored
4
.github/workflows/scorecards.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # tag=v2.3.1
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # tag=v2.4.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -55,6 +55,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
|
||||
uses: github/codeql-action/upload-sarif@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
19
.github/workflows/sdk-test.yml
vendored
19
.github/workflows/sdk-test.yml
vendored
@@ -16,22 +16,15 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.22'
|
||||
GOLANGCI_VERSION: 'v1.54.2'
|
||||
|
||||
jobs:
|
||||
sdk-tests:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Env
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
- name: Install Go tools
|
||||
run: |
|
||||
@@ -39,9 +32,9 @@ jobs:
|
||||
make golangci
|
||||
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.19.0
|
||||
kind create cluster
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
name: sdk-test
|
||||
|
||||
- name: Build CLI
|
||||
run: make vela-cli
|
||||
|
||||
11
.github/workflows/sync-api.yml
vendored
11
.github/workflows/sync-api.yml
vendored
@@ -10,21 +10,16 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.22'
|
||||
|
||||
jobs:
|
||||
sync-core-api:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Setup Env
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
|
||||
20
.github/workflows/sync-sdk.yaml
vendored
20
.github/workflows/sync-sdk.yaml
vendored
@@ -14,28 +14,16 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.22'
|
||||
|
||||
jobs:
|
||||
sync_sdk:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
- name: Env setup
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
- name: Install Go tools
|
||||
run: |
|
||||
@@ -44,6 +32,10 @@ jobs:
|
||||
- name: Build CLI
|
||||
run: make vela-cli
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: echo "VERSION=${GITHUB_REF}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Sync SDK to kubevela/kubevela-go-sdk
|
||||
run: bash ./hack/sdk/sync.sh
|
||||
env:
|
||||
|
||||
2
.github/workflows/trivy-scan.yml
vendored
2
.github/workflows/trivy-scan.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
output: 'trivy-results.sarif'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@366883a76d75dcee5428da5c3ae7abf9386e35ac # v2.26.2
|
||||
uses: github/codeql-action/upload-sarif@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
53
.github/workflows/unit-test.yml
vendored
53
.github/workflows/unit-test.yml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
workflow_dispatch: { }
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
@@ -14,15 +14,10 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.22'
|
||||
|
||||
jobs:
|
||||
|
||||
detect-noop:
|
||||
permissions:
|
||||
actions: write # for fkirc/skip-duplicate-actions to skip or stop workflow runs
|
||||
actions: write # for fkirc/skip-duplicate-actions to skip or stop workflow runs
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
noop: ${{ steps.noop.outputs.should_skip }}
|
||||
@@ -42,41 +37,19 @@ jobs:
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
|
||||
- name: Setup Env
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
- name: Setup KinD with Kubernetes
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
|
||||
- name: Run unit tests
|
||||
uses: ./.github/actions/unit-test
|
||||
with:
|
||||
path: .work/pkg
|
||||
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: ${{ runner.os }}-pkg-
|
||||
|
||||
- name: Install ginkgo
|
||||
run: |
|
||||
sudo sed -i 's/azure\.//' /etc/apt/sources.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y golang-ginkgo-dev
|
||||
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.19.0
|
||||
kind create cluster
|
||||
|
||||
- name: Run Make test
|
||||
run: make test
|
||||
|
||||
- name: Upload coverage report
|
||||
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
file: ./coverage.txt
|
||||
flags: core-unittests
|
||||
name: codecov-umbrella
|
||||
codecov-enable: true
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
98
.github/workflows/upgrade-e2e-multicluster-test.yml
vendored
Normal file
98
.github/workflows/upgrade-e2e-multicluster-test.yml
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
# =============================================================================
|
||||
# E2E Upgrade Multicluster Test Workflow
|
||||
# =============================================================================
|
||||
# This workflow performs end-to-end testing for KubeVela multicluster upgrades.
|
||||
# It tests the upgrade path from the latest released version to the current
|
||||
# development branch across multiple Kubernetes versions.
|
||||
#
|
||||
# Test Flow:
|
||||
# 1. Install latest KubeVela release
|
||||
# 2. Build and upgrade to current development version
|
||||
# 3. Run multicluster e2e tests to verify functionality
|
||||
# =============================================================================
|
||||
|
||||
name: E2E Upgrade Multicluster Test
|
||||
|
||||
# =============================================================================
|
||||
# Trigger Configuration
|
||||
# =============================================================================
|
||||
on:
|
||||
# Trigger on pull requests targeting main branches
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
|
||||
# Allow manual workflow execution
|
||||
workflow_dispatch: {}
|
||||
|
||||
# =============================================================================
|
||||
# Security Configuration
|
||||
# =============================================================================
|
||||
permissions:
|
||||
contents: read # Read-only access to repository contents
|
||||
|
||||
# =============================================================================
|
||||
# Global Environment Variables
|
||||
# =============================================================================
|
||||
env:
|
||||
GO_VERSION: '1.23.8' # Go version for building and testing
|
||||
|
||||
# =============================================================================
|
||||
# Job Definitions
|
||||
# =============================================================================
|
||||
jobs:
|
||||
upgrade-multicluster-tests:
|
||||
name: Upgrade Multicluster Tests
|
||||
runs-on: ubuntu-22.04
|
||||
if: startsWith(github.head_ref, 'chore/upgrade-k8s-')
|
||||
timeout-minutes: 60 # Prevent hanging jobs
|
||||
|
||||
# ==========================================================================
|
||||
# Matrix Strategy - Test against multiple Kubernetes versions
|
||||
# ==========================================================================
|
||||
strategy:
|
||||
fail-fast: false # Continue testing other versions if one fails
|
||||
matrix:
|
||||
k8s-version: ['v1.31.9']
|
||||
|
||||
# ==========================================================================
|
||||
# Concurrency Control - Prevent overlapping runs
|
||||
# ==========================================================================
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Environment Setup
|
||||
# ========================================================================
|
||||
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
|
||||
# ========================================================================
|
||||
# Kubernetes Cluster Setup
|
||||
# ========================================================================
|
||||
|
||||
- name: Setup worker cluster kinD
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
name: worker
|
||||
|
||||
- name: Setup KinD master clusters for multicluster testing
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
k8s-version: ${{ matrix.k8s-version }}
|
||||
|
||||
- name: Deploy latest release
|
||||
uses: ./.github/actions/deploy-latest-release
|
||||
|
||||
- name: Upgrade from current branch
|
||||
uses: ./.github/actions/deploy-current-branch
|
||||
|
||||
- name: Run upgarde multicluster tests
|
||||
uses: ./.github/actions/multicluster-test
|
||||
with:
|
||||
codecov-enable: false
|
||||
codecov-token: ''
|
||||
102
.github/workflows/upgrade-e2e-test.yml
vendored
Normal file
102
.github/workflows/upgrade-e2e-test.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
# =============================================================================
|
||||
# Upgrade E2E Test Workflow
|
||||
# =============================================================================
|
||||
# This workflow performs comprehensive end-to-end testing for KubeVela upgrades.
|
||||
# It validates the upgrade path from the latest stable release to the current
|
||||
# development version by running multiple test suites including API, addon,
|
||||
# and general e2e tests.
|
||||
#
|
||||
# Test Flow:
|
||||
# 1. Install latest KubeVela release
|
||||
# 2. Build and upgrade to current development version
|
||||
# 3. Run comprehensive e2e test suites (API, addon, general)
|
||||
# 4. Validate upgrade functionality and compatibility
|
||||
# =============================================================================
|
||||
|
||||
name: Upgrade E2E Test
|
||||
|
||||
# =============================================================================
|
||||
# Trigger Configuration
|
||||
# =============================================================================
|
||||
on:
|
||||
# Trigger on pull requests targeting main branches
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
|
||||
# Allow manual workflow execution
|
||||
workflow_dispatch: {}
|
||||
|
||||
# =============================================================================
|
||||
# Environment Variables
|
||||
# =============================================================================
|
||||
env:
|
||||
GO_VERSION: '1.23.8'
|
||||
|
||||
# =============================================================================
|
||||
# Security Configuration
|
||||
# =============================================================================
|
||||
permissions:
|
||||
contents: read # Read-only access to repository contents
|
||||
|
||||
# =============================================================================
|
||||
# Job Definitions
|
||||
# =============================================================================
|
||||
jobs:
|
||||
upgrade-tests:
|
||||
name: Upgrade E2E Tests
|
||||
runs-on: ubuntu-22.04
|
||||
if: startsWith(github.head_ref, 'chore/upgrade-k8s-')
|
||||
timeout-minutes: 90 # Extended timeout for comprehensive e2e testing
|
||||
|
||||
# ==========================================================================
|
||||
# Matrix Strategy - Test against multiple Kubernetes versions
|
||||
# ==========================================================================
|
||||
strategy:
|
||||
fail-fast: false # Continue testing other versions if one fails
|
||||
matrix:
|
||||
k8s-version: ['v1.31.9']
|
||||
|
||||
# ==========================================================================
|
||||
# Concurrency Control - Prevent overlapping runs
|
||||
# ==========================================================================
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Repository Setup
|
||||
# ========================================================================
|
||||
- name: Check out code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
|
||||
# ========================================================================
|
||||
# Kubernetes Cluster Setup
|
||||
# ========================================================================
|
||||
- name: Setup KinD with Kubernetes ${{ matrix.k8s-version }}
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
k8s-version: ${{ matrix.k8s-version }}
|
||||
|
||||
- name: Build vela CLI
|
||||
run: make vela-cli
|
||||
|
||||
- name: Build kubectl-vela plugin
|
||||
run: make kubectl-vela
|
||||
|
||||
- name: Install kustomize
|
||||
run: make kustomize
|
||||
|
||||
- name: Deploy latest release
|
||||
uses: ./.github/actions/deploy-latest-release
|
||||
|
||||
- name: Upgrade from current branch
|
||||
uses: ./.github/actions/deploy-current-branch
|
||||
|
||||
# ========================================================================
|
||||
# E2E Test Execution
|
||||
# ========================================================================
|
||||
- name: Run upgrade e2e tests
|
||||
uses: ./.github/actions/e2e-test
|
||||
83
.github/workflows/upgrade-unit-test.yml
vendored
Normal file
83
.github/workflows/upgrade-unit-test.yml
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
# =============================================================================
|
||||
# Upgrade Unit Test Workflow
|
||||
# =============================================================================
|
||||
# This workflow performs unit testing for KubeVela upgrades by:
|
||||
# 1. Installing the latest stable KubeVela release
|
||||
# 2. Building and upgrading to the current development version
|
||||
# 3. Running unit tests to validate the upgrade functionality
|
||||
# =============================================================================
|
||||
|
||||
name: Upgrade Unit Test
|
||||
|
||||
# =============================================================================
|
||||
# Trigger Configuration
|
||||
# =============================================================================
|
||||
on:
|
||||
# Trigger on pull requests targeting main and release branches
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
|
||||
# Allow manual workflow execution
|
||||
workflow_dispatch: {}
|
||||
|
||||
# =============================================================================
|
||||
# Security Configuration
|
||||
# =============================================================================
|
||||
permissions:
|
||||
contents: read # Read-only access to repository contents
|
||||
|
||||
# =============================================================================
|
||||
# Job Definitions
|
||||
# =============================================================================
|
||||
jobs:
|
||||
upgrade-tests:
|
||||
name: Upgrade Unit Tests
|
||||
runs-on: ubuntu-22.04
|
||||
if: startsWith(github.head_ref, 'chore/upgrade-k8s-')
|
||||
timeout-minutes: 45 # Prevent hanging jobs
|
||||
|
||||
# ==========================================================================
|
||||
# Matrix Strategy - Test against multiple Kubernetes versions
|
||||
# ==========================================================================
|
||||
strategy:
|
||||
fail-fast: false # Continue testing other versions if one fails
|
||||
matrix:
|
||||
k8s-version: ['v1.31.9']
|
||||
|
||||
# ==========================================================================
|
||||
# Concurrency Control - Prevent overlapping runs
|
||||
# ==========================================================================
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
# ========================================================================
|
||||
# Environment Setup
|
||||
# ========================================================================
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
|
||||
# ========================================================================
|
||||
# Kubernetes Cluster Setup
|
||||
# ========================================================================
|
||||
|
||||
- name: Setup KinD with Kubernetes ${{ matrix.k8s-version }}
|
||||
uses: ./.github/actions/setup-kind-cluster
|
||||
with:
|
||||
k8s-version: ${{ matrix.k8s-version }}
|
||||
|
||||
- name: Deploy latest release
|
||||
uses: ./.github/actions/deploy-latest-release
|
||||
|
||||
- name: Upgrade from current branch
|
||||
uses: ./.github/actions/deploy-current-branch
|
||||
|
||||
- name: Run unit tests
|
||||
uses: ./.github/actions/unit-test
|
||||
with:
|
||||
codecov-enable: false
|
||||
codecov-token: ''
|
||||
165
.github/workflows/webhook-upgrade-validation.yml
vendored
Normal file
165
.github/workflows/webhook-upgrade-validation.yml
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
name: Webhook Upgrade Validation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23.8'
|
||||
|
||||
jobs:
|
||||
webhook-upgrade-check:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
|
||||
|
||||
- name: Setup Env
|
||||
uses: ./.github/actions/env-setup
|
||||
|
||||
- name: Setup KinD
|
||||
run: |
|
||||
go install sigs.k8s.io/kind@v0.29.0
|
||||
kind delete cluster || true
|
||||
kind create cluster --image=kindest/node:v1.31.9
|
||||
|
||||
- name: Install KubeVela CLI
|
||||
run: curl -fsSL https://kubevela.io/script/install.sh | bash
|
||||
|
||||
- name: Install KubeVela baseline
|
||||
run: |
|
||||
vela install --set featureGates.enableCueValidation=true
|
||||
kubectl wait --namespace vela-system --for=condition=Available deployment/kubevela-vela-core --timeout=300s
|
||||
|
||||
- name: Prepare failing chart changes
|
||||
run: |
|
||||
cat <<'CHART' > charts/vela-core/templates/defwithtemplate/resource.yaml
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/resource.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Add resource requests and limits on K8s pod for your workload which follows the pod spec in path 'spec.template.'
|
||||
name: resource
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- deployments.apps
|
||||
- statefulsets.apps
|
||||
- daemonsets.apps
|
||||
- jobs.batch
|
||||
- cronjobs.batch
|
||||
podDisruptive: true
|
||||
schematic:
|
||||
cue:
|
||||
template: |2
|
||||
let resourceContent = {
|
||||
resources: {
|
||||
if parameter.cpu != _|_ if parameter.memory != _|_ if parameter.requests == _|_ if parameter.limits == _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
requests: {
|
||||
cpu: parameter.cpu
|
||||
memory: parameter.memory
|
||||
}
|
||||
// +patchStrategy=retainKeys
|
||||
limits: {
|
||||
cpu: parameter.cpu
|
||||
memory: parameter.memory
|
||||
}
|
||||
}
|
||||
if parameter.requests != _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
requests: {
|
||||
cpu: parameter.requests.cpu
|
||||
memory: parameter.requests.memory
|
||||
}
|
||||
}
|
||||
if parameter.limits != _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
limits: {
|
||||
cpu: parameter.limits.cpu
|
||||
memory: parameter.limits.memory
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if context.output.spec != _|_ if context.output.spec.template != _|_ {
|
||||
patch: spec: template: spec: {
|
||||
// +patchKey=name
|
||||
containers: [resourceContent]
|
||||
}
|
||||
}
|
||||
if context.output.spec != _|_ if context.output.spec.jobTemplate != _|_ {
|
||||
patch: spec: jobTemplate: spec: template: spec: {
|
||||
// +patchKey=name
|
||||
containers: [resourceContent]
|
||||
}
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the amount of cpu for requests and limits
|
||||
cpu?: *1 | number | string
|
||||
// +usage=Specify the amount of memory for requests and limits
|
||||
memory?: *"2048Mi" | =~"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"
|
||||
// +usage=Specify the resources in requests
|
||||
requests?: {
|
||||
// +usage=Specify the amount of cpu for requests
|
||||
cpu: *1 | number | string
|
||||
// +usage=Specify the amount of memory for requests
|
||||
memory: *"2048Mi" | =~"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"
|
||||
}
|
||||
// +usage=Specify the resources in limits
|
||||
limits?: {
|
||||
// +usage=Specify the amount of cpu for limits
|
||||
cpu: *1 | number | string
|
||||
// +usage=Specify the amount of memory for limits
|
||||
memory: *"2048Mi" | =~"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"
|
||||
}
|
||||
}
|
||||
|
||||
- name: Load image
|
||||
run: |
|
||||
mkdir -p $HOME/tmp/
|
||||
TMPDIR=$HOME/tmp/ make image-load
|
||||
|
||||
- name: Run Helm upgrade (expected to fail)
|
||||
run: |
|
||||
set +e
|
||||
helm upgrade \
|
||||
--set image.repository=vela-core-test \
|
||||
--set image.tag=$(git rev-parse --short HEAD) \
|
||||
--set featureGates.enableCueValidation=true \
|
||||
--wait kubevela ./charts/vela-core --debug -n vela-system
|
||||
status=$?
|
||||
echo "Helm upgrade exit code: ${status}"
|
||||
if [ $status -eq 0 ]; then
|
||||
echo "Expected helm upgrade to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Helm upgrade failed as expected"
|
||||
|
||||
- name: Dump webhook configurations
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
kubectl get mutatingwebhookconfiguration kubevela-vela-core-admission -o yaml
|
||||
kubectl get validatingwebhookconfiguration kubevela-vela-core-admission -o yaml
|
||||
|
||||
- name: Verify webhook validation remains active
|
||||
run: ginkgo -v --focus-file requiredparam_validation_test.go ./test/e2e-test
|
||||
|
||||
- name: Cleanup kind cluster
|
||||
if: ${{ always() }}
|
||||
run: kind delete cluster --name kind
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -35,6 +35,14 @@ vendor/
|
||||
.vscode
|
||||
.history
|
||||
|
||||
# Debug binaries generated by VS Code/Delve
|
||||
__debug_bin*
|
||||
*/__debug_bin*
|
||||
|
||||
# Webhook certificates generated at runtime
|
||||
k8s-webhook-server/
|
||||
options.go.bak
|
||||
|
||||
pkg/test/vela
|
||||
config/crd/bases
|
||||
_tmp/
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
run:
|
||||
timeout: 10m
|
||||
|
||||
skip-files:
|
||||
- "zz_generated\\..+\\.go$"
|
||||
- ".*_test.go$"
|
||||
|
||||
skip-dirs:
|
||||
- "hack"
|
||||
- "e2e"
|
||||
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
|
||||
@@ -23,24 +11,12 @@ linters-settings:
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
|
||||
# [deprecated] comma-separated list of pairs of the form pkg:regex
|
||||
# the regex is used to ignore names within pkg. (default "fmt:.*").
|
||||
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
|
||||
ignore: fmt:.*,io/ioutil:^Read.*
|
||||
|
||||
exhaustive:
|
||||
# indicates that switch statements are to be considered exhaustive if a
|
||||
# 'default' case is present, even if all enum members aren't listed in the
|
||||
# switch
|
||||
default-signifies-exhaustive: true
|
||||
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: false
|
||||
|
||||
revive:
|
||||
# minimal confidence for issues, default is 0.8
|
||||
min-confidence: 0.8
|
||||
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
@@ -55,9 +31,6 @@ linters-settings:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 30
|
||||
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
|
||||
dupl:
|
||||
# tokens count to trigger issue, 150 by default
|
||||
@@ -73,13 +46,6 @@ linters-settings:
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
|
||||
unused:
|
||||
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
|
||||
unparam:
|
||||
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||
@@ -107,9 +73,13 @@ linters-settings:
|
||||
# Allow only slices initialized with a length of zero. Default is false.
|
||||
always: false
|
||||
|
||||
revive:
|
||||
rules:
|
||||
- name: unused-parameter
|
||||
disabled: true
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- megacheck
|
||||
- govet
|
||||
- gocyclo
|
||||
- gocritic
|
||||
@@ -121,11 +91,10 @@ linters:
|
||||
- misspell
|
||||
- nakedret
|
||||
- exportloopref
|
||||
- unused
|
||||
- gosimple
|
||||
- staticcheck
|
||||
disable:
|
||||
- deadcode
|
||||
- scopelint
|
||||
- structcheck
|
||||
- varcheck
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
- errchkjson
|
||||
@@ -137,8 +106,28 @@ linters:
|
||||
|
||||
|
||||
issues:
|
||||
|
||||
exclude-files:
|
||||
- "zz_generated\\..+\\.go$"
|
||||
- ".*_test.go$"
|
||||
|
||||
exclude-dirs:
|
||||
- "hack"
|
||||
- "e2e"
|
||||
|
||||
# Excluding configuration per-path and per-linter
|
||||
exclude-rules:
|
||||
- path: .*\.go
|
||||
linters:
|
||||
- errcheck
|
||||
text: "fmt\\."
|
||||
|
||||
# Ignore unchecked errors from io/ioutil functions starting with Read
|
||||
- path: .*\.go
|
||||
linters:
|
||||
- errcheck
|
||||
text: "io/ioutil.*Read"
|
||||
|
||||
# Exclude some linters from running on tests files.
|
||||
- path: _test(ing)?\.go
|
||||
linters:
|
||||
@@ -227,7 +216,7 @@ issues:
|
||||
new: false
|
||||
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
max-per-linter: 0
|
||||
max-issues-per-linter: 0
|
||||
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
max-same-issues: 0
|
||||
@@ -31,6 +31,28 @@ builds:
|
||||
ldflags:
|
||||
- -s -w -X github.com/oam-dev/kubevela/version.VelaVersion={{ .Version }} -X github.com/oam-dev/kubevela/version.GitRevision=git-{{.ShortCommit}}
|
||||
|
||||
sboms:
|
||||
- id: kubevela-binaries-sboms
|
||||
artifacts: binary
|
||||
documents:
|
||||
- "${artifact}-{{ .Version }}-{{ .Os }}-{{ .Arch }}.spdx.sbom.json"
|
||||
|
||||
signs:
|
||||
- id: kubevela-cosign-keyless
|
||||
artifacts: checksum # sign the checksum file over individual artifacts
|
||||
signature: "${artifact}-keyless.sig"
|
||||
certificate: "${artifact}-keyless.pem"
|
||||
cmd: cosign
|
||||
args:
|
||||
- "sign-blob"
|
||||
- "--yes"
|
||||
- "--output-signature"
|
||||
- "${artifact}-keyless.sig"
|
||||
- "--output-certificate"
|
||||
- "${artifact}-keyless.pem"
|
||||
- "${artifact}"
|
||||
output: true
|
||||
|
||||
archives:
|
||||
- format: tar.gz
|
||||
id: vela-cli-tgz
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# CONTRIBUTING Guide
|
||||
|
||||
Please refer to https://kubevela.io/docs/contributor/overview for details.
|
||||
Please refer to https://kubevela.io/docs/contributor/overview for details.
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG BASE_IMAGE
|
||||
# Build the manager binary
|
||||
FROM golang:1.22-alpine3.18 as builder
|
||||
FROM golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1 AS builder
|
||||
|
||||
WORKDIR /workspace
|
||||
# Copy the Go Modules manifests
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG BASE_IMAGE
|
||||
# Build the cli binary
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22-alpine@sha256:d1a601b64de09e2fa38c95e55838961811d5ca11062a8f4230a5c434b3ae2a34 as builder
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1 AS builder
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY=${GOPROXY:-https://proxy.golang.org}
|
||||
WORKDIR /workspace
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG BASE_IMAGE
|
||||
# Build the manager binary
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22-alpine@sha256:d1a601b64de09e2fa38c95e55838961811d5ca11062a8f4230a5c434b3ae2a34 as builder
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1 AS builder
|
||||
|
||||
WORKDIR /workspace
|
||||
# Copy the Go Modules manifests
|
||||
|
||||
2
Makefile
2
Makefile
@@ -61,7 +61,7 @@ staticcheck: staticchecktool
|
||||
## lint: Run the golangci-lint
|
||||
lint: golangci
|
||||
@$(INFO) lint
|
||||
@$(GOLANGCILINT) run --fix --verbose --skip-dirs 'scaffold'
|
||||
@GOLANGCILINT=$(GOLANGCILINT) ./hack/utils/golangci-lint-wrapper.sh
|
||||
|
||||
## reviewable: Run the reviewable
|
||||
reviewable: manifests fmt vet lint staticcheck helm-doc-gen sdk_fmt
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
[](https://artifacthub.io/packages/search?repo=kubevela)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/4602)
|
||||

|
||||
[](https://api.securityscorecards.dev/projects/github.com/kubevela/kubevela)
|
||||
[](https://scorecard.dev/viewer/?uri=github.com/kubevela/kubevela)
|
||||
[](https://opensource.alibaba.com/contribution_leaderboard/details?projectValue=kubevela)
|
||||
|
||||
## Introduction
|
||||
@@ -115,4 +115,4 @@ Security is a first priority thing for us at KubeVela. If you come across a rela
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
KubeVela adopts [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
||||
KubeVela adopts [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
||||
@@ -135,6 +135,9 @@ type Status struct {
|
||||
// HealthPolicy defines the health check policy for the abstraction
|
||||
// +optional
|
||||
HealthPolicy string `json:"healthPolicy,omitempty"`
|
||||
// Details stores a string representation of a CUE status map to be evaluated at runtime for display
|
||||
// +optional
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationPhase is a label for the condition of an application at the current time
|
||||
@@ -172,6 +175,7 @@ type ApplicationComponentStatus struct {
|
||||
// WorkloadDefinition is the definition of a WorkloadDefinition, such as deployments/apps.v1
|
||||
WorkloadDefinition WorkloadGVK `json:"workloadDefinition,omitempty"`
|
||||
Healthy bool `json:"healthy"`
|
||||
Details map[string]string `json:"details,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Traits []ApplicationTraitStatus `json:"traits,omitempty"`
|
||||
Scopes []corev1.ObjectReference `json:"scopes,omitempty"`
|
||||
@@ -185,9 +189,10 @@ func (in ApplicationComponentStatus) Equal(r ApplicationComponentStatus) bool {
|
||||
|
||||
// ApplicationTraitStatus records the trait health status
|
||||
type ApplicationTraitStatus struct {
|
||||
Type string `json:"type"`
|
||||
Healthy bool `json:"healthy"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Healthy bool `json:"healthy"`
|
||||
Details map[string]string `json:"details,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// Revision has name and revision number
|
||||
|
||||
@@ -130,10 +130,19 @@ func (in *ApplicationComponent) DeepCopy() *ApplicationComponent {
|
||||
func (in *ApplicationComponentStatus) DeepCopyInto(out *ApplicationComponentStatus) {
|
||||
*out = *in
|
||||
out.WorkloadDefinition = in.WorkloadDefinition
|
||||
if in.Details != nil {
|
||||
in, out := &in.Details, &out.Details
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Traits != nil {
|
||||
in, out := &in.Traits, &out.Traits
|
||||
*out = make([]ApplicationTraitStatus, len(*in))
|
||||
copy(*out, *in)
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Scopes != nil {
|
||||
in, out := &in.Scopes, &out.Scopes
|
||||
@@ -175,6 +184,13 @@ func (in *ApplicationTrait) DeepCopy() *ApplicationTrait {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationTraitStatus) DeepCopyInto(out *ApplicationTraitStatus) {
|
||||
*out = *in
|
||||
if in.Details != nil {
|
||||
in, out := &in.Details, &out.Details
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationTraitStatus.
|
||||
|
||||
@@ -60,3 +60,8 @@ func init() {
|
||||
SchemeBuilder.Register(&workflowv1alpha1.Workflow{}, &workflowv1alpha1.WorkflowList{})
|
||||
_ = SchemeBuilder.AddToScheme(k8sscheme.Scheme)
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ var (
|
||||
ComponentDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: ComponentDefinitionKind}.String()
|
||||
ComponentDefinitionKindAPIVersion = ComponentDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
ComponentDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(ComponentDefinitionKind)
|
||||
ComponentDefinitionGVR = SchemeGroupVersion.WithResource("componentdefinitions")
|
||||
)
|
||||
|
||||
// WorkloadDefinition type metadata.
|
||||
@@ -65,6 +66,7 @@ var (
|
||||
TraitDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: TraitDefinitionKind}.String()
|
||||
TraitDefinitionKindAPIVersion = TraitDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
TraitDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(TraitDefinitionKind)
|
||||
TraitDefinitionGVR = SchemeGroupVersion.WithResource("traitdefinitions")
|
||||
)
|
||||
|
||||
// PolicyDefinition type metadata.
|
||||
@@ -73,6 +75,7 @@ var (
|
||||
PolicyDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: PolicyDefinitionKind}.String()
|
||||
PolicyDefinitionKindAPIVersion = PolicyDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
PolicyDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(PolicyDefinitionKind)
|
||||
PolicyDefinitionGVR = SchemeGroupVersion.WithResource("policydefinitions")
|
||||
)
|
||||
|
||||
// WorkflowStepDefinition type metadata.
|
||||
@@ -81,6 +84,7 @@ var (
|
||||
WorkflowStepDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: WorkflowStepDefinitionKind}.String()
|
||||
WorkflowStepDefinitionKindAPIVersion = WorkflowStepDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
WorkflowStepDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(WorkflowStepDefinitionKind)
|
||||
WorkflowStepDefinitionGVR = SchemeGroupVersion.WithResource("workflowstepdefinitions")
|
||||
)
|
||||
|
||||
// DefinitionRevision type metadata.
|
||||
@@ -115,6 +119,20 @@ var (
|
||||
ResourceTrackerKindVersionKind = SchemeGroupVersion.WithKind(ResourceTrackerKind)
|
||||
)
|
||||
|
||||
// DefinitionTypeInfo contains the mapping information for a definition type
|
||||
type DefinitionTypeInfo struct {
|
||||
GVR schema.GroupVersionResource
|
||||
Kind string
|
||||
}
|
||||
|
||||
// DefinitionTypeMap maps definition types to their corresponding GVR and Kind
|
||||
var DefinitionTypeMap = map[reflect.Type]DefinitionTypeInfo{
|
||||
reflect.TypeOf(ComponentDefinition{}): {GVR: ComponentDefinitionGVR, Kind: ComponentDefinitionKind},
|
||||
reflect.TypeOf(TraitDefinition{}): {GVR: TraitDefinitionGVR, Kind: TraitDefinitionKind},
|
||||
reflect.TypeOf(PolicyDefinition{}): {GVR: PolicyDefinitionGVR, Kind: PolicyDefinitionKind},
|
||||
reflect.TypeOf(WorkflowStepDefinition{}): {GVR: WorkflowStepDefinitionGVR, Kind: WorkflowStepDefinitionKind},
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ComponentDefinition{}, &ComponentDefinitionList{})
|
||||
SchemeBuilder.Register(&WorkloadDefinition{}, &WorkloadDefinitionList{})
|
||||
|
||||
117
apis/core.oam.dev/v1beta1/register_test.go
Normal file
117
apis/core.oam.dev/v1beta1/register_test.go
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright 2025 The KubeVela 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 v1beta1
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestDefinitionTypeMap(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
defType reflect.Type
|
||||
expectedGVR schema.GroupVersionResource
|
||||
expectedKind string
|
||||
}{
|
||||
{
|
||||
name: "ComponentDefinition",
|
||||
defType: reflect.TypeOf(ComponentDefinition{}),
|
||||
expectedGVR: ComponentDefinitionGVR,
|
||||
expectedKind: ComponentDefinitionKind,
|
||||
},
|
||||
{
|
||||
name: "TraitDefinition",
|
||||
defType: reflect.TypeOf(TraitDefinition{}),
|
||||
expectedGVR: TraitDefinitionGVR,
|
||||
expectedKind: TraitDefinitionKind,
|
||||
},
|
||||
{
|
||||
name: "PolicyDefinition",
|
||||
defType: reflect.TypeOf(PolicyDefinition{}),
|
||||
expectedGVR: PolicyDefinitionGVR,
|
||||
expectedKind: PolicyDefinitionKind,
|
||||
},
|
||||
{
|
||||
name: "WorkflowStepDefinition",
|
||||
defType: reflect.TypeOf(WorkflowStepDefinition{}),
|
||||
expectedGVR: WorkflowStepDefinitionGVR,
|
||||
expectedKind: WorkflowStepDefinitionKind,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
info, ok := DefinitionTypeMap[tt.defType]
|
||||
assert.Truef(t, ok, "Type %v should exist in DefinitionTypeMap", tt.defType)
|
||||
assert.Equal(t, tt.expectedGVR, info.GVR)
|
||||
assert.Equal(t, tt.expectedKind, info.Kind)
|
||||
|
||||
// Verify GVR follows Kubernetes conventions
|
||||
assert.Equal(t, Group, info.GVR.Group)
|
||||
assert.Equal(t, Version, info.GVR.Version)
|
||||
// Resource should be lowercase plural of Kind
|
||||
assert.Equal(t, strings.ToLower(info.Kind)+"s", info.GVR.Resource)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefinitionTypeMapCompleteness(t *testing.T) {
|
||||
// Ensure all expected definition types are in the map
|
||||
expectedTypes := []reflect.Type{
|
||||
reflect.TypeOf(ComponentDefinition{}),
|
||||
reflect.TypeOf(TraitDefinition{}),
|
||||
reflect.TypeOf(PolicyDefinition{}),
|
||||
reflect.TypeOf(WorkflowStepDefinition{}),
|
||||
}
|
||||
|
||||
assert.Equal(t, len(expectedTypes), len(DefinitionTypeMap), "DefinitionTypeMap should contain exactly %d entries", len(expectedTypes))
|
||||
|
||||
for _, expectedType := range expectedTypes {
|
||||
_, ok := DefinitionTypeMap[expectedType]
|
||||
assert.Truef(t, ok, "DefinitionTypeMap should contain %v", expectedType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefinitionKindValues(t *testing.T) {
|
||||
// Verify that the Kind values match the actual type names
|
||||
tests := []struct {
|
||||
defType interface{}
|
||||
expectedKind string
|
||||
}{
|
||||
{ComponentDefinition{}, "ComponentDefinition"},
|
||||
{TraitDefinition{}, "TraitDefinition"},
|
||||
{PolicyDefinition{}, "PolicyDefinition"},
|
||||
{WorkflowStepDefinition{}, "WorkflowStepDefinition"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.expectedKind, func(t *testing.T) {
|
||||
actualKind := reflect.TypeOf(tt.defType).Name()
|
||||
assert.Equal(t, tt.expectedKind, actualKind)
|
||||
|
||||
// Also verify it matches what's in the map
|
||||
info, ok := DefinitionTypeMap[reflect.TypeOf(tt.defType)]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, tt.expectedKind, info.Kind)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -552,6 +552,22 @@ func (in *DefinitionRevisionSpec) DeepCopy() *DefinitionRevisionSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DefinitionTypeInfo) DeepCopyInto(out *DefinitionTypeInfo) {
|
||||
*out = *in
|
||||
out.GVR = in.GVR
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefinitionTypeInfo.
|
||||
func (in *DefinitionTypeInfo) DeepCopy() *DefinitionTypeInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DefinitionTypeInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManagedResource) DeepCopyInto(out *ManagedResource) {
|
||||
*out = *in
|
||||
|
||||
@@ -99,6 +99,8 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `featureGates.sharedDefinitionStorageForApplicationRevision` | use definition cache to reduce duplicated definition storage for application revision, must be used with InformerCacheFilterUnnecessaryFields | `true` |
|
||||
| `featureGates.disableWorkflowContextConfigMapCache` | disable the workflow context's configmap informer cache | `true` |
|
||||
| `featureGates.enableCueValidation` | enable the strict cue validation for cue required parameter fields | `false` |
|
||||
| `featureGates.enableApplicationStatusMetrics` | enable application status metrics and structured logging | `false` |
|
||||
| `featureGates.validateResourcesExist` | enable webhook validation to check if resource types referenced in definition templates exist in the cluster | `false` |
|
||||
|
||||
### MultiCluster parameters
|
||||
|
||||
@@ -146,14 +148,16 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `affinity` | Affinity | `{}` |
|
||||
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
|
||||
| `logDebug` | Enable debug logs for development purpose | `false` |
|
||||
| `devLogs` | Enable formatted logging support for development purpose | `false` |
|
||||
| `logFilePath` | If non-empty, write log files in this path | `""` |
|
||||
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
|
||||
| `kubeClient.qps` | The qps for reconcile clients | `400` |
|
||||
| `kubeClient.burst` | The burst for reconcile clients | `600` |
|
||||
| `authentication.enabled` | Enable authentication for application | `false` |
|
||||
| `authentication.withUser` | Application authentication will impersonate as the request User | `true` |
|
||||
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
|
||||
| `authentication.enabled` | Enable authentication framework for applications | `false` |
|
||||
| `authentication.withUser` | Application authentication will impersonate as the request User (must be true for security) | `true` |
|
||||
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided or withUser is false | `kubevela:vela-core` |
|
||||
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |
|
||||
| `authorization.definitionValidationEnabled` | Enable definition permission validation for RBAC checks on definitions | `false` |
|
||||
| `sharding.enabled` | When sharding enabled, the controller will run as master mode. Refer to https://github.com/kubevela/kubevela/blob/master/design/vela-core/sharding.md for details. | `false` |
|
||||
| `sharding.schedulableShards` | The shards available for scheduling. If empty, dynamic discovery will be used. | `""` |
|
||||
| `core.metrics.enabled` | Enable metrics for vela-core | `false` |
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: applicationrevisions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
@@ -395,7 +395,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
@@ -429,24 +428,8 @@ spec:
|
||||
description: Components record the related Components created
|
||||
by Application Controller
|
||||
items:
|
||||
description: |-
|
||||
ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
---
|
||||
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
|
||||
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
|
||||
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
|
||||
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
|
||||
Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
|
||||
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
|
||||
|
||||
|
||||
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
|
||||
description: ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -460,7 +443,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
@@ -577,6 +559,10 @@ spec:
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
details:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
env:
|
||||
type: string
|
||||
healthy:
|
||||
@@ -589,24 +575,8 @@ spec:
|
||||
type: string
|
||||
scopes:
|
||||
items:
|
||||
description: |-
|
||||
ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
---
|
||||
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
|
||||
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
|
||||
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
|
||||
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
|
||||
Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
|
||||
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
|
||||
|
||||
|
||||
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
|
||||
description: ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -620,7 +590,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
@@ -655,6 +624,10 @@ spec:
|
||||
description: ApplicationTraitStatus records the trait
|
||||
health status
|
||||
properties:
|
||||
details:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
healthy:
|
||||
type: boolean
|
||||
message:
|
||||
@@ -693,24 +666,8 @@ spec:
|
||||
appRevision:
|
||||
type: string
|
||||
contextBackend:
|
||||
description: |-
|
||||
ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
---
|
||||
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
|
||||
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
|
||||
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
|
||||
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
|
||||
Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
|
||||
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
|
||||
|
||||
|
||||
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
|
||||
description: ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -724,7 +681,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
@@ -1048,6 +1004,11 @@ spec:
|
||||
description: CustomStatus defines the custom status
|
||||
message that could display to user
|
||||
type: string
|
||||
details:
|
||||
description: Details stores a string representation
|
||||
of a CUE status map to be evaluated at runtime for
|
||||
display
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy
|
||||
for the abstraction
|
||||
@@ -1650,6 +1611,11 @@ spec:
|
||||
description: CustomStatus defines the custom status
|
||||
message that could display to user
|
||||
type: string
|
||||
details:
|
||||
description: Details stores a string representation
|
||||
of a CUE status map to be evaluated at runtime for
|
||||
display
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy
|
||||
for the abstraction
|
||||
@@ -2335,6 +2301,11 @@ spec:
|
||||
description: CustomStatus defines the custom status
|
||||
message that could display to user
|
||||
type: string
|
||||
details:
|
||||
description: Details stores a string representation
|
||||
of a CUE status map to be evaluated at runtime for
|
||||
display
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy
|
||||
for the abstraction
|
||||
@@ -2403,24 +2374,8 @@ spec:
|
||||
appRevision:
|
||||
type: string
|
||||
contextBackend:
|
||||
description: |-
|
||||
ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
---
|
||||
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
|
||||
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
|
||||
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
|
||||
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
|
||||
Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
|
||||
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
|
||||
|
||||
|
||||
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
|
||||
description: ObjectReference contains enough information to let
|
||||
you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -2434,7 +2389,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
|
||||
@@ -3,7 +3,7 @@ kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: vela-system/kubevela-vela-core-root-cert
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: applications.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
@@ -345,7 +345,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
@@ -379,24 +378,8 @@ spec:
|
||||
description: Components record the related Components created by Application
|
||||
Controller
|
||||
items:
|
||||
description: |-
|
||||
ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
---
|
||||
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
|
||||
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
|
||||
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
|
||||
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
|
||||
Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
|
||||
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
|
||||
|
||||
|
||||
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
|
||||
description: ObjectReference contains enough information to let
|
||||
you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -410,7 +393,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
@@ -525,6 +507,10 @@ spec:
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
details:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
env:
|
||||
type: string
|
||||
healthy:
|
||||
@@ -537,24 +523,8 @@ spec:
|
||||
type: string
|
||||
scopes:
|
||||
items:
|
||||
description: |-
|
||||
ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
---
|
||||
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
|
||||
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
|
||||
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
|
||||
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
|
||||
Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
|
||||
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
|
||||
|
||||
|
||||
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
|
||||
description: ObjectReference contains enough information to
|
||||
let you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -568,7 +538,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
@@ -603,6 +572,10 @@ spec:
|
||||
description: ApplicationTraitStatus records the trait health
|
||||
status
|
||||
properties:
|
||||
details:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
healthy:
|
||||
type: boolean
|
||||
message:
|
||||
@@ -641,24 +614,8 @@ spec:
|
||||
appRevision:
|
||||
type: string
|
||||
contextBackend:
|
||||
description: |-
|
||||
ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
---
|
||||
New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.
|
||||
1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.
|
||||
2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular
|
||||
restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted".
|
||||
Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.
|
||||
4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.
|
||||
|
||||
|
||||
Instead of using this type, create a locally provided and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .
|
||||
description: ObjectReference contains enough information to let
|
||||
you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -672,7 +629,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: componentdefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
@@ -190,6 +190,10 @@ spec:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
details:
|
||||
description: Details stores a string representation of a CUE status
|
||||
map to be evaluated at runtime for display
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: definitionrevisions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
@@ -236,6 +236,10 @@ spec:
|
||||
description: CustomStatus defines the custom status message
|
||||
that could display to user
|
||||
type: string
|
||||
details:
|
||||
description: Details stores a string representation of
|
||||
a CUE status map to be evaluated at runtime for display
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy
|
||||
for the abstraction
|
||||
@@ -773,6 +777,10 @@ spec:
|
||||
description: CustomStatus defines the custom status message
|
||||
that could display to user
|
||||
type: string
|
||||
details:
|
||||
description: Details stores a string representation of
|
||||
a CUE status map to be evaluated at runtime for display
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy
|
||||
for the abstraction
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: policies.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: policydefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: resourcetrackers.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
@@ -96,7 +96,6 @@ spec:
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
TODO: this design is not final and this field is subject to change in the future.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: traitdefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
@@ -220,6 +220,10 @@ spec:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
details:
|
||||
description: Details stores a string representation of a CUE status
|
||||
map to be evaluated at runtime for display
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.14.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.5
|
||||
name: workflowstepdefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
|
||||
@@ -29,3 +29,36 @@ Welcome to use the KubeVela! Enjoy your shipping application journey!
|
||||
|
||||
|
||||
You can refer to https://kubevela.io for more details.
|
||||
|
||||
{{- if and .Values.authentication.enabled (not .Values.authentication.withUser) }}
|
||||
|
||||
WARNING: Authentication is enabled but withUser is disabled.
|
||||
This configuration provides NO security benefit:
|
||||
- All applications will run as '{{ .Values.authentication.defaultUser }}' regardless of who creates them
|
||||
- User groups matching '{{ .Values.authentication.groupPattern }}' are still collected but not used effectively
|
||||
- Service account annotations are blocked
|
||||
|
||||
To enable true user impersonation for security:
|
||||
--set authentication.withUser=true
|
||||
{{- end }}
|
||||
|
||||
{{- if and (not .Values.authorization.definitionValidationEnabled) (not .Values.authentication.enabled) }}
|
||||
|
||||
SECURITY RECOMMENDATION: Both authentication and definition validation are disabled.
|
||||
If KubeVela is running with cluster-admin or other high-level permissions,
|
||||
consider enabling one or both security features:
|
||||
|
||||
1. Authentication with impersonation (recommended for multi-tenant environments):
|
||||
--set authentication.enabled=true
|
||||
--set authentication.withUser=true
|
||||
This makes KubeVela impersonate the requesting user, applying their RBAC permissions.
|
||||
Note: Both flags must be enabled for user impersonation to work.
|
||||
|
||||
2. Definition permission validation (lightweight RBAC for definitions):
|
||||
--set authorization.definitionValidationEnabled=true
|
||||
This ensures users can only reference definitions they have access to.
|
||||
|
||||
Using both features together provides defense in depth.
|
||||
Without these protections, users can leverage KubeVela's permissions to deploy
|
||||
resources beyond their intended access level.
|
||||
{{- end }}
|
||||
|
||||
@@ -4,7 +4,7 @@ kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade,post-rollback
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission
|
||||
|
||||
@@ -4,7 +4,7 @@ kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade,post-rollback
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission-create
|
||||
name: {{ template "kubevela.fullname" . }}-admission-create
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission-create
|
||||
name: {{ template "kubevela.fullname" . }}-admission-create
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission-create
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
@@ -39,17 +39,26 @@ spec:
|
||||
- --cert-name=tls.crt
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: {{ template "kubevela.fullname" . }}-admission
|
||||
{{- with .Values.admissionWebhooks.patch.nodeSelector }}
|
||||
{{- if .Values.admissionWebhooks.patch.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- toYaml .Values.admissionWebhooks.patch.nodeSelector | nindent 8 }}
|
||||
{{- else if .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml .Values.nodeSelector | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.admissionWebhooks.patch.affinity }}
|
||||
{{- if .Values.admissionWebhooks.patch.affinity }}
|
||||
affinity:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- toYaml .Values.admissionWebhooks.patch.affinity | nindent 8 }}
|
||||
{{- else if .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml .Values.affinity | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.admissionWebhooks.patch.tolerations }}
|
||||
{{- if .Values.admissionWebhooks.patch.tolerations }}
|
||||
tolerations:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- toYaml .Values.admissionWebhooks.patch.tolerations | nindent 8 }}
|
||||
{{- else if .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml .Values.tolerations | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
runAsGroup: 2000
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission-patch
|
||||
name: {{ template "kubevela.fullname" . }}-admission-patch
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,post-upgrade
|
||||
"helm.sh/hook": post-install,post-upgrade,post-rollback
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission-patch
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission-patch
|
||||
name: {{ template "kubevela.fullname" . }}-admission-patch
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission-patch
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
@@ -41,13 +41,26 @@ spec:
|
||||
{{- end }}
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: {{ template "kubevela.fullname" . }}-admission
|
||||
{{- with .Values.admissionWebhooks.patch.affinity }}
|
||||
affinity:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- if .Values.admissionWebhooks.patch.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml .Values.admissionWebhooks.patch.nodeSelector | nindent 8 }}
|
||||
{{- else if .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml .Values.nodeSelector | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.admissionWebhooks.patch.tolerations }}
|
||||
{{- if .Values.admissionWebhooks.patch.affinity }}
|
||||
affinity:
|
||||
{{- toYaml .Values.admissionWebhooks.patch.affinity | nindent 8 }}
|
||||
{{- else if .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml .Values.affinity | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.admissionWebhooks.patch.tolerations }}
|
||||
tolerations:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- toYaml .Values.admissionWebhooks.patch.tolerations | nindent 8 }}
|
||||
{{- else if .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml .Values.tolerations | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
runAsGroup: 2000
|
||||
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade,post-rollback
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission
|
||||
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade,post-rollback
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission
|
||||
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-admission
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
|
||||
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade,post-rollback
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.name" . }}-admission
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
{{- if .Values.admissionWebhooks.enabled -}}
|
||||
{{- /* Preserve existing caBundle on upgrade to avoid breaking admission if hooks fail. */}}
|
||||
{{- $mName := printf "%s-admission" (include "kubevela.fullname" .) -}}
|
||||
{{- $existing := (lookup "admissionregistration.k8s.io/v1" "MutatingWebhookConfiguration" "" $mName) -}}
|
||||
{{- $vals := dict "apps" "" "comps" "" -}}
|
||||
{{- if $existing -}}
|
||||
{{- range $existing.webhooks -}}
|
||||
{{- if eq .name "mutating.core.oam.dev.v1beta1.applications" -}}{{- $_ := set $vals "apps" .clientConfig.caBundle -}}{{- end -}}
|
||||
{{- if eq .name "mutating.core.oam-dev.v1beta1.componentdefinitions" -}}{{- $_ := set $vals "comps" .clientConfig.caBundle -}}{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
@@ -10,7 +20,7 @@ metadata:
|
||||
{{- end }}
|
||||
webhooks:
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
caBundle: {{ default "Cg==" (get $vals "apps") }}
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -36,7 +46,7 @@ webhooks:
|
||||
resources:
|
||||
- applications
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
caBundle: {{ default "Cg==" (get $vals "comps") }}
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
{{- if .Values.admissionWebhooks.enabled -}}
|
||||
{{- /* Preserve existing caBundle on upgrade to avoid breaking admission if hooks fail. */}}
|
||||
{{- $vName := printf "%s-admission" (include "kubevela.fullname" .) -}}
|
||||
{{- $existing := (lookup "admissionregistration.k8s.io/v1" "ValidatingWebhookConfiguration" "" $vName) -}}
|
||||
{{- $vals := dict "traits" "" "apps" "" "comps" "" "policies" "" -}}
|
||||
{{- if $existing -}}
|
||||
{{- range $existing.webhooks -}}
|
||||
{{- if eq .name "validating.core.oam.dev.v1beta1.traitdefinitions" -}}{{- $_ := set $vals "traits" .clientConfig.caBundle -}}{{- end -}}
|
||||
{{- if eq .name "validating.core.oam.dev.v1beta1.applications" -}}{{- $_ := set $vals "apps" .clientConfig.caBundle -}}{{- end -}}
|
||||
{{- if eq .name "validating.core.oam-dev.v1beta1.componentdefinitions" -}}{{- $_ := set $vals "comps" .clientConfig.caBundle -}}{{- end -}}
|
||||
{{- if eq .name "validating.core.oam-dev.v1beta1.policydefinitions" -}}{{- $_ := set $vals "policies" .clientConfig.caBundle -}}{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
@@ -10,7 +22,7 @@ metadata:
|
||||
{{- end }}
|
||||
webhooks:
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
caBundle: {{ default "Cg==" (get $vals "traits") }}
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -37,7 +49,7 @@ webhooks:
|
||||
- traitdefinitions
|
||||
timeoutSeconds: 5
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
caBundle: {{ default "Cg==" (get $vals "apps") }}
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -63,7 +75,7 @@ webhooks:
|
||||
resources:
|
||||
- applications
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
caBundle: {{ default "Cg==" (get $vals "comps") }}
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -89,7 +101,7 @@ webhooks:
|
||||
resources:
|
||||
- componentdefinitions
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
caBundle: {{ default "Cg==" (get $vals "policies") }}
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -114,4 +126,30 @@ webhooks:
|
||||
- UPDATE
|
||||
resources:
|
||||
- policydefinitions
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /validating-core-oam-dev-v1beta1-workflowstepdefinitions
|
||||
{{- if .Values.admissionWebhooks.patch.enabled }}
|
||||
failurePolicy: Ignore
|
||||
{{- else }}
|
||||
failurePolicy: Fail
|
||||
{{- end }}
|
||||
name: validating.core.oam-dev.v1beta1.workflowstepdefinitions
|
||||
sideEffects: None
|
||||
admissionReviewVersions:
|
||||
- v1beta1
|
||||
- v1
|
||||
rules:
|
||||
- apiGroups:
|
||||
- core.oam.dev
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- workflowstepdefinitions
|
||||
{{- end -}}
|
||||
|
||||
@@ -190,4 +190,4 @@ subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "kubevela.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -95,6 +95,18 @@ spec:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
@@ -138,4 +150,16 @@ spec:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{ end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -39,8 +39,9 @@ spec:
|
||||
parameter: {
|
||||
// +usage=Specify the AppArmor profile for the pod
|
||||
appArmorProfile?: {
|
||||
type: "RuntimeDefault" | "Unconfined" | "Localhost"
|
||||
localhostProfile: string
|
||||
type: "RuntimeDefault" | "Unconfined" | "Localhost"
|
||||
// +usage: localhostProfile is required when type is 'Localhost'
|
||||
localhostProfile?: string
|
||||
}
|
||||
fsGroup?: int
|
||||
runAsGroup?: int
|
||||
@@ -50,8 +51,9 @@ spec:
|
||||
runAsNonRoot: *true | bool
|
||||
// +usage=Specify the seccomp profile for the pod
|
||||
seccompProfile?: {
|
||||
type: "RuntimeDefault" | "Unconfined" | "Localhost"
|
||||
localhostProfile: string
|
||||
type: "RuntimeDefault" | "Unconfined" | "Localhost"
|
||||
// +usage: localhostProfile is required when type is 'Localhost'
|
||||
localhostProfile?: string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
custom.definition.oam.dev/category: External Intergration
|
||||
custom.definition.oam.dev/category: External Integration
|
||||
definition.oam.dev/alias: ""
|
||||
definition.oam.dev/description: Send request to the url
|
||||
name: request
|
||||
@@ -14,8 +14,8 @@ spec:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"vela/op"
|
||||
"vela/http"
|
||||
"vela/builtin"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
@@ -33,14 +33,22 @@ spec:
|
||||
}
|
||||
}
|
||||
}
|
||||
fail: {
|
||||
if http.$returns.response.statusCode > 400 {
|
||||
requestFail: builtin.#Fail & {
|
||||
$params: message: "request of \(parameter.url) is fail: \(http.response.statusCode)"
|
||||
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: req.$returns != _|_
|
||||
message?: "Waiting for response from \(parameter.url)"
|
||||
}
|
||||
|
||||
fail: op.#Steps & {
|
||||
if req.$returns.statusCode > 400 {
|
||||
requestFail: op.#Fail & {
|
||||
message: "request of \(parameter.url) is fail: \(req.$returns.statusCode)"
|
||||
}
|
||||
}
|
||||
}
|
||||
response: json.Unmarshal(http.$returns.response.body)
|
||||
|
||||
response: json.Unmarshal(req.$returns.body)
|
||||
|
||||
parameter: {
|
||||
url: string
|
||||
method: *"GET" | "POST" | "PUT" | "DELETE"
|
||||
|
||||
@@ -17,49 +17,51 @@ spec:
|
||||
podDisruptive: true
|
||||
schematic:
|
||||
cue:
|
||||
template: |2
|
||||
let resourceContent = {
|
||||
resources: {
|
||||
if parameter.cpu != _|_ if parameter.memory != _|_ if parameter.requests == _|_ if parameter.limits == _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
requests: {
|
||||
cpu: parameter.cpu
|
||||
memory: parameter.memory
|
||||
template: |
|
||||
patch: {
|
||||
let resourceContent = {
|
||||
resources: {
|
||||
if parameter.cpu != _|_ if parameter.memory != _|_ if parameter.requests == _|_ if parameter.limits == _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
requests: {
|
||||
cpu: parameter.cpu
|
||||
memory: parameter.memory
|
||||
}
|
||||
// +patchStrategy=retainKeys
|
||||
limits: {
|
||||
cpu: parameter.cpu
|
||||
memory: parameter.memory
|
||||
}
|
||||
}
|
||||
// +patchStrategy=retainKeys
|
||||
limits: {
|
||||
cpu: parameter.cpu
|
||||
memory: parameter.memory
|
||||
}
|
||||
}
|
||||
|
||||
if parameter.requests != _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
requests: {
|
||||
cpu: parameter.requests.cpu
|
||||
memory: parameter.requests.memory
|
||||
if parameter.requests != _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
requests: {
|
||||
cpu: parameter.requests.cpu
|
||||
memory: parameter.requests.memory
|
||||
}
|
||||
}
|
||||
}
|
||||
if parameter.limits != _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
limits: {
|
||||
cpu: parameter.limits.cpu
|
||||
memory: parameter.limits.memory
|
||||
if parameter.limits != _|_ {
|
||||
// +patchStrategy=retainKeys
|
||||
limits: {
|
||||
cpu: parameter.limits.cpu
|
||||
memory: parameter.limits.memory
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if context.output.spec != _|_ if context.output.spec.template != _|_ {
|
||||
patch: spec: template: spec: {
|
||||
// +patchKey=name
|
||||
containers: [resourceContent]
|
||||
if context.output.spec != _|_ if context.output.spec.template != _|_ {
|
||||
spec: template: spec: {
|
||||
// +patchKey=name
|
||||
containers: [resourceContent]
|
||||
}
|
||||
}
|
||||
}
|
||||
if context.output.spec != _|_ if context.output.spec.jobTemplate != _|_ {
|
||||
patch: spec: jobTemplate: spec: template: spec: {
|
||||
// +patchKey=name
|
||||
containers: [resourceContent]
|
||||
if context.output.spec != _|_ if context.output.spec.jobTemplate != _|_ {
|
||||
spec: jobTemplate: spec: template: spec: {
|
||||
// +patchKey=name
|
||||
containers: [resourceContent]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,9 +98,6 @@ spec:
|
||||
if _params.periodSeconds != _|_ {
|
||||
periodSeconds: _params.periodSeconds
|
||||
}
|
||||
if _params.tcpSocket != _|_ {
|
||||
tcpSocket: _params.tcpSocket
|
||||
}
|
||||
if _params.timeoutSeconds != _|_ {
|
||||
timeoutSeconds: _params.timeoutSeconds
|
||||
}
|
||||
|
||||
605
charts/vela-core/templates/defwithtemplate/statefulset.yaml
Normal file
605
charts/vela-core/templates/defwithtemplate/statefulset.yaml
Normal file
@@ -0,0 +1,605 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/statefulset.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Describes long-running, scalable, containerized services used to manage stateful application, like database.
|
||||
name: statefulset
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
mountsArray: [
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.pvc != _|_ for v in parameter.volumeMounts.pvc {
|
||||
{
|
||||
mountPath: v.mountPath
|
||||
if v.subPath != _|_ {
|
||||
subPath: v.subPath
|
||||
}
|
||||
name: v.name
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.configMap != _|_ for v in parameter.volumeMounts.configMap {
|
||||
{
|
||||
mountPath: v.mountPath
|
||||
if v.subPath != _|_ {
|
||||
subPath: v.subPath
|
||||
}
|
||||
name: v.name
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.secret != _|_ for v in parameter.volumeMounts.secret {
|
||||
{
|
||||
mountPath: v.mountPath
|
||||
if v.subPath != _|_ {
|
||||
subPath: v.subPath
|
||||
}
|
||||
name: v.name
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.emptyDir != _|_ for v in parameter.volumeMounts.emptyDir {
|
||||
{
|
||||
mountPath: v.mountPath
|
||||
if v.subPath != _|_ {
|
||||
subPath: v.subPath
|
||||
}
|
||||
name: v.name
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.hostPath != _|_ for v in parameter.volumeMounts.hostPath {
|
||||
{
|
||||
mountPath: v.mountPath
|
||||
if v.subPath != _|_ {
|
||||
subPath: v.subPath
|
||||
}
|
||||
name: v.name
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
volumesList: [
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.pvc != _|_ for v in parameter.volumeMounts.pvc {
|
||||
{
|
||||
name: v.name
|
||||
persistentVolumeClaim: claimName: v.claimName
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.configMap != _|_ for v in parameter.volumeMounts.configMap {
|
||||
{
|
||||
name: v.name
|
||||
configMap: {
|
||||
defaultMode: v.defaultMode
|
||||
name: v.cmName
|
||||
if v.items != _|_ {
|
||||
items: v.items
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.secret != _|_ for v in parameter.volumeMounts.secret {
|
||||
{
|
||||
name: v.name
|
||||
secret: {
|
||||
defaultMode: v.defaultMode
|
||||
secretName: v.secretName
|
||||
if v.items != _|_ {
|
||||
items: v.items
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.emptyDir != _|_ for v in parameter.volumeMounts.emptyDir {
|
||||
{
|
||||
name: v.name
|
||||
emptyDir: medium: v.medium
|
||||
}
|
||||
},
|
||||
|
||||
if parameter.volumeMounts != _|_ if parameter.volumeMounts.hostPath != _|_ for v in parameter.volumeMounts.hostPath {
|
||||
{
|
||||
name: v.name
|
||||
hostPath: path: v.path
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
deDupVolumesArray: [
|
||||
for val in [
|
||||
for i, vi in volumesList {
|
||||
for j, vj in volumesList if j < i && vi.name == vj.name {
|
||||
_ignore: true
|
||||
}
|
||||
vi
|
||||
},
|
||||
] if val._ignore == _|_ {
|
||||
val
|
||||
},
|
||||
]
|
||||
|
||||
output: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "StatefulSet"
|
||||
spec: {
|
||||
selector: matchLabels: "app.oam.dev/component": context.name
|
||||
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
if parameter.labels != _|_ {
|
||||
parameter.labels
|
||||
}
|
||||
if parameter.addRevisionLabel {
|
||||
"app.oam.dev/revision": context.revision
|
||||
}
|
||||
"app.oam.dev/name": context.appName
|
||||
"app.oam.dev/component": context.name
|
||||
}
|
||||
if parameter.annotations != _|_ {
|
||||
annotations: parameter.annotations
|
||||
}
|
||||
}
|
||||
|
||||
spec: {
|
||||
containers: [{
|
||||
name: context.name
|
||||
image: parameter.image
|
||||
if parameter["port"] != _|_ if parameter["ports"] == _|_ {
|
||||
ports: [{
|
||||
containerPort: parameter.port
|
||||
}]
|
||||
}
|
||||
if parameter["ports"] != _|_ {
|
||||
ports: [for v in parameter.ports {
|
||||
{
|
||||
containerPort: {
|
||||
if v.containerPort != _|_ {v.containerPort}
|
||||
if v.containerPort == _|_ {v.port}
|
||||
}
|
||||
protocol: v.protocol
|
||||
if v.name != _|_ {
|
||||
name: v.name
|
||||
}
|
||||
if v.name == _|_ {
|
||||
_name: {
|
||||
if v.containerPort != _|_ {"port-" + strconv.FormatInt(v.containerPort, 10)}
|
||||
if v.containerPort == _|_ {"port-" + strconv.FormatInt(v.port, 10)}
|
||||
}
|
||||
name: *_name | string
|
||||
if v.protocol != "TCP" {
|
||||
name: _name + "-" + strings.ToLower(v.protocol)
|
||||
}
|
||||
}
|
||||
}}]
|
||||
}
|
||||
|
||||
if parameter["imagePullPolicy"] != _|_ {
|
||||
imagePullPolicy: parameter.imagePullPolicy
|
||||
}
|
||||
|
||||
if parameter["cmd"] != _|_ {
|
||||
command: parameter.cmd
|
||||
}
|
||||
|
||||
if parameter["args"] != _|_ {
|
||||
args: parameter.args
|
||||
}
|
||||
|
||||
if parameter["env"] != _|_ {
|
||||
env: parameter.env
|
||||
}
|
||||
|
||||
if context["config"] != _|_ {
|
||||
env: context.config
|
||||
}
|
||||
|
||||
if parameter["cpu"] != _|_ {
|
||||
resources: {
|
||||
limits: cpu: parameter.cpu
|
||||
requests: cpu: parameter.cpu
|
||||
}
|
||||
}
|
||||
|
||||
if parameter["memory"] != _|_ {
|
||||
resources: {
|
||||
limits: memory: parameter.memory
|
||||
requests: memory: parameter.memory
|
||||
}
|
||||
}
|
||||
|
||||
if parameter["volumes"] != _|_ if parameter["volumeMounts"] == _|_ {
|
||||
volumeMounts: [for v in parameter.volumes {
|
||||
{
|
||||
mountPath: v.mountPath
|
||||
name: v.name
|
||||
}}]
|
||||
}
|
||||
|
||||
if parameter["volumeMounts"] != _|_ {
|
||||
volumeMounts: mountsArray
|
||||
}
|
||||
|
||||
if parameter["livenessProbe"] != _|_ {
|
||||
livenessProbe: parameter.livenessProbe
|
||||
}
|
||||
|
||||
if parameter["readinessProbe"] != _|_ {
|
||||
readinessProbe: parameter.readinessProbe
|
||||
}
|
||||
|
||||
}]
|
||||
|
||||
if parameter["hostAliases"] != _|_ {
|
||||
// +patchKey=ip
|
||||
hostAliases: parameter.hostAliases
|
||||
}
|
||||
|
||||
if parameter["imagePullSecrets"] != _|_ {
|
||||
imagePullSecrets: [for v in parameter.imagePullSecrets {
|
||||
name: v
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
if parameter["volumes"] != _|_ if parameter["volumeMounts"] == _|_ {
|
||||
volumes: [for v in parameter.volumes {
|
||||
{
|
||||
name: v.name
|
||||
if v.type == "pvc" {
|
||||
persistentVolumeClaim: claimName: v.claimName
|
||||
}
|
||||
if v.type == "configMap" {
|
||||
configMap: {
|
||||
defaultMode: v.defaultMode
|
||||
name: v.cmName
|
||||
if v.items != _|_ {
|
||||
items: v.items
|
||||
}
|
||||
}
|
||||
}
|
||||
if v.type == "secret" {
|
||||
secret: {
|
||||
defaultMode: v.defaultMode
|
||||
secretName: v.secretName
|
||||
if v.items != _|_ {
|
||||
items: v.items
|
||||
}
|
||||
}
|
||||
}
|
||||
if v.type == "emptyDir" {
|
||||
emptyDir: medium: v.medium
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
if parameter["volumeMounts"] != _|_ {
|
||||
volumes: deDupVolumesArray
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exposePorts: [
|
||||
if parameter.ports != _|_ for v in parameter.ports if v.expose == true {
|
||||
port: v.port
|
||||
if v.containerPort != _|_ {targetPort: v.containerPort}
|
||||
if v.containerPort == _|_ {targetPort: v.port}
|
||||
if v.name != _|_ {name: v.name}
|
||||
if v.name == _|_ {
|
||||
_name: {
|
||||
if v.containerPort != _|_ {
|
||||
"port-" + strconv.FormatInt(v.containerPort, 10)
|
||||
}
|
||||
if v.containerPort == _|_ {
|
||||
"port-" + strconv.FormatInt(v.port, 10)
|
||||
}
|
||||
}
|
||||
name: *_name | string
|
||||
if v.protocol != "TCP" {
|
||||
name: _name + "-" + strings.ToLower(v.protocol)
|
||||
}
|
||||
}
|
||||
if v.nodePort != _|_ if parameter.exposeType == "NodePort" {
|
||||
nodePort: v.nodePort
|
||||
}
|
||||
if v.protocol != _|_ {
|
||||
protocol: v.protocol
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
outputs: {
|
||||
if len(exposePorts) != 0 {
|
||||
statefulsetsExpose: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: name: context.name
|
||||
spec: {
|
||||
selector: "app.oam.dev/component": context.name
|
||||
ports: exposePorts
|
||||
type: parameter.exposeType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parameter: {
|
||||
// +usage=Specify the labels in the workload
|
||||
labels?: [string]: string
|
||||
|
||||
// +usage=Specify the annotations in the workload
|
||||
annotations?: [string]: string
|
||||
|
||||
// +usage=Which image would you like to use for your service
|
||||
// +short=i
|
||||
image: string
|
||||
|
||||
// +usage=Specify image pull policy for your service
|
||||
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
|
||||
|
||||
// +usage=Specify image pull secrets for your service
|
||||
imagePullSecrets?: [...string]
|
||||
|
||||
// +ignore
|
||||
// +usage=Deprecated field, please use ports instead
|
||||
// +short=p
|
||||
port?: int
|
||||
|
||||
// +usage=Which ports do you want customer traffic sent to, defaults to 80
|
||||
ports?: [...{
|
||||
// +usage=Number of port to expose on the pod's IP address
|
||||
port: int
|
||||
// +usage=Number of container port to connect to, defaults to port
|
||||
containerPort?: int
|
||||
// +usage=Name of the port
|
||||
name?: string
|
||||
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
|
||||
protocol: *"TCP" | "UDP" | "SCTP"
|
||||
// +usage=Specify if the port should be exposed
|
||||
expose: *false | bool
|
||||
// +usage=exposed node port. Only Valid when exposeType is NodePort
|
||||
nodePort?: int
|
||||
}]
|
||||
|
||||
// +ignore
|
||||
// +usage=Specify what kind of Service you want. options: "ClusterIP", "NodePort", "LoadBalancer"
|
||||
exposeType: *"ClusterIP" | "NodePort" | "LoadBalancer"
|
||||
|
||||
// +ignore
|
||||
// +usage=If addRevisionLabel is true, the revision label will be added to the underlying pods
|
||||
addRevisionLabel: *false | bool
|
||||
|
||||
// +usage=Commands to run in the container
|
||||
cmd?: [...string]
|
||||
|
||||
// +usage=Arguments to the entrypoint
|
||||
args?: [...string]
|
||||
|
||||
// +usage=Define arguments by using environment variables
|
||||
env?: [...{
|
||||
// +usage=Environment variable name
|
||||
name: string
|
||||
// +usage=The value of the environment variable
|
||||
value?: string
|
||||
// +usage=Specifies a source the value of this var should come from
|
||||
valueFrom?: {
|
||||
// +usage=Selects a key of a secret in the pod's namespace
|
||||
secretKeyRef?: {
|
||||
// +usage=The name of the secret in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the secret to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
// +usage=Selects a key of a config map in the pod's namespace
|
||||
configMapKeyRef?: {
|
||||
// +usage=The name of the config map in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the config map to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
|
||||
cpu?: string
|
||||
|
||||
// +usage=Specifies the attributes of the memory resource required for the container.
|
||||
memory?: string
|
||||
|
||||
volumeMounts?: {
|
||||
// +usage=Mount PVC type volume
|
||||
pvc?: [...{
|
||||
name: string
|
||||
mountPath: string
|
||||
subPath?: string
|
||||
// +usage=The name of the PVC
|
||||
claimName: string
|
||||
}]
|
||||
// +usage=Mount ConfigMap type volume
|
||||
configMap?: [...{
|
||||
name: string
|
||||
mountPath: string
|
||||
subPath?: string
|
||||
defaultMode: *420 | int
|
||||
cmName: string
|
||||
items?: [...{
|
||||
key: string
|
||||
path: string
|
||||
mode: *511 | int
|
||||
}]
|
||||
}]
|
||||
// +usage=Mount Secret type volume
|
||||
secret?: [...{
|
||||
name: string
|
||||
mountPath: string
|
||||
subPath?: string
|
||||
defaultMode: *420 | int
|
||||
secretName: string
|
||||
items?: [...{
|
||||
key: string
|
||||
path: string
|
||||
mode: *511 | int
|
||||
}]
|
||||
}]
|
||||
// +usage=Mount EmptyDir type volume
|
||||
emptyDir?: [...{
|
||||
name: string
|
||||
mountPath: string
|
||||
subPath?: string
|
||||
medium: *"" | "Memory"
|
||||
}]
|
||||
// +usage=Mount HostPath type volume
|
||||
hostPath?: [...{
|
||||
name: string
|
||||
mountPath: string
|
||||
subPath?: string
|
||||
path: string
|
||||
}]
|
||||
}
|
||||
|
||||
// +usage=Deprecated field, use volumeMounts instead.
|
||||
volumes?: [...{
|
||||
name: string
|
||||
mountPath: string
|
||||
// +usage=Specify volume type, options: "pvc","configMap","secret","emptyDir", default to emptyDir
|
||||
type: *"emptyDir" | "pvc" | "configMap" | "secret"
|
||||
if type == "pvc" {
|
||||
claimName: string
|
||||
}
|
||||
if type == "configMap" {
|
||||
defaultMode: *420 | int
|
||||
cmName: string
|
||||
items?: [...{
|
||||
key: string
|
||||
path: string
|
||||
mode: *511 | int
|
||||
}]
|
||||
}
|
||||
if type == "secret" {
|
||||
defaultMode: *420 | int
|
||||
secretName: string
|
||||
items?: [...{
|
||||
key: string
|
||||
path: string
|
||||
mode: *511 | int
|
||||
}]
|
||||
}
|
||||
if type == "emptyDir" {
|
||||
medium: *"" | "Memory"
|
||||
}
|
||||
}]
|
||||
|
||||
// +usage=Instructions for assessing whether the container is alive.
|
||||
livenessProbe?: #HealthProbe
|
||||
|
||||
// +usage=Instructions for assessing whether the container is in a suitable state to serve traffic.
|
||||
readinessProbe?: #HealthProbe
|
||||
|
||||
// +usage=Specify the hostAliases to add
|
||||
hostAliases?: [...{
|
||||
ip: string
|
||||
hostnames: [...string]
|
||||
}]
|
||||
}
|
||||
|
||||
#HealthProbe: {
|
||||
|
||||
// +usage=Instructions for assessing container health by executing a command. Either this attribute or the httpGet attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the httpGet attribute and the tcpSocket attribute.
|
||||
exec?: {
|
||||
// +usage=A command to be executed inside the container to assess its health. Each space delimited token of the command is a separate array element. Commands exiting 0 are considered to be successful probes, whilst all other exit codes are considered failures.
|
||||
command: [...string]
|
||||
}
|
||||
|
||||
// +usage=Instructions for assessing container health by executing an HTTP GET request. Either this attribute or the exec attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the tcpSocket attribute.
|
||||
httpGet?: {
|
||||
// +usage=The endpoint, relative to the port, to which the HTTP GET request should be directed.
|
||||
path: string
|
||||
// +usage=The TCP socket within the container to which the HTTP GET request should be directed.
|
||||
port: int
|
||||
host?: string
|
||||
scheme?: *"HTTP" | string
|
||||
httpHeaders?: [...{
|
||||
name: string
|
||||
value: string
|
||||
}]
|
||||
}
|
||||
|
||||
// +usage=Instructions for assessing container health by probing a TCP socket. Either this attribute or the exec attribute or the httpGet attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the httpGet attribute.
|
||||
tcpSocket?: {
|
||||
// +usage=The TCP socket within the container that should be probed to assess container health.
|
||||
port: int
|
||||
}
|
||||
|
||||
// +usage=Number of seconds after the container is started before the first probe is initiated.
|
||||
initialDelaySeconds: *0 | int
|
||||
|
||||
// +usage=How often, in seconds, to execute the probe.
|
||||
periodSeconds: *10 | int
|
||||
|
||||
// +usage=Number of seconds after which the probe times out.
|
||||
timeoutSeconds: *1 | int
|
||||
|
||||
// +usage=Minimum consecutive successes for the probe to be considered successful after having failed.
|
||||
successThreshold: *1 | int
|
||||
|
||||
// +usage=Number of consecutive failures required to determine the container is not alive (liveness probe) or not ready (readiness probe).
|
||||
failureThreshold: *3 | int
|
||||
}
|
||||
status:
|
||||
customStatus: |-
|
||||
ready: {
|
||||
readyReplicas: *0 | int
|
||||
} & {
|
||||
if context.output.status.readyReplicas != _|_ {
|
||||
readyReplicas: context.output.status.readyReplicas
|
||||
}
|
||||
}
|
||||
message: "Ready:\(ready.readyReplicas)/\(context.output.spec.replicas)"
|
||||
healthPolicy: |-
|
||||
ready: {
|
||||
updatedReplicas: *0 | int
|
||||
readyReplicas: *0 | int
|
||||
replicas: *0 | int
|
||||
observedGeneration: *0 | int
|
||||
} & {
|
||||
if context.output.status.updatedReplicas != _|_ {
|
||||
updatedReplicas: context.output.status.updatedReplicas
|
||||
}
|
||||
if context.output.status.readyReplicas != _|_ {
|
||||
readyReplicas: context.output.status.readyReplicas
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
replicas: context.output.status.replicas
|
||||
}
|
||||
if context.output.status.observedGeneration != _|_ {
|
||||
observedGeneration: context.output.status.observedGeneration
|
||||
}
|
||||
}
|
||||
_isHealth: (context.output.spec.replicas == ready.readyReplicas) && (context.output.spec.replicas == ready.updatedReplicas) && (context.output.spec.replicas == ready.replicas) && (ready.observedGeneration == context.output.metadata.generation || ready.observedGeneration > context.output.metadata.generation)
|
||||
isHealth: *_isHealth | bool
|
||||
if context.output.metadata.annotations != _|_ {
|
||||
if context.output.metadata.annotations["app.oam.dev/disable-health-check"] != _|_ {
|
||||
isHealth: true
|
||||
}
|
||||
}
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
type: statefulsets.apps
|
||||
|
||||
@@ -57,7 +57,10 @@ spec:
|
||||
if parameter.hostPath != _|_ for v in parameter.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
path: v.path
|
||||
hostPath: {
|
||||
path: v.path
|
||||
type: v.type
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
@@ -14,6 +14,7 @@ spec:
|
||||
output: {
|
||||
apiVersion: "batch/v1"
|
||||
kind: "Job"
|
||||
metadata: name: "\(context.appName)-\(context.name)"
|
||||
spec: {
|
||||
parallelism: parameter.count
|
||||
completions: parameter.count
|
||||
|
||||
@@ -207,16 +207,32 @@ spec:
|
||||
}
|
||||
|
||||
if parameter["cpu"] != _|_ {
|
||||
resources: {
|
||||
limits: cpu: parameter.cpu
|
||||
requests: cpu: parameter.cpu
|
||||
if (parameter.limit.cpu != _|_) {
|
||||
resources: {
|
||||
requests: cpu: parameter.cpu
|
||||
limits: cpu: parameter.limit.cpu
|
||||
}
|
||||
}
|
||||
if (parameter.limit.cpu == _|_) {
|
||||
resources: {
|
||||
limits: cpu: parameter.cpu
|
||||
requests: cpu: parameter.cpu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if parameter["memory"] != _|_ {
|
||||
resources: {
|
||||
limits: memory: parameter.memory
|
||||
requests: memory: parameter.memory
|
||||
if (parameter.limit.memory != _|_) {
|
||||
resources: {
|
||||
limits: memory: parameter.limit.memory
|
||||
requests: memory: parameter.memory
|
||||
}
|
||||
}
|
||||
if (parameter.limit.memory == _|_) {
|
||||
resources: {
|
||||
limits: memory: parameter.memory
|
||||
requests: memory: parameter.memory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,6 +437,11 @@ spec:
|
||||
// +usage=Specifies the attributes of the memory resource required for the container.
|
||||
memory?: string
|
||||
|
||||
limit?: {
|
||||
cpu?: string
|
||||
memory?: string
|
||||
}
|
||||
|
||||
volumeMounts?: {
|
||||
// +usage=Mount PVC type volume
|
||||
pvc?: [...{
|
||||
|
||||
@@ -299,8 +299,8 @@ spec:
|
||||
- "--enable-external-package-for-default-compiler={{ .Values.workflow.enableExternalPackageForDefaultCompiler }}"
|
||||
- "--enable-external-package-watch-for-default-compiler={{ .Values.workflow.enableExternalPackageWatchForDefaultCompiler }}"
|
||||
- "--feature-gates=EnableSuspendOnFailure={{- .Values.workflow.enableSuspendOnFailure | toString -}}"
|
||||
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
|
||||
- "--feature-gates=GzipResourceTracker={{- .Values.featureGates.gzipResourceTracker | toString -}}"
|
||||
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
|
||||
- "--feature-gates=ZstdResourceTracker={{- .Values.featureGates.zstdResourceTracker | toString -}}"
|
||||
- "--feature-gates=ApplyOnce={{- .Values.featureGates.applyOnce | toString -}}"
|
||||
- "--feature-gates=MultiStageComponentApply= {{- .Values.featureGates.multiStageComponentApply | toString -}}"
|
||||
@@ -312,6 +312,9 @@ spec:
|
||||
- "--feature-gates=SharedDefinitionStorageForApplicationRevision={{- .Values.featureGates.sharedDefinitionStorageForApplicationRevision | toString -}}"
|
||||
- "--feature-gates=DisableWorkflowContextConfigMapCache={{- .Values.featureGates.disableWorkflowContextConfigMapCache | toString -}}"
|
||||
- "--feature-gates=EnableCueValidation={{- .Values.featureGates.enableCueValidation | toString -}}"
|
||||
- "--feature-gates=EnableApplicationStatusMetrics={{- .Values.featureGates.enableApplicationStatusMetrics | toString -}}"
|
||||
- "--feature-gates=ValidateResourcesExist={{- .Values.featureGates.validateResourcesExist | toString -}}"
|
||||
- "--feature-gates=ValidateDefinitionPermissions={{ .Values.authorization.definitionValidationEnabled | toString -}}"
|
||||
{{ if .Values.authentication.enabled }}
|
||||
{{ if .Values.authentication.withUser }}
|
||||
- "--authentication-with-user"
|
||||
@@ -325,6 +328,7 @@ spec:
|
||||
- "--feature-gates=ValidateComponentWhenSharding={{- .Values.featureGates.validateComponentWhenSharding | toString -}}"
|
||||
- "--feature-gates=DisableWebhookAutoSchedule={{- .Values.featureGates.disableWebhookAutoSchedule | toString -}}"
|
||||
{{ end }}
|
||||
- "--dev-logs={{ .Values.devLogs }}"
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
|
||||
resources:
|
||||
|
||||
@@ -48,3 +48,15 @@ spec:
|
||||
|
||||
echo "Application and its components are created"
|
||||
restartPolicy: Never
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -124,6 +124,8 @@ optimize:
|
||||
##@param featureGates.sharedDefinitionStorageForApplicationRevision use definition cache to reduce duplicated definition storage for application revision, must be used with InformerCacheFilterUnnecessaryFields
|
||||
##@param featureGates.disableWorkflowContextConfigMapCache disable the workflow context's configmap informer cache
|
||||
##@param featureGates.enableCueValidation enable the strict cue validation for cue required parameter fields
|
||||
##@param featureGates.enableApplicationStatusMetrics enable application status metrics and structured logging
|
||||
##@param featureGates.validateResourcesExist enable webhook validation to check if resource types referenced in definition templates exist in the cluster
|
||||
##@param
|
||||
featureGates:
|
||||
gzipResourceTracker: false
|
||||
@@ -140,6 +142,8 @@ featureGates:
|
||||
sharedDefinitionStorageForApplicationRevision: true
|
||||
disableWorkflowContextConfigMapCache: true
|
||||
enableCueValidation: false
|
||||
enableApplicationStatusMetrics: false
|
||||
validateResourcesExist: false
|
||||
|
||||
## @section MultiCluster parameters
|
||||
|
||||
@@ -254,6 +258,9 @@ rbac:
|
||||
## @param logDebug Enable debug logs for development purpose
|
||||
logDebug: false
|
||||
|
||||
## @param devLogs Enable formatted logging support for development purpose
|
||||
devLogs: false
|
||||
|
||||
## @param logFilePath If non-empty, write log files in this path
|
||||
logFilePath: ""
|
||||
|
||||
@@ -287,9 +294,12 @@ kubeClient:
|
||||
qps: 400
|
||||
burst: 600
|
||||
|
||||
## @param authentication.enabled Enable authentication for application
|
||||
## @param authentication.withUser Application authentication will impersonate as the request User
|
||||
## @param authentication.defaultUser Application authentication will impersonate as the User if no user provided in Application
|
||||
## @param authentication.enabled Enable authentication framework for applications
|
||||
## SECURITY NOTE: When enabled WITH authentication.withUser=true, KubeVela impersonates the requesting user
|
||||
## when deploying resources, ensuring that users cannot deploy resources beyond their RBAC permissions.
|
||||
## This is strongly recommended when KubeVela has cluster-admin or other high-level permissions.
|
||||
## @param authentication.withUser Application authentication will impersonate as the request User (must be true for security)
|
||||
## @param authentication.defaultUser Application authentication will impersonate as the User if no user provided or withUser is false
|
||||
## @param authentication.groupPattern Application authentication will impersonate as the request Group that matches the pattern
|
||||
authentication:
|
||||
enabled: false
|
||||
@@ -297,6 +307,15 @@ authentication:
|
||||
defaultUser: kubevela:vela-core
|
||||
groupPattern: kubevela:*
|
||||
|
||||
## @param authorization.definitionValidationEnabled Enable definition permission validation for RBAC checks on definitions
|
||||
## SECURITY NOTE: If KubeVela is running with cluster-admin or high-level permissions,
|
||||
## consider enabling this feature and/or authentication.enabled for security:
|
||||
## - This feature: Validates users can only reference definitions they have RBAC access to
|
||||
## - authentication.enabled: Makes KubeVela impersonate users, applying their full RBAC permissions
|
||||
## Both features can be used together for defense in depth.
|
||||
authorization:
|
||||
definitionValidationEnabled: false
|
||||
|
||||
## @param sharding.enabled When sharding enabled, the controller will run as master mode. Refer to https://github.com/kubevela/kubevela/blob/master/design/vela-core/sharding.md for details.
|
||||
## @param sharding.schedulableShards The shards available for scheduling. If empty, dynamic discovery will be used.
|
||||
sharding:
|
||||
|
||||
580
cmd/core/app/color_writer.go
Normal file
580
cmd/core/app/color_writer.go
Normal file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
Copyright 2022 The KubeVela 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 app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const (
|
||||
ansiReset = "\x1b[0m"
|
||||
ansiDate = "\x1b[36m"
|
||||
ansiInfo = "\x1b[32m"
|
||||
ansiWarn = "\x1b[33m"
|
||||
ansiError = "\x1b[31m"
|
||||
ansiFatal = "\x1b[35m"
|
||||
ansiDebug = "\x1b[34m"
|
||||
ansiThread = "\x1b[34m"
|
||||
ansiLocation = "\x1b[93m"
|
||||
ansiMessage = "\x1b[97m"
|
||||
ansiKey = "\x1b[96m"
|
||||
ansiValue = "\x1b[37m"
|
||||
)
|
||||
|
||||
var methodPatterns = []*regexp.Regexp{
|
||||
regexp.MustCompile(`(?i)\b(?:caller|func|function|method)\s*[:=]\s*"?([a-zA-Z0-9_./()*-]+)`),
|
||||
}
|
||||
|
||||
var srcIdx = newSourceIndex()
|
||||
|
||||
type colorWriter struct {
|
||||
dst io.Writer
|
||||
mu sync.Mutex
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
func newColorWriter(dst io.Writer) io.Writer {
|
||||
return &colorWriter{dst: dst}
|
||||
}
|
||||
|
||||
func (w *colorWriter) Write(p []byte) (int, error) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
written := 0
|
||||
for len(p) > 0 {
|
||||
idx := bytes.IndexByte(p, '\n')
|
||||
if idx == -1 {
|
||||
_, _ = w.buf.Write(p)
|
||||
written += len(p)
|
||||
break
|
||||
}
|
||||
_, _ = w.buf.Write(p[:idx])
|
||||
if err := w.flushLineLocked(); err != nil {
|
||||
written += idx
|
||||
return written, err
|
||||
}
|
||||
if _, err := w.dst.Write([]byte{'\n'}); err != nil {
|
||||
written += idx + 1
|
||||
return written, err
|
||||
}
|
||||
p = p[idx+1:]
|
||||
written += idx + 1
|
||||
}
|
||||
return written, nil
|
||||
}
|
||||
|
||||
func (w *colorWriter) flushLineLocked() error {
|
||||
if w.buf.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
line := w.buf.String()
|
||||
w.buf.Reset()
|
||||
_, err := io.WriteString(w.dst, formatColoredLine(line))
|
||||
return err
|
||||
}
|
||||
|
||||
func formatColoredLine(line string) string {
|
||||
if len(line) == 0 {
|
||||
return line
|
||||
}
|
||||
severity := line[0]
|
||||
rest := line[1:]
|
||||
headerEnd := strings.IndexByte(rest, ']')
|
||||
if headerEnd == -1 {
|
||||
return line
|
||||
}
|
||||
header := rest[:headerEnd]
|
||||
remainder := strings.TrimSpace(rest[headerEnd+1:])
|
||||
fields := strings.Fields(header)
|
||||
if len(fields) < 4 {
|
||||
return line
|
||||
}
|
||||
|
||||
date := fields[0]
|
||||
ts := fields[1]
|
||||
pid := strings.TrimSpace(fields[2])
|
||||
rawLocation := strings.Join(fields[3:], " ")
|
||||
level, levelColor := mapSeverity(severity)
|
||||
location := buildLocation(rawLocation, remainder)
|
||||
|
||||
sb := strings.Builder{}
|
||||
sb.Grow(len(line) + 32)
|
||||
|
||||
sb.WriteString(ansiDate)
|
||||
sb.WriteString("[")
|
||||
sb.WriteString(formatTimestamp(date, ts))
|
||||
sb.WriteString("]")
|
||||
sb.WriteString(ansiReset)
|
||||
sb.WriteString(" ")
|
||||
|
||||
sb.WriteString(levelColor)
|
||||
sb.WriteString("[")
|
||||
sb.WriteString(fmt.Sprintf("%-5s", level))
|
||||
sb.WriteString("]")
|
||||
sb.WriteString(ansiReset)
|
||||
sb.WriteString(" ")
|
||||
|
||||
sb.WriteString(ansiThread)
|
||||
sb.WriteString("[")
|
||||
sb.WriteString(pid)
|
||||
sb.WriteString("]")
|
||||
sb.WriteString(ansiReset)
|
||||
sb.WriteString(" ")
|
||||
|
||||
sb.WriteString(ansiLocation)
|
||||
sb.WriteString("[")
|
||||
sb.WriteString(location)
|
||||
sb.WriteString("]")
|
||||
sb.WriteString(ansiReset)
|
||||
|
||||
if remainder != "" {
|
||||
msg, fields := splitMessageAndFields(remainder)
|
||||
if msg != "" {
|
||||
sb.WriteString(" ")
|
||||
sb.WriteString(ansiMessage)
|
||||
sb.WriteString(msg)
|
||||
sb.WriteString(ansiReset)
|
||||
}
|
||||
for _, field := range fields {
|
||||
sb.WriteString(" ")
|
||||
sb.WriteString(ansiKey)
|
||||
sb.WriteString(field.key)
|
||||
sb.WriteString(ansiReset)
|
||||
sb.WriteString("=")
|
||||
sb.WriteString(ansiValue)
|
||||
sb.WriteString(field.renderValue())
|
||||
sb.WriteString(ansiReset)
|
||||
}
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func mapSeverity(s byte) (string, string) {
|
||||
switch s {
|
||||
case 'I':
|
||||
return "INFO", ansiInfo
|
||||
case 'W':
|
||||
return "WARN", ansiWarn
|
||||
case 'E':
|
||||
return "ERROR", ansiError
|
||||
case 'F':
|
||||
return "FATAL", ansiFatal
|
||||
case 'D':
|
||||
return "DEBUG", ansiDebug
|
||||
default:
|
||||
return string(s), ansiDebug
|
||||
}
|
||||
}
|
||||
|
||||
func formatTimestamp(date, ts string) string {
|
||||
if len(date) == 4 {
|
||||
return fmt.Sprintf("%s-%s %s", date[:2], date[2:], trimMicros(ts))
|
||||
}
|
||||
return strings.TrimSpace(date + " " + trimMicros(ts))
|
||||
}
|
||||
|
||||
func trimMicros(ts string) string {
|
||||
if dot := strings.IndexByte(ts, '.'); dot != -1 && len(ts) > dot+4 {
|
||||
return ts[:dot+4]
|
||||
}
|
||||
return ts
|
||||
}
|
||||
|
||||
func buildLocation(rawLocation, remainder string) string {
|
||||
file, line := splitFileAndLine(rawLocation)
|
||||
method := lookupMethod(file, line)
|
||||
if method == "" {
|
||||
method = extractMethodName(remainder)
|
||||
}
|
||||
if file == "" {
|
||||
return rawLocation
|
||||
}
|
||||
if method == "" {
|
||||
if line != "" {
|
||||
return fmt.Sprintf("%s:%s", file, line)
|
||||
}
|
||||
return file
|
||||
}
|
||||
if line == "" {
|
||||
return fmt.Sprintf("%s:%s", file, method)
|
||||
}
|
||||
return fmt.Sprintf("%s:%s:%s", file, method, line)
|
||||
}
|
||||
|
||||
func splitFileAndLine(raw string) (string, string) {
|
||||
trimmed := strings.TrimSpace(raw)
|
||||
if trimmed == "" {
|
||||
return "", ""
|
||||
}
|
||||
lastColon := strings.LastIndex(trimmed, ":")
|
||||
if lastColon == -1 {
|
||||
return trimmed, ""
|
||||
}
|
||||
return strings.TrimSpace(trimmed[:lastColon]), strings.TrimSpace(trimmed[lastColon+1:])
|
||||
}
|
||||
|
||||
type kvField struct {
|
||||
key string
|
||||
value string
|
||||
quoted bool
|
||||
}
|
||||
|
||||
func (f kvField) renderValue() string {
|
||||
if f.quoted {
|
||||
return fmt.Sprintf("\"%s\"", f.value)
|
||||
}
|
||||
return f.value
|
||||
}
|
||||
|
||||
func splitMessageAndFields(s string) (string, []kvField) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return "", nil
|
||||
}
|
||||
idx := findFirstKVIndex(s)
|
||||
if idx == -1 {
|
||||
return s, nil
|
||||
}
|
||||
msg := strings.TrimSpace(s[:idx])
|
||||
fields := parseKeyValues(s[idx:])
|
||||
return msg, fields
|
||||
}
|
||||
|
||||
func findFirstKVIndex(s string) int {
|
||||
inQuotes := false
|
||||
for i := 0; i < len(s); i++ {
|
||||
ch := s[i]
|
||||
if ch == '"' {
|
||||
if i == 0 || s[i-1] != '\\' {
|
||||
inQuotes = !inQuotes
|
||||
}
|
||||
continue
|
||||
}
|
||||
if inQuotes {
|
||||
continue
|
||||
}
|
||||
if ch == '=' {
|
||||
keyEnd := i
|
||||
keyStart := keyEnd - 1
|
||||
for keyStart >= 0 && !unicode.IsSpace(rune(s[keyStart])) {
|
||||
keyStart--
|
||||
}
|
||||
key := strings.TrimSpace(s[keyStart+1 : keyEnd])
|
||||
if isValidKey(key) {
|
||||
return keyStart + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func parseKeyValues(s string) []kvField {
|
||||
fields := make([]kvField, 0)
|
||||
i := 0
|
||||
for i < len(s) {
|
||||
for i < len(s) && unicode.IsSpace(rune(s[i])) {
|
||||
i++
|
||||
}
|
||||
if i >= len(s) {
|
||||
break
|
||||
}
|
||||
keyStart := i
|
||||
for i < len(s) && s[i] != '=' && !unicode.IsSpace(rune(s[i])) {
|
||||
i++
|
||||
}
|
||||
keyEnd := i
|
||||
for keyEnd > keyStart && unicode.IsSpace(rune(s[keyEnd-1])) {
|
||||
keyEnd--
|
||||
}
|
||||
if i >= len(s) || s[i] != '=' {
|
||||
for i < len(s) && !unicode.IsSpace(rune(s[i])) {
|
||||
i++
|
||||
}
|
||||
continue
|
||||
}
|
||||
key := s[keyStart:keyEnd]
|
||||
if !isValidKey(key) {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
i++
|
||||
for i < len(s) && unicode.IsSpace(rune(s[i])) {
|
||||
i++
|
||||
}
|
||||
if i >= len(s) {
|
||||
fields = append(fields, kvField{key: key, value: "", quoted: false})
|
||||
break
|
||||
}
|
||||
quoted := false
|
||||
var value string
|
||||
if s[i] == '"' {
|
||||
quoted = true
|
||||
i++
|
||||
start := i
|
||||
for i < len(s) {
|
||||
if s[i] == '"' && (i == start || s[i-1] != '\\') {
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
value = s[start:i]
|
||||
if i < len(s) && s[i] == '"' {
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
start := i
|
||||
for i < len(s) && !unicode.IsSpace(rune(s[i])) {
|
||||
i++
|
||||
}
|
||||
value = s[start:i]
|
||||
}
|
||||
fields = append(fields, kvField{key: key, value: value, quoted: quoted})
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func isValidKey(key string) bool {
|
||||
if key == "" {
|
||||
return false
|
||||
}
|
||||
for _, r := range key {
|
||||
if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' || r == '-' || r == '.' {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func extractMethodName(remainder string) string {
|
||||
if remainder == "" {
|
||||
return ""
|
||||
}
|
||||
for _, pattern := range methodPatterns {
|
||||
if matches := pattern.FindStringSubmatch(remainder); len(matches) > 1 {
|
||||
return simplifyMethodName(matches[1])
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func simplifyMethodName(name string) string {
|
||||
if name == "" {
|
||||
return ""
|
||||
}
|
||||
name = strings.Trim(name, "\"' ")
|
||||
if idx := strings.LastIndex(name, "/"); idx != -1 {
|
||||
name = name[idx+1:]
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func lookupMethod(file, line string) string {
|
||||
if file == "" || line == "" {
|
||||
return ""
|
||||
}
|
||||
ln, err := strconv.Atoi(line)
|
||||
if err != nil || ln <= 0 {
|
||||
return ""
|
||||
}
|
||||
return srcIdx.functionAt(file, ln)
|
||||
}
|
||||
|
||||
type funcInfo struct {
|
||||
name string
|
||||
startLine int
|
||||
endLine int
|
||||
}
|
||||
|
||||
type fileCache struct {
|
||||
once sync.Once
|
||||
funcs []funcInfo
|
||||
}
|
||||
|
||||
type sourceIndex struct {
|
||||
mu sync.Mutex
|
||||
files map[string]*fileCache
|
||||
}
|
||||
|
||||
func newSourceIndex() *sourceIndex {
|
||||
return &sourceIndex{files: make(map[string]*fileCache)}
|
||||
}
|
||||
|
||||
func (s *sourceIndex) functionAt(base string, line int) string {
|
||||
s.mu.Lock()
|
||||
cache, ok := s.files[base]
|
||||
if !ok {
|
||||
cache = &fileCache{}
|
||||
s.files[base] = cache
|
||||
}
|
||||
s.mu.Unlock()
|
||||
|
||||
cache.once.Do(func() {
|
||||
cache.funcs = loadFunctionsFor(base)
|
||||
})
|
||||
for _, fn := range cache.funcs {
|
||||
if line >= fn.startLine && line <= fn.endLine {
|
||||
return fn.name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func loadFunctionsFor(base string) []funcInfo {
|
||||
paths := findSourceFiles(base)
|
||||
if len(paths) == 0 {
|
||||
return nil
|
||||
}
|
||||
infos := make([]funcInfo, 0, len(paths)*4)
|
||||
for _, path := range paths {
|
||||
fset := token.NewFileSet()
|
||||
fileAst, err := parser.ParseFile(fset, path, nil, 0)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, decl := range fileAst.Decls {
|
||||
fn, ok := decl.(*ast.FuncDecl)
|
||||
if !ok || fn.Name == nil {
|
||||
continue
|
||||
}
|
||||
start := fset.Position(fn.Pos()).Line
|
||||
end := fset.Position(fn.End()).Line
|
||||
name := fn.Name.Name
|
||||
if recv := receiverType(fn); recv != "" {
|
||||
name = fmt.Sprintf("%s.%s", recv, name)
|
||||
}
|
||||
infos = append(infos, funcInfo{name: name, startLine: start, endLine: end})
|
||||
}
|
||||
}
|
||||
return infos
|
||||
}
|
||||
|
||||
func receiverType(fn *ast.FuncDecl) string {
|
||||
if fn.Recv == nil || len(fn.Recv.List) == 0 {
|
||||
return ""
|
||||
}
|
||||
return typeString(fn.Recv.List[0].Type)
|
||||
}
|
||||
|
||||
func typeString(expr ast.Expr) string {
|
||||
switch v := expr.(type) {
|
||||
case *ast.Ident:
|
||||
return v.Name
|
||||
case *ast.StarExpr:
|
||||
return typeString(v.X)
|
||||
case *ast.SelectorExpr:
|
||||
return v.Sel.Name
|
||||
case *ast.IndexExpr:
|
||||
return typeString(v.X)
|
||||
case *ast.IndexListExpr:
|
||||
return typeString(v.X)
|
||||
case *ast.ParenExpr:
|
||||
return typeString(v.X)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
searchRootsOnce sync.Once
|
||||
cachedRoots []string
|
||||
)
|
||||
|
||||
func findSourceFiles(base string) []string {
|
||||
matches := make([]string, 0)
|
||||
seen := make(map[string]struct{})
|
||||
for _, root := range sourceRoots() {
|
||||
if root == "" {
|
||||
continue
|
||||
}
|
||||
lookupFilesInRoot(root, base, seen, &matches)
|
||||
}
|
||||
return matches
|
||||
}
|
||||
|
||||
func sourceRoots() []string {
|
||||
searchRootsOnce.Do(func() {
|
||||
roots := make([]string, 0, 4)
|
||||
if env := os.Getenv("VELA_SOURCE_ROOT"); env != "" {
|
||||
for _, item := range strings.Split(env, string(os.PathListSeparator)) {
|
||||
if trimmed := strings.TrimSpace(item); trimmed != "" {
|
||||
roots = append(roots, trimmed)
|
||||
}
|
||||
}
|
||||
}
|
||||
if cwd, err := os.Getwd(); err == nil {
|
||||
roots = append(roots, cwd)
|
||||
}
|
||||
cachedRoots = dedupeStrings(roots)
|
||||
})
|
||||
return cachedRoots
|
||||
}
|
||||
|
||||
func lookupFilesInRoot(root, base string, seen map[string]struct{}, matches *[]string) {
|
||||
_ = filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
// Continue scanning on error.
|
||||
//nolint:nilerr
|
||||
return nil
|
||||
}
|
||||
if d.IsDir() {
|
||||
name := d.Name()
|
||||
if name == "vendor" || name == "node_modules" || strings.HasPrefix(name, ".") {
|
||||
if root == path {
|
||||
return nil
|
||||
}
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if d.Name() == base {
|
||||
if _, ok := seen[path]; !ok {
|
||||
seen[path] = struct{}{}
|
||||
*matches = append(*matches, path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func dedupeStrings(in []string) []string {
|
||||
seen := make(map[string]struct{}, len(in))
|
||||
out := make([]string, 0, len(in))
|
||||
for _, v := range in {
|
||||
if _, ok := seen[v]; ok {
|
||||
continue
|
||||
}
|
||||
seen[v] = struct{}{}
|
||||
out = append(out, v)
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func TestPreStartHook(t *testing.T) {
|
||||
|
||||
var _ = Describe("Test pre-start hooks", func() {
|
||||
It("Test SystemCRDValidationHook", func() {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(&testing.T{}, utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, true)()
|
||||
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, true)
|
||||
ctx := context.Background()
|
||||
Expect(k8s.EnsureNamespace(ctx, singleton.KubeClient.Get(), types.DefaultKubeVelaNS)).Should(Succeed())
|
||||
err := hooks.NewSystemCRDValidationHook().Run(ctx)
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/kubevela/pkg/cue/cuex"
|
||||
|
||||
pkgclient "github.com/kubevela/pkg/controller/client"
|
||||
ctrlrec "github.com/kubevela/pkg/controller/reconciler"
|
||||
"github.com/kubevela/pkg/controller/sharding"
|
||||
@@ -35,7 +37,6 @@ import (
|
||||
oamcontroller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/resourcekeeper"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/providers"
|
||||
)
|
||||
|
||||
// CoreOptions contains everything necessary to create and run vela-core
|
||||
@@ -49,6 +50,7 @@ type CoreOptions struct {
|
||||
LogFilePath string
|
||||
LogFileMaxSize uint64
|
||||
LogDebug bool
|
||||
DevLogs bool
|
||||
ControllerArgs *oamcontroller.Args
|
||||
HealthAddr string
|
||||
StorageDriver string
|
||||
@@ -75,6 +77,7 @@ func NewCoreOptions() *CoreOptions {
|
||||
LogFilePath: "",
|
||||
LogFileMaxSize: 1024,
|
||||
LogDebug: false,
|
||||
DevLogs: false,
|
||||
ControllerArgs: &oamcontroller.Args{
|
||||
RevisionLimit: 50,
|
||||
AppRevisionLimit: 10,
|
||||
@@ -115,6 +118,7 @@ func (s *CoreOptions) Flags() cliflag.NamedFlagSets {
|
||||
gfs.StringVar(&s.LogFilePath, "log-file-path", s.LogFilePath, "The file to write logs to.")
|
||||
gfs.Uint64Var(&s.LogFileMaxSize, "log-file-max-size", s.LogFileMaxSize, "Defines the maximum size a log file can grow to, Unit is megabytes.")
|
||||
gfs.BoolVar(&s.LogDebug, "log-debug", s.LogDebug, "Enable debug logs for development purpose")
|
||||
gfs.BoolVar(&s.DevLogs, "dev-logs", s.DevLogs, "Enable ANSI color formatting for console logs (ignored when log-file-path is set)")
|
||||
gfs.StringVar(&s.HealthAddr, "health-addr", s.HealthAddr, "The address the health endpoint binds to.")
|
||||
gfs.DurationVar(&s.InformerSyncPeriod, "informer-sync-period", s.InformerSyncPeriod,
|
||||
"The re-sync period for informer in controller-runtime. This is a system-level configuration.")
|
||||
@@ -129,8 +133,8 @@ func (s *CoreOptions) Flags() cliflag.NamedFlagSets {
|
||||
gfs.BoolVar(&s.EnableClusterGateway, "enable-cluster-gateway", s.EnableClusterGateway, "Enable cluster-gateway to use multicluster, disabled by default.")
|
||||
gfs.BoolVar(&s.EnableClusterMetrics, "enable-cluster-metrics", s.EnableClusterMetrics, "Enable cluster-metrics-management to collect metrics from clusters with cluster-gateway, disabled by default. When this param is enabled, enable-cluster-gateway should be enabled")
|
||||
gfs.DurationVar(&s.ClusterMetricsInterval, "cluster-metrics-interval", s.ClusterMetricsInterval, "The interval that ClusterMetricsMgr will collect metrics from clusters, default value is 15 seconds.")
|
||||
gfs.BoolVar(&providers.EnableExternalPackageForDefaultCompiler, "enable-external-package-for-default-compiler", providers.EnableExternalPackageForDefaultCompiler, "Enable external package for default compiler")
|
||||
gfs.BoolVar(&providers.EnableExternalPackageWatchForDefaultCompiler, "enable-external-package-watch-for-default-compiler", providers.EnableExternalPackageWatchForDefaultCompiler, "Enable external package watch for default compiler")
|
||||
gfs.BoolVar(&cuex.EnableExternalPackageForDefaultCompiler, "enable-external-package-for-default-compiler", cuex.EnableExternalPackageForDefaultCompiler, "Enable external package for default compiler")
|
||||
gfs.BoolVar(&cuex.EnableExternalPackageWatchForDefaultCompiler, "enable-external-package-watch-for-default-compiler", cuex.EnableExternalPackageWatchForDefaultCompiler, "Enable external package watch for default compiler")
|
||||
|
||||
s.ControllerArgs.AddFlags(fss.FlagSet("controllerArgs"), s.ControllerArgs)
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/kubevela/pkg/cue/cuex"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
oamcontroller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
)
|
||||
@@ -96,3 +98,26 @@ func TestCoreOptions_Flags(t *testing.T) {
|
||||
t.Errorf("Flags() diff: %v", cmp.Diff(opt, expected, cmp.AllowUnexported(CoreOptions{})))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCuexOptions_Flags(t *testing.T) {
|
||||
pflag.NewFlagSet("test", pflag.ContinueOnError)
|
||||
cuex.EnableExternalPackageForDefaultCompiler = false
|
||||
cuex.EnableExternalPackageWatchForDefaultCompiler = false
|
||||
|
||||
opts := &CoreOptions{
|
||||
ControllerArgs: &oamcontroller.Args{},
|
||||
}
|
||||
fss := opts.Flags()
|
||||
|
||||
args := []string{
|
||||
"--enable-external-package-for-default-compiler=true",
|
||||
"--enable-external-package-watch-for-default-compiler=true",
|
||||
}
|
||||
err := fss.FlagSet("generic").Parse(args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
assert.True(t, cuex.EnableExternalPackageForDefaultCompiler, "The --enable-external-package-for-default-compiler flag should be enabled")
|
||||
assert.True(t, cuex.EnableExternalPackageWatchForDefaultCompiler, "The --enable-external-package-watch-for-default-compiler flag should be enabled")
|
||||
}
|
||||
|
||||
@@ -103,6 +103,17 @@ func run(ctx context.Context, s *options.CoreOptions) error {
|
||||
restConfig.QPS = float32(s.QPS)
|
||||
restConfig.Burst = s.Burst
|
||||
restConfig.Wrap(auth.NewImpersonatingRoundTripper)
|
||||
|
||||
// Set logger (use --dev-logs=true for local development)
|
||||
if s.DevLogs {
|
||||
logOutput := newColorWriter(os.Stdout)
|
||||
klog.LogToStderr(false)
|
||||
klog.SetOutput(logOutput)
|
||||
ctrl.SetLogger(textlogger.NewLogger(textlogger.NewConfig(textlogger.Output(logOutput))))
|
||||
} else {
|
||||
ctrl.SetLogger(textlogger.NewLogger(textlogger.NewConfig()))
|
||||
}
|
||||
|
||||
klog.InfoS("Kubernetes Config Loaded",
|
||||
"UserAgent", restConfig.UserAgent,
|
||||
"QPS", restConfig.QPS,
|
||||
@@ -127,8 +138,6 @@ func run(ctx context.Context, s *options.CoreOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
ctrl.SetLogger(textlogger.NewLogger(textlogger.NewConfig()))
|
||||
|
||||
if utilfeature.DefaultMutableFeatureGate.Enabled(features.ApplyOnce) {
|
||||
commonconfig.ApplicationReSyncPeriod = s.InformerSyncPeriod
|
||||
}
|
||||
|
||||
191
docs/WEBHOOK_DEBUGGING.md
Normal file
191
docs/WEBHOOK_DEBUGGING.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# KubeVela Webhook Debugging Guide
|
||||
|
||||
This guide explains how to debug KubeVela webhook validation locally, particularly for the feature that validates ComponentDefinitions, TraitDefinitions, and PolicyDefinitions to ensure they don't reference non-existent CRDs.
|
||||
|
||||
## Overview
|
||||
|
||||
The webhook validation feature checks that CUE templates in definitions only reference Kubernetes resources that exist on the cluster. This prevents runtime errors when non-existent CRDs are referenced.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker Desktop or similar container runtime
|
||||
- k3d for local Kubernetes clusters
|
||||
- VS Code with Go extension
|
||||
- kubectl configured
|
||||
- openssl for certificate generation
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Complete setup (cluster + CRDs + webhook)
|
||||
make webhook-debug-setup
|
||||
|
||||
# 2. Start VS Code debugger
|
||||
# Press F5 and select "Debug Webhook Validation"
|
||||
```
|
||||
|
||||
## Detailed Setup Steps
|
||||
|
||||
### 1. Environment Setup
|
||||
|
||||
```bash
|
||||
# Create k3d cluster
|
||||
make k3d-create
|
||||
|
||||
# Install KubeVela CRDs
|
||||
make manifests
|
||||
kubectl apply -f charts/vela-core/crds/
|
||||
```
|
||||
|
||||
### 2. Webhook Certificate Setup
|
||||
|
||||
The webhook requires TLS certificates with proper Subject Alternative Names (SANs) for IP addresses.
|
||||
|
||||
```bash
|
||||
# Generate certificates and create Kubernetes secret
|
||||
make webhook-setup
|
||||
```
|
||||
|
||||
This creates:
|
||||
- CA certificate and key
|
||||
- Server certificate with IP SANs (127.0.0.1, Docker internal IP, local machine IP)
|
||||
- Kubernetes Secret `webhook-server-cert` in `vela-system` namespace
|
||||
- ValidatingWebhookConfiguration pointing to local debugger
|
||||
|
||||
### 3. Start Debugger in VS Code
|
||||
|
||||
#### VS Code Launch Configuration
|
||||
|
||||
If you're using VSCode add this configuration to `.vscode/launch.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug Webhook Validation",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}/cmd/core",
|
||||
"args": [
|
||||
"--log-debug=true",
|
||||
"--metrics-addr=:8080",
|
||||
"--enable-leader-election=false",
|
||||
"--use-webhook=true",
|
||||
"--webhook-port=9445",
|
||||
"--webhook-cert-dir=${workspaceFolder}/k8s-webhook-server/serving-certs"
|
||||
],
|
||||
"env": {
|
||||
"KUBECONFIG": "${env:HOME}/.kube/config",
|
||||
"POD_NAMESPACE": "vela-system"
|
||||
},
|
||||
"showLog": false,
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Set Breakpoints
|
||||
|
||||
Recommended breakpoint locations:
|
||||
- `pkg/webhook/core.oam.dev/v1beta1/componentdefinition/validating_handler.go` - ComponentDefinition handler
|
||||
- `pkg/webhook/core.oam.dev/v1beta1/traitdefinition/validating_handler.go` - TraitDefinition handler
|
||||
- `pkg/webhook/core.oam.dev/v1beta1/policydefinition/validating_handler.go` - PolicyDefinition handler
|
||||
- `pkg/webhook/core.oam.dev/v1beta1/workflowstepdefinition/workflowstep_validating_handler.go` - WorkflowDefinition handler
|
||||
|
||||
#### Launch Debugger
|
||||
|
||||
1. Open VS Code
|
||||
2. Press `F5` or go to Run → Start Debugging
|
||||
3. Select **"Debug Webhook Validation"** configuration
|
||||
4. Wait for webhook server to start (look for message about port 9445)
|
||||
|
||||
The debugger configuration includes:
|
||||
- `--use-webhook=true` - Enables webhook server
|
||||
- `--webhook-port=9445` - Port for webhook server
|
||||
- `--webhook-cert-dir` - Path to certificates
|
||||
- `POD_NAMESPACE=vela-system` - Required for finding the secret
|
||||
|
||||
## Make Targets Reference
|
||||
|
||||
| Target | Description |
|
||||
|--------|-------------|
|
||||
| `make webhook-help` | Show webhook debugging help |
|
||||
| `make webhook-debug-setup` | Complete setup (cluster + CRDs + webhook) |
|
||||
| `make k3d-create` | Create k3d cluster |
|
||||
| `make k3d-delete` | Delete k3d cluster |
|
||||
| `make webhook-setup` | Setup certificates and webhook configuration |
|
||||
| `make webhook-clean` | Clean up webhook environment |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Refused Error
|
||||
|
||||
If you get "connection refused" errors:
|
||||
1. Ensure the debugger is running in VS Code
|
||||
2. Check that port 9445 is not blocked by firewall
|
||||
3. Verify the webhook server started (check VS Code console)
|
||||
|
||||
### TLS Certificate Errors
|
||||
|
||||
If you get certificate validation errors:
|
||||
1. Regenerate certificates: `make webhook-setup`
|
||||
2. Restart the debugger
|
||||
3. Ensure IP addresses in certificates match your setup
|
||||
|
||||
### Webhook Not Triggering
|
||||
|
||||
If the webhook doesn't trigger:
|
||||
1. Check ValidatingWebhookConfiguration: `kubectl get validatingwebhookconfiguration`
|
||||
2. Verify the webhook URL matches your debugger's IP
|
||||
3. Check namespace is correct (vela-system)
|
||||
|
||||
### Secret Not Found
|
||||
|
||||
If you see "Wait webhook secret" messages:
|
||||
1. Ensure the secret exists: `kubectl get secret webhook-server-cert -n vela-system`
|
||||
2. Recreate if needed: `make webhook-setup`
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Certificate Generation**: Creates TLS certificates with proper SANs for local IPs
|
||||
2. **Secret Creation**: Stores certificates in Kubernetes secret
|
||||
3. **Webhook Configuration**: Creates ValidatingWebhookConfiguration pointing to local debugger
|
||||
4. **Debugger Startup**: VS Code starts the webhook server on port 9445
|
||||
5. **Validation**: When definitions are applied, Kubernetes calls the webhook
|
||||
6. **Debugging**: Breakpoints allow stepping through validation logic
|
||||
|
||||
## Files and Components
|
||||
|
||||
- **Script**: `hack/debug-webhook-setup.sh` - Main setup script
|
||||
- **Makefile**: `makefiles/develop.mk` - Make targets for debugging
|
||||
- **VS Code Config**: `.vscode/launch.json` - Debugger configuration
|
||||
- **Test Files**: `test/webhook-*.yaml` - Test manifests
|
||||
- **Validation Logic**: `pkg/webhook/utils/utils.go` - Core validation implementation
|
||||
- **Handlers**: `pkg/webhook/core.oam.dev/v1beta1/*/validating_handler.go` - Resource handlers
|
||||
|
||||
## Clean Up
|
||||
|
||||
```bash
|
||||
# Clean up webhook setup
|
||||
make webhook-clean
|
||||
|
||||
# Delete k3d cluster
|
||||
make k3d-delete
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
1. **Always start the debugger before testing** - The webhook configuration points to your local machine
|
||||
2. **Use breakpoints wisely** - Too many breakpoints can cause timeouts
|
||||
3. **Check logs** - VS Code Debug Console shows detailed logs
|
||||
4. **Test both valid and invalid cases** - Ensures validation works correctly
|
||||
5. **Keep certificates updated** - Regenerate if IPs change
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [KubeVela Webhook Implementation](../pkg/webhook/README.md)
|
||||
- [CUE Template Validation](../pkg/webhook/utils/README.md)
|
||||
- [Admission Webhooks](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)
|
||||
@@ -42,6 +42,6 @@ spec:
|
||||
repoType: helm
|
||||
retries: 3
|
||||
secretRef: kubevela-core
|
||||
url: https://charts.kubevela.net/core
|
||||
url: "https://kubevela.github.io/charts"
|
||||
type: helm
|
||||
```
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
# How to use
|
||||
The Kubevela platform out of the box provides supported and complete `StatefulSet` component and `Storage` trait. This example is just provided for education.
|
||||
|
||||
Please check also the online documentation:
|
||||
* [Trait Definition](https://kubevela.io/docs/platform-engineers/traits/customize-trait/)
|
||||
* [Component Definition](https://kubevela.io/docs/platform-engineers/components/custom-component/)
|
||||
|
||||
# Yet another example defining a custom component and custom trait
|
||||
|
||||
1. define a stateful component with StatefulSet as output
|
||||
|
||||
|
||||
@@ -15,6 +15,6 @@ spec:
|
||||
properties:
|
||||
volumeClaimTemplates:
|
||||
- name: test
|
||||
requests: 10Gi
|
||||
storageClassName: cbs
|
||||
requests: 1Gi
|
||||
storageClassName: local-path
|
||||
mountPath: /usr/share/nginx/html
|
||||
@@ -24,9 +24,9 @@ spec:
|
||||
type: helm
|
||||
properties:
|
||||
repoType: helm
|
||||
url: https://charts.kubevela.net/addons
|
||||
url: https://kubevela.github.io/charts
|
||||
chart: terraform-controller
|
||||
version: 0.2.11
|
||||
version: 0.8.0
|
||||
values:
|
||||
image:
|
||||
repository: ghcr.io/kubevela/oamdev/terraform-controller
|
||||
|
||||
@@ -22,7 +22,7 @@ entries:
|
||||
version: 2.0.0
|
||||
annotations:
|
||||
system.vela: ">=1.5.0"
|
||||
system.kubernetes: ">=1.30.0"
|
||||
system.kubernetes: ">=1.32.0"
|
||||
vela-workflow:
|
||||
- annotations:
|
||||
system.vela: '>=v1.6.0-beta.1'
|
||||
@@ -32,8 +32,8 @@ entries:
|
||||
icon: https://static.kubevela.net/images/logos/KubeVela%20-03.png
|
||||
name: vela-workflow
|
||||
urls:
|
||||
- http://127.0.0.1:9098/helm/vela-workflow-v0.3.5.tgz
|
||||
version: v0.3.5
|
||||
- http://127.0.0.1:9098/helm/vela-workflow-v0.6.2.tgz
|
||||
version: v0.6.2
|
||||
foo:
|
||||
- created: "2022-10-29T09:11:16.865230605Z"
|
||||
description: Vela test addon named foo
|
||||
|
||||
Binary file not shown.
BIN
e2e/addon/mock/testrepo/helm-repo/vela-workflow-v0.6.2.tgz
Normal file
BIN
e2e/addon/mock/testrepo/helm-repo/vela-workflow-v0.6.2.tgz
Normal file
Binary file not shown.
@@ -125,8 +125,8 @@ var helmHandler http.HandlerFunc = func(rw http.ResponseWriter, req *http.Reques
|
||||
_, _ = rw.Write([]byte(err.Error()))
|
||||
}
|
||||
rw.Write(file)
|
||||
case strings.Contains(req.URL.Path, "vela-workflow-v0.3.5.tgz"):
|
||||
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/vela-workflow-v0.3.5.tgz")
|
||||
case strings.Contains(req.URL.Path, "vela-workflow-v0.6.2.tgz"):
|
||||
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/vela-workflow-v0.6.2.tgz")
|
||||
if err != nil {
|
||||
_, _ = rw.Write([]byte(err.Error()))
|
||||
}
|
||||
|
||||
@@ -44,20 +44,23 @@ var (
|
||||
applicationName = "app-basic"
|
||||
traitAlias = "scaler"
|
||||
appNameForInit = "initmyapp"
|
||||
jsonAppFile = `{"name":"nginx-vela","services":{"nginx":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
|
||||
testDeleteJsonAppFile = `{"name":"test-vela-delete","services":{"nginx-test":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
|
||||
appbasicJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
|
||||
appbasicAddTraitJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}],"scaler":{"replicas":2}}}}`
|
||||
jsonAppFile = `{"name":"nginx-vela","services":{"nginx":{"type":"webservice","image":"nginx:1.29.0","ports":[{port: 80, expose: true}]}}}`
|
||||
testDeleteJsonAppFile = `{"name":"test-vela-delete","services":{"nginx-test":{"type":"webservice","image":"nginx:1.29.0","ports":[{port: 80, expose: true}]}}}`
|
||||
appbasicJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.29.0","ports":[{port: 80, expose: true}]}}}`
|
||||
appbasicAddTraitJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.29.0","ports":[{port: 80, expose: true}],"scaler":{"replicas":2}}}}`
|
||||
velaQL = "test-component-pod-view{appNs=default,appName=nginx-vela,name=nginx}"
|
||||
|
||||
waitAppfileToSuccess = `{"name":"app-wait-success","services":{"app-basic1":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
|
||||
waitAppfileToSuccess = `{"name":"app-wait-success","services":{"app-basic1":{"type":"webservice","image":"nginx:1.29.0","ports":[{port: 80, expose: true}]}}}`
|
||||
waitAppfileToFail = `{"name":"app-wait-fail","services":{"app-basic2":{"type":"webservice","image":"nginx:fail","ports":[{port: 80, expose: true}]}}}`
|
||||
|
||||
componentDependsOnFailApp = `{"name":"comp-depends-fail","services":{"failing-db":{"type":"webservice","image": ""},"dependent-service":{"type":"webservice","dependsOn":["failing-db"],"image":"nginx:latest","ports":[{"port":8080,"expose":false}]}}}`
|
||||
componentDependsOnMultipleApp = `{"name":"comp-depends-multiple","services":{"database":{"type":"webservice","image":"nginx:latest","ports":[{"port":3306,"expose":false}]},"cache":{"type":"webservice","image":"nginx:latest","ports":[{"port":6379,"expose":false}]},"backend":{"type":"webservice","dependsOn":["database","cache"],"image":"nginx:latest","ports":[{"port":8080,"expose":false}]}}}`
|
||||
)
|
||||
|
||||
var _ = ginkgo.Describe("Test Vela Application", ginkgo.Ordered, func() {
|
||||
e2e.DeleteEnvFunc("env delete", envName)
|
||||
e2e.JsonAppFileContext("json appfile apply", jsonAppFile)
|
||||
e2e.EnvSetContext("env set default", "default")
|
||||
e2e.DeleteEnvFunc("env delete", envName)
|
||||
e2e.EnvInitContext("env init env-application", envName)
|
||||
e2e.EnvSetContext("env set", envName)
|
||||
e2e.JsonAppFileContext("deploy app-basic", appbasicJsonAppFile)
|
||||
@@ -128,6 +131,15 @@ var ApplicationExecContext = func(context string, appName string) bool {
|
||||
|
||||
var ApplicationPortForwardContext = func(context string, appName string) bool {
|
||||
return ginkgo.It(context+": should get output of port-forward successfully", func() {
|
||||
ginkgo.By(fmt.Sprintf("waiting for the application [%s] to reach the desired status", appName))
|
||||
gomega.Eventually(func() string {
|
||||
cli := fmt.Sprintf("vela status %s", appName)
|
||||
output, err := e2e.Exec(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
return output
|
||||
}, 90*time.Second, 1*time.Second).Should(gomega.ContainSubstring("running"))
|
||||
|
||||
ginkgo.By("executing port-forward")
|
||||
cli := fmt.Sprintf("vela port-forward %s 8080:80 ", appName)
|
||||
output, err := e2e.ExecAndTerminate(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
@@ -304,3 +316,61 @@ var VelaQLPodListContext = func(context string, velaQL string) bool {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var _ = ginkgo.Describe("Test Component Level DependsOn CLI", ginkgo.Ordered, func() {
|
||||
|
||||
e2e.JsonAppFileContext("component dependsOn failure blocking", componentDependsOnFailApp)
|
||||
ComponentDependsOnFailureContext("component dependsOn failure blocking verification", "comp-depends-fail")
|
||||
e2e.WorkloadDeleteContext("delete failure app", "comp-depends-fail")
|
||||
|
||||
e2e.JsonAppFileContext("component dependsOn multiple dependencies", componentDependsOnMultipleApp)
|
||||
ComponentDependsOnMultipleContext("component dependsOn multiple dependencies verification", "comp-depends-multiple")
|
||||
e2e.WorkloadDeleteContext("delete multiple deps app", "comp-depends-multiple")
|
||||
})
|
||||
|
||||
var ComponentDependsOnFailureContext = func(context string, appName string) bool {
|
||||
return ginkgo.It(context+": should block dependent components when dependency fails", func() {
|
||||
ginkgo.By("verify application doesn't reach running state due to component failure")
|
||||
ginkgo.By("wait sufficient time for dependency check")
|
||||
time.Sleep(45 * time.Second)
|
||||
|
||||
cli := fmt.Sprintf("vela status %s", appName)
|
||||
output, err := e2e.Exec(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
ginkgo.By("check that dependent service is blocked")
|
||||
gomega.Expect(strings.ToLower(output)).Should(gomega.ContainSubstring("failed"))
|
||||
// The app should show some indication that components are waiting on dependencies
|
||||
gomega.Expect(strings.ToLower(output)).Should(gomega.SatisfyAny(
|
||||
gomega.ContainSubstring("pending"),
|
||||
gomega.ContainSubstring("progressing"),
|
||||
gomega.ContainSubstring("waiting"),
|
||||
gomega.ContainSubstring("suspend"),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
var ComponentDependsOnMultipleContext = func(context string, appName string) bool {
|
||||
return ginkgo.It(context+": should handle multiple dependencies correctly", func() {
|
||||
ginkgo.By("verify application eventually reaches running state")
|
||||
gomega.Eventually(func() string {
|
||||
cli := fmt.Sprintf("vela status %s", appName)
|
||||
output, err := e2e.Exec(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
return output
|
||||
}, 300*time.Second, 5*time.Second).Should(gomega.ContainSubstring("running"))
|
||||
|
||||
ginkgo.By("wait sufficient time for dependency check")
|
||||
time.Sleep(time.Minute)
|
||||
|
||||
ginkgo.By("verify all components are healthy")
|
||||
cli := fmt.Sprintf("vela status %s --tree", appName)
|
||||
output, err := e2e.Exec(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
gomega.Expect(output).Should(gomega.And(
|
||||
gomega.ContainSubstring("database"),
|
||||
gomega.ContainSubstring("cache"),
|
||||
gomega.ContainSubstring("backend"),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ spec:
|
||||
}
|
||||
|
||||
outputs: ingress: {
|
||||
apiVersion: "networking.k8s.io/v1beta1"
|
||||
apiVersion: "networking.k8s.io/v1"
|
||||
kind: "Ingress"
|
||||
metadata:
|
||||
name: context.name
|
||||
@@ -436,9 +436,14 @@ spec:
|
||||
paths: [
|
||||
for k, v in parameter.http {
|
||||
path: k
|
||||
pathType: "Prefix"
|
||||
backend: {
|
||||
serviceName: context.name
|
||||
servicePort: v
|
||||
service: {
|
||||
name: context.name
|
||||
port: {
|
||||
number: v
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
@@ -617,7 +622,7 @@ spec:
|
||||
|
||||
---
|
||||
## From the trait test-ingress
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations: {}
|
||||
@@ -637,9 +642,12 @@ spec:
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: express-server
|
||||
servicePort: 80
|
||||
service:
|
||||
name: express-server
|
||||
port:
|
||||
number: 80
|
||||
path: /
|
||||
pathType: Prefix
|
||||
|
||||
---
|
||||
`
|
||||
@@ -721,7 +729,7 @@ var livediffResult = `Application (test-vela-app) has been modified(*)
|
||||
- app.oam.dev/component: express-server
|
||||
|
||||
* Component (express-server) / Trait (test-ingress/ingress) has been removed(-)
|
||||
- apiVersion: networking.k8s.io/v1beta1
|
||||
- apiVersion: networking.k8s.io/v1
|
||||
- kind: Ingress
|
||||
- metadata:
|
||||
- labels:
|
||||
@@ -739,9 +747,12 @@ var livediffResult = `Application (test-vela-app) has been modified(*)
|
||||
- http:
|
||||
- paths:
|
||||
- - backend:
|
||||
- serviceName: express-server
|
||||
- servicePort: 80
|
||||
- service:
|
||||
- name: express-server
|
||||
- port:
|
||||
- number: 80
|
||||
- path: /
|
||||
- pathType: Prefix
|
||||
|
||||
* Component (new-express-server) has been added(+)
|
||||
+ apiVersion: apps/v1
|
||||
@@ -796,7 +807,7 @@ var livediffResult = `Application (test-vela-app) has been modified(*)
|
||||
+ app.oam.dev/component: new-express-server
|
||||
|
||||
* Component (new-express-server) / Trait (test-ingress/ingress) has been added(+)
|
||||
+ apiVersion: networking.k8s.io/v1beta1
|
||||
+ apiVersion: networking.k8s.io/v1
|
||||
+ kind: Ingress
|
||||
+ metadata:
|
||||
+ labels:
|
||||
@@ -814,9 +825,12 @@ var livediffResult = `Application (test-vela-app) has been modified(*)
|
||||
+ http:
|
||||
+ paths:
|
||||
+ - backend:
|
||||
+ serviceName: new-express-server
|
||||
+ servicePort: 8080
|
||||
+ service:
|
||||
+ name: new-express-server
|
||||
+ port:
|
||||
+ number: 8080
|
||||
+ path: /
|
||||
+ pathType: Prefix
|
||||
`
|
||||
|
||||
var testShowComponentDef = `
|
||||
|
||||
@@ -87,7 +87,9 @@ var _ = Describe("test registry and trait/comp command", func() {
|
||||
Expect(output).To(ContainSubstring("pvc"))
|
||||
Expect(output).To(ContainSubstring("[deployments.apps]"))
|
||||
})
|
||||
It("list trait from default registry", func() {
|
||||
|
||||
// TODO: enable this test after the default registry has been updated
|
||||
XIt("list trait from default registry", func() {
|
||||
cli := "vela trait --discover"
|
||||
output, err := e2e.Exec(cli)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@@ -100,10 +102,10 @@ var _ = Describe("test registry and trait/comp command", func() {
|
||||
})
|
||||
|
||||
It("test list trait in raw url", func() {
|
||||
cli := "vela trait --discover --url=oss://registry.kubevela.net"
|
||||
cli := "vela trait --discover --url=https://github.com/kubevela/kubevela/tree/master/vela-templates/registry/auto-gen/"
|
||||
output, err := e2e.Exec(cli)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).To(SatisfyAll(ContainSubstring("Showing trait definition from url"), ContainSubstring("oss://registry.kubevela.net")))
|
||||
Expect(output).To(SatisfyAll(ContainSubstring("Showing trait definition from url"), ContainSubstring("https://github.com/kubevela/kubevela/tree/master/vela-templates/registry/auto-gen/")))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user