Compare commits

...

67 Commits

Author SHA1 Message Date
Brian Kane
9d160cdf84 refactor: rename autoRevision annotation to policy.oam.dev namespace
Changed annotation from app.oam.dev/autoRevision to
policy.oam.dev/autoRevision to better indicate its purpose and
prevent misuse in other areas of the codebase.

This annotation specifically controls whether application-scoped
policy transforms should create new ApplicationRevisions.

Updated:
- labels.go: Changed constant value
- devlogs: Updated all references in documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 18:19:20 +00:00
Brian Kane
03a91c9fb1 docs: update devlog with commit SHA for dispatcher fix
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 18:16:11 +00:00
Brian Kane
06e1d20a74 fix: component dispatch with autoRevision=true for policy transforms
When policies retrigger with autoRevision=true, components were not
redeploying even though new ApplicationRevisions were created. The
dispatcher was comparing component properties against the NEW revision
(which already had policy transforms) instead of the PREVIOUS revision.

Changes:
- generator.go: Pass latestAppRev to generateDispatcher()
- dispatcher.go: Add previousAppRev parameter and conditional comparison
  logic based on autoRevision annotation
- When autoRevision=true: Compare against previous revision to detect
  policy-driven changes
- When autoRevision=false (default): Use existing logic for backward
  compatibility

Added documentation noting that the default comparison logic seems
unclear and may need future simplification.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 18:15:51 +00:00
Brian Kane
4435c3bb14 feat: add helper functions for new policy flow
Added helper functions to support simplified policy architecture:
- extractRenderedSpec() - extract spec from policy results
- extractRenderedMetadata() - extract labels/annotations/context
- applyMetadataToApp() - apply metadata to Application CR
- applySpecToApp() - apply spec to Application
- renderAllPolicies() - render both global and explicit policies together

These will be used in the refactored ApplyApplicationScopeTransforms.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 12:42:50 +00:00
Brian Kane
3d8440bc45 feat: add autoRevision annotation for policy-driven spec changes
Added app.oam.dev/autoRevision annotation to control whether policies
can modify Application.Spec and trigger new ApplicationRevisions.

Changes:
- Added AnnotationAutoRevision constant to pkg/oam/labels.go
- Added shouldAutoCreateRevision() helper function
- Orthogonal to autoUpdate (which controls definition version updates)
- Consistent naming: autoRevision (not auto-revision) matches autoUpdate

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 12:36:47 +00:00
Brian Kane
a83432e98c refactor: rename GlobalPolicyCache to ApplicationPolicyCache
Simplified cache structure and removed global policy hash tracking.
2026-02-17 12:33:02 +00:00
Brian Kane
68805310e3 WIP: Cascade invalidation approach (will be replaced)
This commit captures the cascade invalidation exploration before
we pivot to a simpler design. Key changes:

1. computeCascadeID() only hashes spec fields (not metadata)
2. computeApplicationHash() only hashes spec (not labels/annotations)
3. Application hash computed BEFORE policies run
4. Attempted to integrate explicit policies into new flow

Design Decision: This approach is too complex. We're pivoting to:
- Simple 1-minute in-memory cache
- Always render policies
- Store rendered vs applied spec in ConfigMap
- Auto-update annotation for spec changes

This commit preserved for historical reference.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 12:01:07 +00:00
Brian Kane
83675a1aae feat: add per-output-type refresh control infrastructure (Part 4)
Implements the data structures, functions, and API for per-output-type
policy caching with cascade invalidation. Note: Full integration into
the policy execution flow will be done in Part 5.

## What's Implemented

### 1. PolicyConfig with refresh fields (policy_transforms.go:782-809)
- RefreshMode type: RefreshAlways, RefreshNever, RefreshPeriodic
- OutputRefreshConfig struct: Mode, Interval, ForceRefresh
- PolicyConfig with nested Refresh for Spec, Labels, Annotations, Ctx
- Each output type has independent refresh control

### 2. extractRefreshConfig function (policy_transforms.go:845-882)
- Extracts config.refresh from CUE templates
- Applies defaults (all modes default to "never")
- Validates periodic mode requires interval > 0

### 3. Per-output-type cache storage (policy_transforms.go:932-954)
- CachedOutputData: per-type cache with metadata
- PolicyCacheRecord: new ConfigMap format with cascade tracking
- Helper functions: createPolicyCacheRecord, reconstructPolicyOutputFromCache, shouldRefreshOutput

### 4. Cascade ID computation (policy_transforms.go:1506-1525)
- computeCascadeID(): hashes upstream policy outputs
- Enables cascade invalidation when upstream policies refresh

### 5. New cache load function (policy_transforms.go:1593-1683)
- loadCachedPolicyRecord(): loads with cascade & refresh checks
- Checks Application hash, cascade ID, per-output-type refresh
- Old loadCachedPolicyFromConfigMap() kept for backwards compatibility

### 6. Removed CacheTTLSeconds from CRD
- Removed from PolicyDefinitionSpec (policy_definition.go)
- TTL now controlled via config.refresh in templates
- Removed deprecated test

### 7. CUE schema (vela-templates/definitions/internal/policy/app-policy-schema.cue)
- Defines #ApplicationPolicyTemplate with full API
- Provides type safety, validation, defaults
- Documents complete config.refresh API

## API Example

```cue
config: {
  enabled: true
  refresh: {
    labels: { mode: "always" }
    ctx: { mode: "periodic", interval: 300 }
  }
}
```

## Status

 Infrastructure complete
 162 tests passing
 Full integration into execution flow: Part 5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 10:16:03 +00:00
Brian Kane
0f5add7902 feat: implement config.enabled for Policy API redesign (Part 3)
Part 3 of Policy API Redesign - updated both tests and implementation:

**Test changes (policy_transforms_test.go):**
- Updated all 25 PolicyDefinition templates to use new API syntax
- Old: `enabled: true` at root level
- New: `config: { enabled: true }`

**Implementation changes (policy_transforms.go):**
- Added PolicyConfig struct with enabled and cacheDuration fields
- Updated extractEnabled() to support both new and old API:
  - Tries config.enabled first (new API)
  - Falls back to root enabled (old API, backwards compatible)
  - Defaults to true if neither exists

**Testing:**
- Tests now pass with new API syntax
- Backwards compatibility maintained for old API
- TDD approach: updated tests first, then implementation

**Next:**
- Part 4: Per-output-type refresh control (config.refresh)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-17 09:41:52 +00:00
Brian Kane
5330c0f0fe test: fix all policy transform tests for new output API
Updated all tests to use the new 'output' API structure instead of the old
'transforms' API. Key changes:

1. Fixed RenderedPolicyResult usage in tests
   - Changed Output field to Transforms field (stores *PolicyOutput)
   - Added missing Transforms field for tests calling applyRenderedPolicyResult

2. Fixed CUE templates in policy tests
   - Changed 'additionalContext' to 'output.ctx' (3 templates)
   - Fixed kube.#Get usage to avoid double-defining output (2 templates)
   - Changed test expectations from 'transforms' to 'output' key in ConfigMap

3. Removed deprecated transforms API validation
   - Removed test checking for old transforms API rejection
   - Removed extractTransforms() function and its callers
   - Removed PolicyTransforms validation logic

4. Fixed nil pointer bugs in revision comparison
   - Added nil checks in DeepEqualRevision for definition maps
   - Added nil check in gatherRevisionSpec for nil appfile parameter

All policy transform tests now pass successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-16 20:16:43 +00:00
Brian Kane
deabee9714 fix: handle NewAppHandler error return in regression tests
NewAppHandler returns (*AppHandler, error), but regression tests
were only capturing the handler. Fixed to capture and check error.
2026-02-16 17:10:49 +00:00
Brian Kane
5a3be983dc chore: regenerate deepcopy and CRD manifests
Auto-generated files updated after API changes (output API structs).

Changes are minimal - mostly import reordering in deepcopy files.
2026-02-16 17:05:00 +00:00
Brian Kane
738ddfd98e test: migrate all tests to output API and add regression tests
Completes the test migration for the transforms → output API change.

## Test Migrations

### policy_transforms_test.go (29 transforms → output)
- 21 labels transforms → output.labels
- 7 spec transforms → output.components
- 1 annotations transform → output.annotations

All type/value wrappers removed for cleaner syntax.

### policy_validation_test.go
Already migrated in previous commit.

## Regression Tests Added

### Test 1: Policy spec modifications preserved across status patch
Verifies fix for bug where UpdateAppLatestRevisionStatus() lost
policy-modified spec during Status().Patch() operation.

Tests that after applying a policy that modifies components, the
modifications survive the status update operation.

### Test 2: JSON normalization prevents infinite ApplicationRevisions
Verifies fix for bug where RawExtension JSON with different byte
representations caused infinite revision creation.

Tests that semantically identical JSON with different field order
produces identical normalized bytes and matching hashes.

## Additional Changes

- Minor whitespace cleanup in application_controller.go
- Import reordering in suite_test.go
- Formatting alignment in references/cli/policy.go

All tests now use the new output API exclusively.
2026-02-16 16:58:23 +00:00
Brian Kane
bf8d128128 feat: migrate from transforms API to output API and fix critical bugs
This commit completes the migration from the old transforms API to the
simpler output API, and fixes two critical bugs discovered during testing.

## Part 1: API Migration (transforms → output)

**Old API**:
```cue
transforms: {
  spec: {type: "replace", value: {components: [...]}}
  labels: {type: "merge", value: {"key": "val"}}
}
```

**New API**:
```cue
output: {
  components: [...]          // replaces spec.components (always replace)
  workflow: {...}            // replaces spec.workflow (always replace)
  policies: [...]            // replaces spec.policies (always replace)
  labels: {"key": "val"}     // always merge
  annotations: {...}         // always merge
  ctx: {...}                 // runtime-only context
}
```

**Implementation** (policy_transforms.go):
- Added PolicyOutput struct for new API
- Added extractOutput() to parse output field
- Added applyPolicyTransform() to apply output to Application
- Updated renderPolicy() to support both APIs temporarily
- Reject old transforms API with clear error message

## Part 2: Bug Fixes

### Bug 1: Policy modifications lost during status update

**Problem**: `Status().Patch()` with `client.Merge` refreshes entire object
from API server, losing in-memory spec modifications made by policies.

**Symptom**: Workflows failed with "component not found" errors.

**Fix** (revision.go:544-555): Save/restore app.Spec around patchStatus().

### Bug 2: Infinite ApplicationRevision creation

**Problem**: RawExtension JSON had inconsistent byte representations,
causing DeepEqualRevision() failures and infinite revision creation.

**Symptom**: 100+ identical ApplicationRevisions created.

**Fix** (revision.go:136-146): Normalize component properties JSON in
gatherRevisionSpec() for consistent comparison.

## Testing

- Migrated policy_validation_test.go to output API (14 tests)
- Verified in test cluster: 1 revision per change, workflows work correctly
- Note: policy_transforms_test.go migration in progress

Tested with OCM policy creating ManifestWork - single revision created,
workflow finds correct components.
2026-02-16 16:45:13 +00:00
Brian Kane
f3b67e79ed feat: implement foundation - context cleanup and security (Part 1)
This commit implements Part 1 of the policy refactor plan, establishing
a clean and secure context structure for Application-scoped policies.

Key Changes:

1. Security: Metadata Filtering
   - Added filterUserMetadata() to filter internal annotations/labels
   - Prevents policies from accessing system annotations (app.oam.dev/*,
     kubernetes.io/*, kubectl.kubernetes.io/*, etc.)
   - O(1) map-based filtering for performance

2. Explicit Context Fields
   - Added context.appName (instead of context.application.metadata.name)
   - Added context.namespace, context.appRevision, context.appRevisionNum
   - Added filtered context.appLabels and context.appAnnotations
   - All exposed via process.Context infrastructure

3. Controlled Application Spec Access
   - Added context.appComponents (components array only)
   - Added context.appWorkflow (workflow object only)
   - Added context.appPolicies (policies array only)
   - Prevents unintended access to full Application CR

4. Removed context.application
   - Completely removed to enforce explicit field access
   - Deleted cleanApplicationForPolicyContext() helper function
   - Forces security best practices

5. Removed context.prior
   - Simplified incremental policy feature (can be added back later)
   - Deleted associated test coverage

Test Changes:
   - Deleted 3 test blocks relying on removed features
   - Fixed TTL test expectation (CRD default is -1, not 0)
   - Fixed WorkflowStep struct initialization
   - All tests passing

Benefits:
   -  Clean API with explicit fields
   -  Security: No bypass to unfiltered metadata
   -  Forces best practices
   -  Simpler for policy authors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-13 21:53:48 +00:00
Brian Kane
f36017dfa5 feat: add explicit context fields and filtered metadata to policies
Populate policy context with explicit fields and filtered metadata
using the existing process.Context infrastructure, providing a
secure and user-friendly API for policy templates.

Changes:
- Populate ContextData with filtered labels/annotations (via filterUserMetadata)
- Add explicit fields: appName, namespace, appRevision, appRevisionNum
- Use process.Context.BaseContextFile() to inject context into CUE
- Reuses existing context infrastructure (same as components/workflows)

Context fields now available in policies:
- context.appName - explicit application name
- context.namespace - explicit namespace
- context.appRevision - explicit revision name
- context.appRevisionNum - explicit revision number
- context.appLabels - filtered user labels (internal prefixes removed)
- context.appAnnotations - filtered user annotations (internal prefixes removed)

Security: Filtered metadata isolates policy context from components/workflows:
- Policies: get filtered labels/annotations (secure)
- Components/workflows: get unfiltered labels/annotations (unchanged)
- Policy additionalContext flows via Go context to components as context.custom

Tests:
- Verify explicit fields accessible in policies
- Verify user metadata accessible (filtered)
- Verify internal metadata filtered out

Part of Policy Refactor Plan v3 - Part 1.2 & 1.3: Foundation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-13 20:56:27 +00:00
Brian Kane
566b72b882 feat: add filterUserMetadata for secure policy context
Add filterUserMetadata() function to filter out internal/system
labels and annotations from policy context, preventing policies
from accessing sensitive KubeVela/Kubernetes internal metadata.

Implementation:
- Uses map-based prefix lookup for O(1) performance
- Filters prefixes: app.oam.dev/, oam.dev/, kubectl.kubernetes.io/,
  kubernetes.io/, k8s.io/, helm.sh/, app.kubernetes.io/
- Optimized for hot path (runs on every reconciliation with policies)
- Returns nil for empty results to avoid unnecessary allocations

Tests:
- Filter internal vs user metadata
- Handle empty inputs
- Handle keys without prefixes
- Verify all internal prefixes are excluded

Part of Policy Refactor Plan v3 - Part 1.1: Foundation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-13 20:30:18 +00:00
Brian Kane
d8562f1c2c Checkpoint - bug fixes for application context
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-02-13 13:42:41 +00:00
Brian Kane
32d166c219 Checkpoint - context working 2026-02-10 17:43:06 +00:00
Brian Kane
bfa143297b Checkpoint - working with caching and globals 2026-02-10 14:08:48 +00:00
Brian Kane
32ac0d69c7 Feature: Configurable Application Policies 2026-02-09 10:19:05 +00:00
Brian Kane
995a09d3c7 Fix: 7032 Adds component type to structured log output (#7033)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 11m56s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-01-27 09:30:58 +00:00
Brian Kane
7c06ee2060 Fix: Prevent app validation errors when traits are used alongside workflow data passing (#7031)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 51m50s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-01-23 18:03:09 +00:00
Brian Kane
37fb2a6f49 Feat: 7024 Enable custom errors in components similar to traits (#7028)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 12m42s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-01-21 10:37:07 +00:00
Brian Kane
555e4416f4 Fix: 7018 Ensure Component removals are correctly persisted and reflected in status (#7027)
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-01-21 09:26:17 +00:00
Amit Singh
5ead6db8d7 Chore: bumps up pkg and workflow dependency versions (#7026)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 1m29s
* chore: bumps up workflow and pkg versions and updates import statements

Signed-off-by: Amit Singh <singhamitch@outlook.com>

* chore: minor linter fixes

Signed-off-by: Amit Singh <singhamitch@outlook.com>

---------

Signed-off-by: Amit Singh <singhamitch@outlook.com>
2026-01-20 15:32:03 +00:00
Brian Kane
2a75dbdc35 Add a minimal, interface based provider registry to break complex import cycle (#7021)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 1m45s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-01-19 11:22:28 +00:00
Brian Kane
568b1c578b Feat: 7019 Support re-running workflows and ensure passed data is updated during dispatch (#7025)
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-01-19 11:18:10 +00:00
GoGstickGo
8c85dcdbbc Fix: Support cuex package imports in vela show/def show commands (#7017)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 2m0s
- Added GetCUExParameterValue()
 function that uses cuex.DefaultCompiler instead
    of standard CUE compiler

 - Added GetParametersWithCuex() function with cuex support
- Updated GetBaseResourceKinds() to use cuex compiler
- Updated all callers to use cuex-aware functions

 Fixes #7012

Signed-off-by: GoGstickGo <janilution@gmail.com>
2026-01-16 09:56:10 +00:00
Amit Singh
0b85d55e68 Feat: post dispatch output context (#7008)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 1m46s
* exploring context data passing

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* adds output status fetch logic

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix: standardize  import in dispatcher.

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* feat: Allow  traits to access workload output status in CUE context

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* feat: Implement PostDispatch traits that apply after component health is confirmed.

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* feat: Refactor  trait handling and status propagation in application dispatch.

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix: run make reviewable

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* feat: Implement and document PostDispatch traits, applying them after component health is confirmed and guarded by a feature flag, along with new example applications.

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* feat: Add comments

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Fix: Restore the status field in ctx.

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Fix: Error for evaluating the status of the trait

Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* refactor: removes minor unnecessary changes

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* refactor: minor linter changes

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* test: Add comprehensive tests for PostDispatch traits and their status handling

Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Fix: Increase multi-cluster test time

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Chore: Add focus and print the application status

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Chore: print deployment status in the multicluster test

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Chore: add labels for the deployment

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* debugging test failure

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* debugging test failure by updating multi cluster ctx

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* undoes multi cluster ctx change

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Feat: enable MultiStageComponentApply feature by default

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Feat: implement post-dispatch traits application in workflow states

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Chore: remove unnecessary blank lines in application_controller.go

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Feat: enhance output readiness handling in health checks

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Feat: add logic to determine need for post-dispatch outputs in workload processing

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* Feat: enhance output extraction and dependency checking for post-dispatch traits

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix code to exclude validation of post dispatch trait in webhook

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix code to exclude validation of post dispatch trait in webhook

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* commit for running the test again

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* commit for running the test again

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* commit for running the test again

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* triggering checks

Signed-off-by: Amit Singh <singhamitch@outlook.com>

* chore: adds explanation comments

Signed-off-by: Amit Singh <singhamitch@outlook.com>

* chore: adds errors to context

Signed-off-by: Amit Singh <singhamitch@outlook.com>

* chore: minor improvements

Signed-off-by: Amit Singh <singhamitch@outlook.com>

* fix: update output handling for pending PostDispatch traits

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix: improve output handling for PostDispatch traits in deploy process

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix: streamline output handling in PostDispatch process

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* chore: commit to re run the pipeline

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* chore: commit to re run the pipeline

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* chore: commit to re run the pipeline

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix: enhance output status handling in PostDispatch context for multi-stage support

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* chore: commit to re run the pipeline

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix: increase timeout for PostDispatch trait verification in tests

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* fix: enhance output status handling in PostDispatch context for multi-stage support

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

* chore: commit to re run the pipeline

Signed-off-by: Vishal Kumar <vishal210893@gmail.com>

---------

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com>
Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Chitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Vishal Kumar <vishal210893@gmail.com>
2026-01-14 10:28:13 +00:00
Brian Kane
432ffd3ddd Feat: Improve Cue Error Reporting (#6984)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 11m49s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2026-01-07 14:37:06 +00:00
Ricardo Noriega
3cc668289e Fix typos in documentation (#7015)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 2m58s
Signed-off-by: Ricardo Noriega De Soto <rnoriega@redhat.com>
2026-01-06 11:29:14 +00:00
Anoop Gopalakrishnan
e2935da549 Docs(KEP): Go SDK for X-Definition Authoring (defkit) (#7009)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 16m11s
* Docs(KEP): Go SDK for X-Definition Authoring (defkit)

  Introduces KEP proposal for defkit, a Go SDK that enables platform
  engineers to author X-Definitions using native Go code instead of CUE.

  Key proposed features:
  - Fluent builder API for Component, Trait, Policy, and WorkflowStep definitions
  - Transparent Go-to-CUE compilation
  - IDE support with autocomplete and type checking
  - Schema-agnostic resource construction
  - Collection operations (map, filter, dedupe)
  - Composable health and status expressions
  - Addon integration with godef/ folder support
  - Module dependencies for definition sharing via go get

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Fix(KEP): Examples and minor api changes given in the document

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Fix(KEP): align defkit examples

- Fix golang version in CI
- Fix variable declaration in example for testing
- Add Is() comparison method to status check

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Docs(KEP): add security considerations section

- Add goal #7 for secure code execution model
- Add Security Considerations section covering:
  - Code execution model (compile-time only, not runtime)
  - Security benefits over CUE (static analysis, dependency scanning)
  - Threat model with mitigations

Addresses PR feedback about code execution safety.

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Docs(KEP): add module versioning and definition placement sections

- Add Module Versioning section explaining git-based version derivation
- Add Definition Placement section covering:
  - Motivation for placement constraints in multi-cluster environments
  - Fluent API for placement (RunOn, NotRunOn, label conditions)
  - Logical combinators (And, Or, Not)
  - Module-level placement defaults
  - Placement evaluation logic
  - CLI experience for managing cluster labels
- Add Module Hooks section for lifecycle callbacks
- Minor fixes and clarifications throughout

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Docs(KEP): add module hooks and update addon integration sections

- Add Module Hooks section covering:
  - Use cases (CRD installation, setup scripts, post-install samples)
  - Hook configuration in module.yaml (pre-apply, post-apply)
  - Hook types (path for manifests, script for shell scripts)
  - waitFor field with condition names and CUE expressions
  - CLI usage (--skip-hooks, --dry-run)

- Update Addon Integration section with implementation details:
  - godef/ folder structure with module.yaml
  - CLI flags (--godef, --components, --traits, --policies, --workflowsteps)
  - Conflict detection and --override-definitions flag
  - Development workflow

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Docs(KEP): address PR review comments and clarify placement labels

- Fix misleading "Sandboxed Compilation" claim (cubic-ai feedback) -
  renamed to "Isolated Compilation" and clarified that security relies
  on trust model, not technical sandboxing
- Fix inconsistent apiVersion in module hooks example (defkit.oam.dev/v1
  → core.oam.dev/v1beta1)
- Clarify that placement uses vela-cluster-identity ConfigMap directly,
  not the vela cluster labels command (which is planned for future)
- Add --stats flag to apply-module CLI documentation

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Docs(KEP): fix API documentation

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Docs(KEP): add forward-reference for RawCUE() escape hatch

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

---------

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
2025-12-30 16:11:46 -08:00
Bryan Leong
358e46e628 Style: clean up dry-run (#7007)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 13m45s
- Remove trailing whitespace on dryrun outputs
- Fixed the relevant plugin-test outputs
- Refactor to avoid partial lines that codecov flags out

Signed-off-by: Bryan Leong <leong.bryan@gmail.com>
2025-12-16 11:18:14 +00:00
Brian Kane
bf2340bb35 Feat(KEP): Declarative Addon Support (#6996)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 17m36s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2025-11-28 16:43:06 +00:00
rahulkhinchi-wq
a459bba20e fix: dangerous-exec-command-87 (#6999)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 17m1s
Co-authored-by: root <root@ai-guardian-remediation-54f45fdc58-g5zpm>
2025-11-26 06:52:34 -08:00
Ayush Kumar
552764d48f Fix: Enhance shared resource handling to avoid last-applied-configuration pollution (#6998)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 19m3s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2025-11-26 11:08:22 +00:00
Brian Kane
9b558e38cd Feat(KEP): #6973 - Native Helm Rendering (#6974)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 16m47s
* KEP #6973 - Native Helm Rendering

Signed-off-by: Brian Kane <briankane1@gmail.com>

* KEP: #6973 - Native Helm Rendering - Minor format and spelling corrections

Signed-off-by: Brian Kane <briankane1@gmail.com>

---------

Signed-off-by: Brian Kane <briankane1@gmail.com>
2025-11-25 11:36:27 +00:00
Brian Kane
9889a0cb31 Feat(KEP): Nested Definition Rendering (Compositions) (#6993)
* Feat(KEP): Nested Definition Rendering (Compositions)

Signed-off-by: Brian Kane <briankane1@gmail.com>

* Feat(KEP) #6990 - Nested Definition Rendering (Compositions) - Minor Updates

Signed-off-by: Brian Kane <briankane1@gmail.com>

---------

Signed-off-by: Brian Kane <briankane1@gmail.com>
2025-11-25 11:35:08 +00:00
Chaitanyareddy0702
90ed704cff Refactor: update workflow-related types to use v1alpha1 API (#6975)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 17m1s
* refactor: update workflow-related types to use v1alpha1 API

- Changed the workflow mode in ApplicationBuilder from v1beta1 to v1alpha1.
- Updated WorkflowStep and WorkflowSubStep constructors to use the new v1alpha1 types.
- Modified the TypedApplication interface to reflect the new workflow mode.
- Adjusted WorkflowStepBase and WorkflowSubStepBase to utilize v1alpha1 inputs and outputs.
- Commented out unused WorkflowSubStep registration for future consideration.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: update Inputs and Outputs types to use v1alpha1 API in GoDefModifier

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: remove commented-out code for AddInput and AddOutput in genBaseSetterFunc

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: update ApplicationBuilder to use apis package for components, steps, and policies

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: remove unused WorkflowSubStep related code and update WorkflowStep reference to use v1alpha1 API

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* feat: add support for WorkflowSubStep registration and handling in GoDefModifier

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: update import path for WorkflowStepBase in GoDefModifier

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: update import path for WorkflowStep in DefinitionKindToStatement

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: update WorkflowSubStep references to use WorkflowStepBase from v1alpha1 API

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: simplify subSteps generation in GoDefModifier by directly appending WorkflowStepBase

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: nest properties under WorkflowStepBase in GoDefModifier for WorkflowStep definitions

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: remove toolchain version from go.mod

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* Run: make reviewable

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* fix: enhance application auto-update test to wait for application revisions

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

---------

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: semmet95 <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: Amit Singh <singhamitch@outlook.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
2025-11-18 08:47:44 +00:00
Ayush Kumar
0a599ad177 Refactor: Pre-Validation Hooks to be More Extensible and Testable (#6978)
* refactor: pre-start hook implementation

- Introduced a new `hook.go` file defining the `PreStartHook` interface for pre-start validation hooks.
- Removed the old `pre_start_hook.go` file which contained the `SystemCRDValidationHook` implementation.
- Updated the server initialization code to use the new hook structure, specifically integrating the `crdvalidation` package for pre-start validation.
- Enhanced logging for pre-start hook execution to improve clarity on hook names and execution results.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: move color writer implementation to logging package and update usage in server setup

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: rename Hook to CRDValidation for clarity and consistency

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: reorder import statements for consistency

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: replace hardcoded namespace with variable in cleanup function

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: rename CRDValidation type to Hook for consistency

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: enhance CRD validation hook with custom client support and improved error handling

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: extend timeout for CRD validation hook and improve error handling for slow API servers

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: remove redundant comments from PreStartHook definition

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
2025-11-17 18:14:40 -08:00
Chaitanyareddy0702
d064d3dbd2 Feat: Add configurable timeout for admission webhooks (#6977)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 23s
* Feat: Add configurable timeout for admission webhooks

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* Feat: Update admission webhook timeout configuration to use admissionWebhookTimeout variable

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* Feat: Add admission webhook timeout parameter to README

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

* removed period in readme to run pipelines

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>

---------

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Chaitanyareddy0702 <chaitanyareddy0702@gmail.com>
Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
2025-11-13 11:43:35 +08:00
Ayush Kumar
89ff116f8e Fix: E2E Application Test (live-diff application version) (#6976)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 27s
* refactor: Simplify application auto-update test by removing unnecessary reconciliation waits

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>

* feat: Add e2e application tests with k3d and webhook validation

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* fix: Remove unnecessary blank line in application auto-update test

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: Add k3d cleanup step after running application tests

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
2025-11-11 14:24:30 +00:00
Ayush Kumar
0485704cd7 Fix: Prevent namespace admins from accessing vela-system definitions without explicit permissions (#6972)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 34s
* fix: add admission rules for applications and improve permission checks

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* test: enhance application auto-update tests with reconciliation checks

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* fix: enhance application auto-update test to verify application revision creation

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
2025-11-10 08:14:41 +00:00
Amit Singh
2a31930c4b Chore: imports workflow crd from pkg repo (#6954)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 38s
* chore: adds logic to pull workflow crd from pkg repo

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: introduce GetIteratorLabel utility function and refactor label retrieval in CUE processing

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>
Co-authored-by: Vishal Kumar <vishal210893@gmail.com>

* feat: refactor FromCUE method to use GetIteratorLabel utility for improved label retrieval

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: remove unused imports and optimize list concatenation in template files

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>
Co-authored-by: Vishal Kumar <vishal210893@gmail.com>

* refactor: standardize import formatting across multiple YAML and Go files

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>
Co-authored-by: Vishal Kumar <vishal210893@gmail.com>
Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>

* refactor: import statements in multiple YAML templates for consistency

- Removed unnecessary parentheses around import statements in various CUE templates.
- Ensured a consistent import style across all templates in the vela-core chart.

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>

* feat: add disk space cleanup steps before and after cross-build in Go workflow

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>

* refactor: update check-diff target to depend on build for improved consistency

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>

* refactor: update reviewable target to include build for improved consistency in check-diff

Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Ayush <ayushshyamkumar888@gmail.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Vishal Kumar <vishal210893@gmail.com>
2025-11-06 18:56:04 -08:00
Brian Kane
8e3749f970 Fix: Fix issue with imports/packages in status validations (#6963)
Signed-off-by: Brian Kane <briankane1@gmail.com>
2025-11-06 15:23:08 -08:00
Anirudh Edpuganti
089f657b0c fix: update YAML import path to use go.yaml.in/yaml/v3 and adjust dependencies in go.mod and go.sum (#6944)
Signed-off-by: ANIRUDH-333 <aniedpuganti@gmail.com>
2025-11-06 10:37:19 +00:00
Ayush Kumar
ea409c7437 Refactor: controller setup and improve server tests (#6958)
* Feat: Add integration test setup and cleanup scripts, enhance server testing capabilities

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Refactor: Rename variables for clarity and consistency in core command handling

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: Remove redundant server test targets and enhance logging in core command execution

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Refactor server tests and enhance E2E testing setup

- Updated server_test.go to improve test organization and clarity, including the addition of BeforeSuite and AfterSuite for environment setup and teardown.
- Enhanced the waitWebhookSecretVolume tests to cover various scenarios including empty directories and files.
- Added new tests for syncConfigurations and logging setup functions to ensure proper configuration handling.
- Introduced a new E2E test for the main function in main_e2e_test.go to validate the core functionality of the application.
- Improved the e2e.mk file to set up a k3d cluster for running main_e2e_test with embedded test binaries and added cleanup steps.
- Removed the setup-integration-tests.sh script as its functionality is now integrated into the Makefile.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Refactor:  improve multicluster test timeouts

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
2025-11-05 10:23:24 +00:00
Vishal Kumar
5b24e8b410 Chore: Graceful skip and robust processing for missing definition directories in install script (#6964)
* Feat(script): Update installation definition script for improved error handling and namespace management

Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com>

* added line to rerun the github action

Signed-off-by: vishal210893 <vishal210893@gmail.com>

* minor change to rerun the github action

Signed-off-by: vishal210893 <vishal210893@gmail.com>

* Fix(script): Enhance installation script to restore original files on failure

Signed-off-by: vishal210893 <vishal210893@gmail.com>

---------

Signed-off-by: Reetika Malhotra <malhotra.reetika25@gmail.com>
Signed-off-by: vishal210893 <vishal210893@gmail.com>
2025-11-05 09:12:56 +00:00
AshvinBambhaniya2003
305a90f428 Feat(addon): Store addon registry tokens in Secrets (#6935)
* feat(addon): Store addon registry tokens in Secrets

Previously, addon registry tokens were stored in plaintext within the 'vela-addon-registry' ConfigMap. This is not a secure practice for sensitive data.

This commit refactors the addon registry functionality to store tokens in Kubernetes Secrets. The ConfigMap now only contains a reference to the secret name, while the token itself is stored securely.

This change includes:
- Creating/updating secrets when a registry is added/updated.
- Loading tokens from secrets when a registry is listed/retrieved.
- Deleting secrets when a registry is deleted.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* test(addon): Add tests for registry token secret storage

This commit introduces a comprehensive test suite for the addon registry feature.

It includes:
- Isolated unit tests for each CRUD operation (Add, Update, List, Get, Delete) to ensure each function works correctly in isolation.
- A stateful integration test to validate the complete lifecycle of an addon registry from creation to deletion.

The tests verify that tokens are handled correctly via Kubernetes Secrets, confirming the implementation of the secure token storage feature.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat(addon): improve addon registry robustness and fix bugs

This commit introduces several improvements to the addon registry to make it more robust and fixes several bugs.

- When updating a secret, the existing secret is now fetched and updated to avoid potential conflicts.
- Deleting a non-existent registry now returns no error, making the operation idempotent.
- Getting a non-existent registry now returns a structured not-found error.
- Loading a token from a non-existent secret is now handled gracefully.
- When setting a token directly on a git-based addon source, the token secret reference is now cleared.
- The token secret reference is now correctly copied in `SafeCopy`.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* Refactor(addon): Fix secret deletion and improve registry logic

This commit refactors the addon registry data store to fix a critical bug where deleting an addon registry would not delete its associated token secret.

The root cause was that the `GetRegistry` function, which was used by `DeleteRegistry`, would load the token from the secret and then clear the `TokenSecretRef` field on the in-memory object. This meant that when `DeleteRegistry` tried to find the secret to delete, the reference was already gone.

This has been fixed by:
1. Introducing a central `getRegistries` helper function to read the raw registry data from the ConfigMap.
2. Refactoring all data store methods (`List`, `Get`, `Add`, `Update`, `Delete`) to use this central helper, removing duplicate code.
3. Ensuring `DeleteRegistry` uses the raw, unmodified registry data so that the `TokenSecretRef` is always available for deletion.

Additionally, comprehensive unit tests for the new helper functions (`getRegistries`, `loadTokenFromSecret`, `createOrUpdateTokenSecret`) have been added to verify the fix and improve overall code quality and stability.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat(addon): improve addon registry token security and logging

This commit enhances the security and observability of addon registry token handling.

- Adds a warning message to users when an insecure inline token is detected in an addon registry configuration, prompting them to migrate to a more secure secret-based storage.
- Implements info-level logging to create an audit trail for token migrations, providing administrators with visibility into security-related events.
- Refactors the token migration logic into a new `migrateInlineTokenToSecret` function, improving code clarity and maintainability.
- Introduces unit tests for the `TokenSource` interface methods and the `GetTokenSource` function to ensure correctness and prevent regressions.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* Chore: remove comments to triger ci

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-31 13:52:30 +00:00
AshvinBambhaniya2003
d1f077ee0d Fix(addon): show correct owner in definition conflict error (#6903)
* fix(addon): show correct owner in definition conflict error

When enabling an addon, if a definition conflicted with one from another existing addon, the error message would misleadingly cite the addon being installed as the owner, rather than the actual owner of the definition. This made it difficult for users to diagnose the conflict.

This commit corrects the error message generation in `checkConflictDefs` to use the name of the actual owner application. A comprehensive unit test for this function has also been added to verify the corrected behavior and prevent regressions.

Fixes #6898

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* fix(addon): show correct owner name in conflict message

When a definition conflict occurs, the error message attempts to show the addon that owns the existing definition.

However, if the owner is not a KubeVela addon application (i.e., its name doesn't have the 'addon-' prefix), the `AppName2Addon` function returns an empty string. This resulted in a confusing conflict message with a blank owner name, like "already exist in  \n".

This patch fixes the issue by checking if the result of `AppName2Addon` is empty. If it is, it falls back to using the full application name of the owner,
ensuring the conflict message is always clear and actionable.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* chore(addon): update comment for addon name

- Add this comment to trigger ci

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* fix(addon): improve conflict message for addon definitions

adjust comment placement and logic to ensure correct addon name display in conflict messages

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-31 13:52:00 +00:00
AshvinBambhaniya2003
260fc1a294 Feat: Enhance unit test coverage for references/appfile package (#6913)
* feat(appfile): Enhance unit test coverage and migrate to standard Go testing

This commit significantly enhances the unit test coverage for the `references/appfile` package by introducing a comprehensive suite of new test cases and migrating existing tests to the standard Go `testing` framework with `testify/assert`.

Key additions and improvements include:
- **New Test Cases for `references/appfile/api/appfile.go`**: Added tests for `NewAppFile`, `JSONToYaml`, and `LoadFromBytes` to ensure correct application file initialization, parsing, and loading.
- **New Test Cases for `references/appfile/api/service.go`**: Introduced tests for `GetUserConfigName`, `GetApplicationConfig`, and `ToStringSlice` to validate service configuration extraction and type conversions.
- **Expanded Test Coverage for `references/appfile/app.go`**: Added new tests for `NewApplication`, `Validate`, `GetComponents`, `GetServiceConfig`, `GetApplicationSettings`, `GetWorkload`, and `GetTraits`, ensuring the robustness of application-level operations.
- **Dedicated Test Files for `modify.go` and `run.go`**: Created `modify_test.go` and `run_test.go` to provide specific unit tests for `SetWorkload`, `CreateOrUpdateApplication`, `CreateOrUpdateObjects`, and `Run` functions.
- **Test Framework Migration**: Refactored `addon_suit_test.go` to `main_test.go` and `addon_test.go` to use standard Go `testing` and `testify/assert`, improving consistency and maintainability.

These changes collectively improve the robustness, reliability, and maintainability of the `appfile` package by providing a more comprehensive and standardized testing approach.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* chore(references/appfile): improve test suite robustness and style

This commit introduces two improvements to the test suite in the `references/appfile` package.

First, the `TestMain` function in `main_test.go` is refactored to ensure the `envtest` control-plane is always stopped, even if test setup fails. This is achieved by creating a single exit path that handles cleanup, preventing resource leaks.

Second, a minor linting issue (S1005) in `modify_test.go` is fixed by removing an unnecessary assignment to the blank identifier.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* Chore: remove comment to trigger ci

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-31 13:51:09 +00:00
AshvinBambhaniya2003
24f6718619 Feat(testing): Enhance Unit Test Coverage for Core Utility Packages (#6929)
* test(cli): enhance unit test coverage for theme and color config

This commit introduces a comprehensive suite of unit tests for the theme and color configuration functions in `references/cli/top/config`.

Key changes include:
- Refactored existing tests in `color_test.go` to use table-driven sub-tests for improved clarity and maintainability.
- Added new test functions to validate color parsing, hex color detection, and default theme creation.
- Implemented tests for theme file lifecycle management, including creation and loading logic.

These additions significantly increase the test coverage and ensure the robustness and correctness of the CLI's theme and color functionality.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* test(cli): refactor and enhance tests for top view models and utils

This commit improves the unit test suite for the CLI's top view functionality by refactoring existing tests and adding new ones to increase coverage.

Key changes include:
- In `application_test.go`, `TestApplicationList_ToTableBody` is refactored to be a table-driven test, and new tests are added for `serviceNum`, `workflowMode`, and `workflowStepNum` helpers.
- In `time_test.go`, `TestTimeFormat` is refactored into a table-driven test for better structure and readability.

These changes align the tests with best practices and improve the overall robustness of the CLI top view's data presentation logic.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* test(cuegen): enhance unit test coverage for CUE generation packages

This commit introduces a comprehensive suite of unit tests and refactors existing tests for the CUE generation packages located in `references/cuegen`.

Key changes include:
- Refactored existing tests in `generator_test.go` and `provider_test.go` to use table-driven sub-tests, improving clarity, maintainability, and coverage of error conditions.
- Added new test functions to `convert_test.go` to validate helper functions for comment generation, type support, and enum field handling.
- Added new tests in `provider_test.go` to cover provider extraction, declaration modification, and panic recovery logic.

These changes significantly increase the test coverage for the `cuegen` libraries, ensuring the correctness and robustness of the CUE code generation functionality.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* test(docgen): add comprehensive unit tests for doc generation

This commit introduces a comprehensive suite of unit tests for the documentation generation package located in `references/docgen`.

Key changes include:
- Added new test files (`console_test.go`, `convert_test.go`, `openapi_test.go`) to cover the core functions for parsing and generating documentation for CUE, Terraform, and OpenAPI schemas.
- Refactored and enhanced `i18n_test.go` to use sub-tests, resolve race conditions, and improve coverage for fallback logic and error handling.
- Ensured all new and existing tests follow best practices, using table-driven tests for clarity and maintainability.

This effort significantly increases the test coverage for the `docgen` package, improving the reliability and robustness of the documentation generation features.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* test: improve test reliability and conventions

This commit introduces several improvements to the test suite to enhance reliability and adhere to best practices.

- **Fix flaky test in `docgen/openapi_test.go`**:
  The test for `GenerateConsoleDocument` was flaky because it performed an exact string match on table output generated from a map. Since map iteration order is not guaranteed, this could cause spurious failures. The test is now order-insensitive, comparing sorted sets of lines instead.

- **Improve assertions in `docgen/console_test.go`**:
  - Removes an unnecessary `test.EquateErrors()` option, which is not needed for simple string comparisons.
  - Corrects the `cmp.Diff` argument order to the standard `(want, got)` convention for clearer failure messages.
  - Fixes a typo in an error message.

- **Standardize assertions in `cli/top/config/color_test.go`**:
  Swaps `assert.Equal` arguments to the standard `(expected, actual)` convention.

- **Clean up `cuegen/generators/provider/provider_test.go`**:
  Removes a redundant error check.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-31 13:50:30 +00:00
AshvinBambhaniya2003
44ac92d1ba Feat(test): Enhance unit test coverage for webhook, workflow, VELAQL, and monitor packages (#6895)
* feat(monitor): Add unit tests for application metrics watcher

This commit introduces a new test file with comprehensive unit tests for the application metrics watcher functionality in pkg/monitor/watcher.

Key additions include:
  - Test cases for the application metrics watcher's inc() method covering add, delete, and update operations
  - Test cases for report() method that verifies dirty flags are cleared
  - Test cases for helper functions getPhase() and getApp()

These additions improve the overall test coverage and ensure the correctness of the application metrics monitoring functionality.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat(velaql): Add comprehensive unit tests for ParseVelaQLFromPath

This commit introduces new unit tests for the ParseVelaQLFromPath function in pkg/velaql, along with test data files to improve test coverage and ensure correctness.

Key additions include:
  - `pkg/velaql/parse_test.go`: Adds TestParseVelaQLFromPath function with comprehensive test cases covering:
    * Valid CUE files with and without export fields
    * Nonexistent and empty file paths
    * Invalid CUE content
    * Files with invalid export types
  - Test data files in pkg/velaql/testdata/:
    * simple-valid.cue: Valid CUE file with export field
    * simple-no-export.cue: Valid CUE file without export field
    * empty.cue: Empty CUE file
    * invalid-cue-content.cue: CUE file with invalid syntax
    * invalid-export.cue: CUE file with invalid export type

These additions improve the overall test coverage and ensure the robustness of the VELAQL parsing functionality.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat(webhook): Add unit tests for ValidateDefinitionRevision function

This commit introduces new unit tests for the ValidateDefinitionRevision function in pkg/webhook/utils to improve test coverage and ensure correctness of definition revision validation.

Key additions include:
  - `pkg/webhook/utils/utils_test.go`: Adds TestValidateDefinitionRevision function with comprehensive test cases covering:
    * Success scenarios with matching definition revisions
    * Success scenarios when definition revision does not exist
    * Failure scenarios with revision hash mismatches
    * Failure scenarios with spec mismatches
    * Failure scenarios with invalid definition revision names

These additions improve the overall test coverage and ensure the robustness of the webhook utility functions for validating definition revisions.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat(workflow): Add unit tests for OAM apply and query utilities

This commit introduces new unit tests for workflow provider functions in pkg/workflow/providers to improve test coverage and ensure correctness.

Key additions include:
  - `pkg/workflow/providers/oam/apply_test.go`: Adds TestRenderComponent function with comprehensive test cases for component rendering
  - `pkg/workflow/providers/query/utils_test.go`: Adds:
    * TestBuildResourceArray function with comprehensive test cases covering simple, nested, and complex resource tree scenarios
    * TestBuildResourceItem function with test cases for resources with and without annotations

These additions improve the overall test coverage and ensure the robustness of the workflow provider functions for OAM applications.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* fix(velaql): Improve error handling in ParseVelaQLFromPath test

This commit addresses an issue in the TestParseVelaQLFromPath function where file read errors were being silently ignored. The changes include:

- Removing the unused expectedView field from test cases
- Replacing conditional error checking with require.NoError to ensure file read operations are properly validated
- Ensuring that test failures are properly reported when file reading fails

This fix improves the reliability of the test suite by making sure that any file I/O errors are properly caught and reported rather than silently ignored.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat: Apply cross-cutting test improvements

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat: Enhance test coverage with file-specific suggestions

This commit applies file-specific suggestions to enhance the test suite's
coverage and robustness.

Key changes include:

- **`pkg/monitor/watcher/application_test.go`**:
  - Added a test case for a multi-step workflow with mixed phases to
    validate `stepPhaseCounter` aggregation.
  - Added a test for idempotence by calling `inc` twice.
  - Added test cases for an empty workflow and an unknown application phase.
  - Strengthened the `report` test to assert that counters are not cleared.

- **`pkg/velaql/parse_test.go`**:
  - Added a test case for `ParseVelaQLFromPath` to handle files with
    leading/trailing whitespace.
  - Added a test case to ensure consistent error messages for relative paths.

- **`pkg/webhook/utils/utils_test.go`**:
  - Added a test case to `TestValidateCueTemplate` for a malformed CUE
    template.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-31 13:49:15 +00:00
Chaitanyareddy0702
d627ecea2a Chore: Upgrade cuelang version to v0.14.1 (#6877)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 24s
* chore: updates culenag version and syntax across all files

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* debuggin: reverts tf provider changes

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Refactor: Simplify provider configuration by removing 'providerBasic' and directly defining access keys and region for providers

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Refactor: Consolidate provider configuration by introducing 'providerBasic' for access keys and region

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: reorganize import statements in deepcopy files for consistency

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: reorder import statements for consistency across deepcopy files

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Refactor: Safely handle pattern parameter selectors to avoid panics in GetParameters and getStatusMap

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: add comment to clarify test context in definition_revision_test.go

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: remove redundant comment from test context initialization in definition_revision_test.go

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Refactor: Introduce GetSelectorLabel function to safely extract labels from CUE selectors

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: add newline at end of file in utils.go

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: increase timeout for multi-cluster e2e

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Amit Singh <singhamitch@outlook.com>
Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
2025-10-23 10:56:37 +01:00
Ayush Kumar
d8a17740dc Refactor: controller flags registration and cobra options (#6949)
* feat: Introduce comprehensive configuration management for KubeVela

- Added multiple configuration files under `cmd/core/app/config` to encapsulate various aspects of KubeVela's functionality, including:
  - Feature gates
  - Logging (KLog)
  - Kubernetes API client settings
  - Multi-cluster management
  - OAM-specific configurations
  - Observability settings (metrics and logging)
  - Performance optimizations
  - Profiling settings
  - Reconciliation settings
  - Resource management
  - Server-level configurations
  - Sharding configurations
  - Webhook settings
  - Workflow engine configurations

- Refactored `CoreOptions` to utilize the new configuration modules, ensuring a clean delegation pattern for flag registration.
- Updated tests to validate the new configuration structure and ensure backward compatibility with legacy fields.

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: Sync config module values to legacy fields and add debug logging for webhook configuration

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: Remove debug logging for webhook configuration in server command

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* chore: Add missing newlines at the end of multiple configuration files

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: Clean up legacy field synchronization and improve configuration handling in CoreOptions

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: Introduce ControllerConfig for improved controller configuration management

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: Implement sync methods for configuration values across various modules

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: Update ControllerConfig to embed Args struct and simplify flag registration

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: Remove ConfigureKLog method and apply klog settings directly in server run function

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: Remove unnecessary line in ControllerConfig and update test assertions for CUE options

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: Enhance CUE configuration flags with detailed descriptions and add comprehensive tests for core options

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: Add backward compatibility notes to sync methods and enhance CLI override tests for configuration values

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* refactor: Standardize flag formatting in TestCoreOptions_AllConfigModulesHaveFlags

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
2025-10-23 10:54:45 +01:00
jguionnet
05b0ec89a5 Refactor: Update documentation generation to retain .md extensions and fixed Components header (#6957)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 25s
- Modified the documentation generation logic to keep .md file extensions, enhancing IDE support and compatibility with Docusaurus.
- Updated various documentation headers to include the correct .md references in auto-generated messages, ensuring consistency across multiple components (component, policy, trait, workflow).

Signed-off-by: jguionnet jguionnet@guidewire.com

Signed-off-by: jguionnet jguionnet@guidewire.com
Signed-off-by: Jerome Guionnet <jguionnet@guidewire.com>
2025-10-22 18:17:46 -07:00
Ayush Kumar
f196d66b5e Fix: Prevent index out-of-bounds in definitions (#6948)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 24s
* Fix: Update ingress messages to handle host retrieval more robustly across multiple templates

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Fix: Enhance output handling in k8s-objects template to check for empty objects

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* Fix: Ensure policy selection from envBindingPolicies only occurs if the list is not empty

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
2025-10-17 14:34:43 +01:00
AshvinBambhaniya2003
21d9d24b07 Feat(addon): Enhance unit test coverage for pkg/addon (#6901)
* feat(addon): add comprehensive unit tests for addon readers

This commit enhances the test coverage and code quality for the addon reader implementations in the pkg/addon package.

- Refactors all existing addon reader tests (gitee, github, gitlab, local) to use consistent, modern testing patterns like sub-tests.
- Replaces the old memory_reader_test.go with a completely refactored implementation.
- Adds new unit tests for previously untested functions, including various getters, client constructors, and RelativePath helpers.
- Improves http-based tests (gitlab, github, gitee) to use robust mock handlers that correctly simulate API behavior, including pagination and error states.

These changes improve the overall quality and reliability of the addon system and uncovered two minor bugs during the process.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat(addon): add more unit tests for addon helpers

This commit continues to improve the test coverage for the pkg/addon package by adding unit tests for several helper and factory functions.

- Adds a test for WrapErrRateLimit to ensure GitHub API rate limit errors are handled correctly.
- Adds a test for ClassifyItemByPattern to verify addon file classification logic.
- Adds a test for the NewAsyncReader factory function to ensure correct reader instantiation.
- Adds tests for various utility functions in utils.go, including IsRegistryFuncs, InstallOptions, ProduceDefConflictError, and GenerateChartMetadata.

These tests increase the reliability of the addon installation and handling logic.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* feat(addon): add unit tests for versioned addon registry

This commit improves test coverage for the versioned addon registry logic in the pkg/addon package.

- Adds a unit test for resolveAddonListFromIndex to verify the logic for parsing Helm index files.
- Introduces a new table-driven test for the internal loadAddon function, covering success and multiple failure scenarios (e.g., version not found, download failure, corrupt data).
- Adds a new test helper, setupAddonTestServer, to create isolated mock HTTP servers for testing addon loading, improving test reliability and clarity.

These tests ensure the core logic for discovering and fetching versioned addons is robust and functions as expected.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* chore(addon): remove unused gitlab testdata path constant

- remove unused gitlab testdata path constant name `gitlabTestdataPath`

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* refactor(addon): improve unit tests based on review feedback

This commit addresses several code review comments to improve the quality, correctness, and robustness of the unit tests in the pkg/addon package.
- Refactors map key assertions in the memory reader test to use the correct "comma ok" idiom instead of assert.NotNil.
- Updates the GitHub reader test to use a compliant addon mock that includes the required template.cue file.
- Modifies the chart metadata test in utils_test.go to use t.TempDir() for better test isolation and automatic cleanup.
- Switches from assert.NotNil to require.NotNil in the versioned registry test to prevent panics on nil pointers.
These changes make the test suite more robust, reliable, and easier to maintain.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-17 10:47:43 +01:00
AshvinBambhaniya2003
3f5b698dac Feat(appfile): Add comprehensive unit tests for appfile and component package (#6908)
* feat(appfile): Add comprehensive unit tests for appfile package

This commit significantly enhances the test coverage for the `pkg/appfile` package by adding a comprehensive suite of new unit tests. These tests improve the reliability of core application parsing, generation, and validation logic.

Key additions include:
- **Parsing:** New tests for policy parsing, legacy application revision handling, and dynamic component loading.
- **Manifest Generation:** Added coverage for `GenerateComponentManifests` and `GeneratePolicyManifests` to ensure correctness of generated resources.
- **OAM Contracts:** New tests for `SetOAMContract` and `setWorkloadRefToTrait` to verify OAM label and reference injection.
- **Template & Context:** Added tests for loading templates from revisions (`LoadTemplateFromRevision`) and preparing the process context (`PrepareProcessContext`).
- **Validation:** Enhanced validation tests for component parameters and uniqueness of output names.

As part of this effort, the existing tests were also migrated from Ginkgo to the standard `testing` package with `testify/assert` to maintain consistency across the codebase.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* refactor(pkg/component): Migrate ref-objects tests to standard Go testing and add new test cases

This commit refactors the unit tests for `pkg/component/ref-objects` from a Ginkgo-based suite to the standard Go `testing` package. Additionally, new unit test cases have been added to further enhance test coverage and ensure the robustness of the `ref-objects` functionality.

Key changes include:
- Deletion of `pkg/component/ref_objects_suite_test.go`.
- Introduction of `pkg/component/main_test.go` to manage test environment setup and teardown using `TestMain`.
- Creation of `pkg/component/ref_objects_test.go` containing all the ref-objects related unit tests, now using standard Go testing functions, along with newly added test cases for improved coverage.

This migration improves consistency with other unit tests in the codebase and leverages the native Go testing framework.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* chore(pkg/component): Reorder imports in ref_objects_test.go

This commit reorders the import statements in `pkg/component/ref_objects_test.go` to adhere to standard Go formatting and import grouping conventions. This change improves code readability and consistency.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-17 10:45:45 +01:00
AshvinBambhaniya2003
4b1d1601c8 fix(addon): correct path calculation in gitlab reader (#6902)
The GetPath method for GitLabItem produced an incorrect path when an addon's base path in the repository was empty. This was caused by an off-by-one error in the string slicing logic that always assumed a base path separator existed, incorrectly truncating the first character of the file path.

This commit corrects the logic by adding a check for an empty base path, ensuring the full path is returned in that case.

Fixes #6899

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-17 10:43:08 +01:00
Brian Kane
ebf73d03c2 Chore: Add codeowners (#6946)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 20s
Signed-off-by: Brian Kane <briankane1@gmail.com>
2025-10-16 08:33:49 -07:00
AshvinBambhaniya2003
1d7b186664 Feat: Enhance unit test coverage for references/common package (#6918)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 26s
* feat(common): Enhance unit test coverage for common utilities

This commit significantly enhances the unit test coverage for the `references/common` package, covering a wide range of utilities related to application management, metrics, registry operations, traits, and workloads. Existing tests have also been refactored to improve readability and maintainability.

Key additions and improvements include:
- **Application Utilities**: New tests for `ExportFromAppFile`, `ApplyApp`, `IsAppfile`, `Info`, `SonLeafResource`, `LoadAppFile`, and `ApplyApplication` in `application_test.go`.
- **Metrics Utilities**: Expanded tests for `ToPercentage`, `GetPodStorage`, and `GetPodOfManagedResource` in `metrics_test.go`, with existing tests refactored to use `testify/assert` and table-driven formats.
- **Registry Operations**: New tests for `InstallComponentDefinition` and `InstallTraitDefinition` in `registry_test.go`.
- **Trait Definitions**: New `trait_test.go` file with tests for `ListRawWorkloadDefinitions`.
- **Workload Initialization**: New `workload_test.go` file with tests for `InitApplication` and `BaseComplete`.

These changes collectively improve the robustness, reliability, and maintainability of the `references/common` package by providing a more comprehensive and standardized testing approach.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* test(common): Improve test assertions and error handling

This commit improves the quality and reliability of unit tests in the `references/common` package by addressing several inconsistencies and potential issues.

Key changes include:

- Asserts the error returned by `v1beta1.AddToScheme` across multiple test files (`application_test.go`, `registry_test.go`, `workload_test.go`) to prevent masking scheme registration failures.
- Replaces `strings.Contains` with the more idiomatic `assert.Contains` in `application_test.go`.
- Adds an assertion to check the error returned by `tmpFile.Close()` in `application_test.go`.
- Uses `assert.EqualError` instead of `assert.Equal` for comparing error messages in `registry_test.go` for more precise error checking.
- Removes an unused `strings` import from `application_test.go`.

These changes lead to more robust, readable, and consistent tests.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* fix(common): Fix flaky test in TestExportFromAppFile

The `TestExportFromAppFile` test was passing locally but failing in CI with a "no matches for kind" error.

This was caused by passing an uninitialized `common.Args` object to the `ExportFromAppFile` function. The function was using the client from this object, which was not the correctly configured fake client.

This commit fixes the issue by explicitly setting the fake client on the `common.Args` object before it is used, making the test hermetic and reliable.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-14 11:33:21 -07:00
James Dobson
d46ad7e06e Chore: Remove unused parameter 'addonName' from 'vela-cli' workflow step. (#6930)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 20s
Signed-off-by: James Dobson <jdobson@guidewire.com>
2025-10-09 13:34:26 -07:00
Ayush Kumar
743fcc6efc Chore: update homebrew bump action (#6939)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 23s
* Fix: update Homebrew formula action to latest version

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>

* Fix: update Homebrew formula action reference to correct version

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>

* fix: remove redundant Homebrew bump action

- Fixes: https://github.com/kubevela/kubevela/actions/runs/18149681613/job/51659048948
- The kubevela formula in homebrew/core is already configured for automatic updates via BrewTestBot.
- BrewTestBot runs every ~3 hours after a new release to automatically open version bump PRs.
- The manual bump step (dawidd6/action-homebrew-bump-formula) was redundant and caused workflow failures:
  'Error: Whoops, the kubevela formula has its version update pull requests automatically opened by BrewTestBot every ~3 hours!'
- Removed the manual bump action to prevent conflicts and rely solely on BrewTestBot for formula updates https://github.com/Homebrew/homebrew-core/blob/master/Formula/k/kubevela.rb.

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>

---------

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
2025-10-06 11:59:00 -07:00
AshvinBambhaniya2003
10b45d3a8f Fix(references/appfile): Fix namespace check and Terraform output parsing (#6915)
* fix(references/appfile): correct namespace existence check in addon

The `generateSecretFromTerraformOutput` function was using an incorrect logic to check for namespace existence. It was trying to create the namespace and if it succeeded, it would return an error.

This commit corrects the logic to use `k8sClient.Get` and checks for a `NotFound` error to accurately determine if the namespace exists.

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

* fix(references/appfile): make terraform output parsing robust

The previous implementation for parsing `terraform output` was fragile and could lead to data corruption or errors. It would incorrectly remove all spaces from values and would fail to parse values that contained an equals sign.

This commit refactors the parsing logic to be more robust:
- It no longer removes spaces from output values, preserving them correctly.
- It correctly parses `key=value` pairs by splitting only on the first equals sign in a line.
- It properly handles quoted string values from Terraform.

The corresponding tests in `addon_test.go` have been updated to align with the refactored function signature and verify the new, robust behavior.

Fixes #6916

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>

---------

Signed-off-by: Ashvin Bambhaniya <ashvin.bambhaniya@improwised.com>
2025-10-06 11:57:37 -07:00
Vishal Kumar
7f81d6f2d6 Feat: add KinD setup step to sync-sdk workflow (#6937)
Some checks failed
Webhook Upgrade Validation / webhook-upgrade-check (push) Failing after 34s
Signed-off-by: vishal210893 <vishal210893@gmail.com>
2025-10-02 15:01:20 -07:00
325 changed files with 41223 additions and 5390 deletions

30
.github/CODEOWNERS vendored
View File

@@ -1,35 +1,35 @@
# This file is a github code protect rule follow the codeowners https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners#example-of-a-codeowners-file
* @barnettZQG @wonderflow @leejanee @Somefive @jefree-cat @FogDong @wangyikewxgm @chivalryq @anoop2811
design/ @barnettZQG @leejanee @wonderflow @Somefive @jefree-cat @FogDong @anoop2811
* @barnettZQG @wonderflow @leejanee @Somefive @jefree-cat @FogDong @wangyikewxgm @chivalryq @anoop2811 @briankane @jguionnet
design/ @barnettZQG @leejanee @wonderflow @Somefive @jefree-cat @FogDong @anoop2811 @briankane @jguionnet
# Owner of Core Controllers
pkg/controller/core.oam.dev @Somefive @FogDong @barnettZQG @wonderflow @wangyikewxgm @chivalryq @anoop2811
pkg/controller/core.oam.dev @Somefive @FogDong @barnettZQG @wonderflow @wangyikewxgm @chivalryq @anoop2811 @briankane @jguionnet
# Owner of Standard Controllers
pkg/controller/standard.oam.dev @wangyikewxgm @barnettZQG @wonderflow @Somefive @anoop2811 @FogDong
pkg/controller/standard.oam.dev @wangyikewxgm @barnettZQG @wonderflow @Somefive @anoop2811 @FogDong @briankane @jguionnet
# Owner of CUE
pkg/cue @leejanee @FogDong @Somefive @anoop2811
pkg/stdlib @leejanee @FogDong @Somefive @anoop2811
pkg/cue @leejanee @FogDong @Somefive @anoop2811 @briankane @jguionnet
pkg/stdlib @leejanee @FogDong @Somefive @anoop2811 @briankane @jguionnet
# Owner of Workflow
pkg/workflow @leejanee @FogDong @Somefive @wangyikewxgm @chivalryq @anoop2811
pkg/workflow @leejanee @FogDong @Somefive @wangyikewxgm @chivalryq @anoop2811 @briankane @jguionnet
# Owner of vela templates
vela-templates/ @Somefive @barnettZQG @wonderflow @FogDong @wangyikewxgm @chivalryq @anoop2811
vela-templates/ @Somefive @barnettZQG @wonderflow @FogDong @wangyikewxgm @chivalryq @anoop2811 @briankane @jguionnet
# Owner of vela CLI
references/cli/ @Somefive @StevenLeiZhang @charlie0129 @wangyikewxgm @chivalryq @anoop2811 @FogDong
references/cli/ @Somefive @StevenLeiZhang @charlie0129 @wangyikewxgm @chivalryq @anoop2811 @FogDong @briankane @jguionnet
# Owner of vela addon framework
pkg/addon/ @wangyikewxgm @wonderflow @charlie0129 @anoop2811 @FogDong
pkg/addon/ @wangyikewxgm @wonderflow @charlie0129 @anoop2811 @FogDong @briankane @jguionnet
# Owner of resource keeper and tracker
pkg/resourcekeeper @Somefive @FogDong @chivalryq @anoop2811
pkg/resourcetracker @Somefive @FogDong @chivalryq @anoop2811
pkg/resourcekeeper @Somefive @FogDong @chivalryq @anoop2811 @briankane @jguionnet
pkg/resourcetracker @Somefive @FogDong @chivalryq @anoop2811 @briankane @jguionnet
.github/ @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811
makefiles @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811
go.* @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811
.github/ @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811 @briankane @jguionnet
makefiles @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811 @briankane @jguionnet
go.* @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811 @briankane @jguionnet

View File

@@ -19,6 +19,10 @@ runs:
# ========================================================================
- name: Configure environment setup
uses: ./.github/actions/env-setup
with:
install-ginkgo: 'true'
install-setup-envtest: 'false'
install-kustomize: 'false'
- name: Build project
shell: bash

View File

@@ -1,11 +1,27 @@
name: 'Kubevela Test Environment Setup'
description: 'Sets up complete testing environment for Kubevela with Go, Kubernetes tools, and Ginkgo framework for E2E testing.'
description: 'Sets up complete testing environment for Kubevela with Go, Kubernetes tools, and testing frameworks.'
inputs:
go-version:
description: 'Go version to use for testing'
required: false
default: '1.23.8'
install-ginkgo:
description: 'Install Ginkgo testing framework'
required: false
default: 'true'
install-setup-envtest:
description: 'Install setup-envtest for integration testing'
required: false
default: 'false'
install-kustomize:
description: 'Install kustomize for manifest management'
required: false
default: 'false'
kustomize-version:
description: 'Kustomize version to install'
required: false
default: '4.5.4'
runs:
@@ -66,7 +82,37 @@ runs:
go mod verify
- name: Install Ginkgo testing framework
if: ${{ inputs.install-ginkgo == 'true' }}
shell: bash
run: |
echo "Installing Ginkgo testing framework..."
go install github.com/onsi/ginkgo/v2/ginkgo@v2.14.0
echo "Ginkgo installed successfully"
- name: Install setup-envtest
if: ${{ inputs.install-setup-envtest == 'true' }}
shell: bash
run: |
echo "Installing setup-envtest for integration testing..."
mkdir -p ./bin
GOBIN=$(pwd)/bin go install sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.0.0-20240522175850-2e9781e9fc60
echo "setup-envtest installed successfully at ./bin/setup-envtest"
ls -la ./bin/setup-envtest
# Download and cache the Kubernetes binaries for envtest
echo "Downloading Kubernetes binaries for envtest..."
KUBEBUILDER_ASSETS=$(./bin/setup-envtest use 1.31.0 --bin-dir ./bin -p path)
echo "Kubernetes binaries downloaded successfully"
echo "KUBEBUILDER_ASSETS=${KUBEBUILDER_ASSETS}"
# Export for subsequent steps
echo "KUBEBUILDER_ASSETS=${KUBEBUILDER_ASSETS}" >> $GITHUB_ENV
- name: Install kustomize
if: ${{ inputs.install-kustomize == 'true' }}
shell: bash
run: |
echo "Installing kustomize version ${{ inputs.kustomize-version }}..."
mkdir -p ./bin
curl -sS https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash -s ${{ inputs.kustomize-version }} $(pwd)/bin
echo "kustomize installed successfully at ./bin/kustomize"
./bin/kustomize version

View File

@@ -20,6 +20,10 @@ runs:
# ========================================================================
- name: Configure environment setup
uses: ./.github/actions/env-setup
with:
install-ginkgo: 'true'
install-setup-envtest: 'false'
install-kustomize: 'false'
# ========================================================================
# E2E Test Execution

View File

@@ -19,6 +19,10 @@ runs:
# ========================================================================
- name: Configure environment setup
uses: ./.github/actions/env-setup
with:
install-ginkgo: 'true'
install-setup-envtest: 'true'
install-kustomize: 'true'
# ========================================================================
# Unit Test Execution

View File

@@ -11,4 +11,7 @@ wangyuan249
chivalryq
FogDong
leejanee
barnettZQG
barnettZQG
anoop2811
briankane
jguionnet

View File

@@ -97,6 +97,21 @@ jobs:
with:
submodules: true
- name: Free Disk Space
run: |
echo "Disk space before cleanup:"
df -h
# Remove unnecessary software to free up disk space
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force
echo "Disk space after cleanup:"
df -h
- name: Setup Env
uses: ./.github/actions/env-setup
@@ -111,6 +126,24 @@ jobs:
- name: Run cross-build
run: make cross-build
- name: Free Disk Space After Cross-Build
run: |
echo "Disk space before cleanup:"
df -h
# Remove cross-build artifacts to free up space
# (make build will rebuild binaries for current platform)
rm -rf _bin
# Clean Go build cache and test cache
go clean -cache -testcache
# Remove Docker build cache
sudo docker builder prune --all --force || true
echo "Disk space after cleanup:"
df -h
- name: Check Diff
run: |
export PATH=$(pwd)/bin/:$PATH

View File

@@ -111,16 +111,9 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- name: Update kubectl plugin version in krew-index
uses: rajatjindal/krew-release-bot@df3eb197549e3568be8b4767eec31c5e8e8e6ad8 # v0.0.46
- name: Update Homebrew formula
uses: dawidd6/action-homebrew-bump-formula@d3667e5ae14df19579e4414897498e3e88f2f458 # v3.10.0
with:
token: ${{ secrets.HOMEBREW_TOKEN }}
formula: kubevela
tag: ${{ github.ref }}
revision: ${{ github.sha }}
force: false
provenance-vela-bins:
name: generate provenance for binaries

View File

@@ -28,10 +28,15 @@ jobs:
- name: Install Go tools
run: |
make goimports
- name: Build CLI
run: make vela-cli
- name: Setup KinD
uses: ./.github/actions/setup-kind-cluster
with:
name: sync-sdk
- name: Get the version
id: get_version
run: echo "VERSION=${GITHUB_REF}" >> $GITHUB_OUTPUT

View File

@@ -230,7 +230,7 @@ spec:
1. Workflow support specify Order Steps by Field Tag (#2022)
2. support application policy (#2011)
3. add OCM multi cluster demo (#1992)
4. Fix(volume): seperate volume to trait (#2027)
4. Fix(volume): separate volume to trait (#2027)
5. allow application skip gc resource and leave workload ownerReference controlled by rollout(#2024)
6. Store component parameters in context (#2030)
7. Allow specify chart values for helm trait(#2033)

View File

@@ -64,8 +64,8 @@ lint: golangci
@GOLANGCILINT=$(GOLANGCILINT) ./hack/utils/golangci-lint-wrapper.sh
## reviewable: Run the reviewable
reviewable: manifests fmt vet lint staticcheck helm-doc-gen sdk_fmt
go mod tidy
## Run make build to compile vela binary before running this target to ensure all generated definitions are up to date.
reviewable: build manifests fmt vet lint staticcheck helm-doc-gen sdk_fmt
# check-diff: Execute auto-gen code commands and ensure branch is clean.
check-diff: reviewable
@@ -103,7 +103,7 @@ manager:
$(GOBUILD_ENV) go build -o bin/manager -a -ldflags $(LDFLAGS) ./cmd/core/main.go
## manifests: Generate manifests e.g. CRD, RBAC etc.
manifests: installcue kustomize
manifests: tidy installcue kustomize sync-crds
go generate $(foreach t,pkg apis,./$(t)/...)
# TODO(yangsoon): kustomize will merge all CRD into a whole file, it may not work if we want patch more than one CRD in this way
$(KUSTOMIZE) build config/crd -o config/crd/base/core.oam.dev_applications.yaml

View File

@@ -107,7 +107,7 @@ Check out [KubeVela videos](https://kubevela.io/videos/talks/en/oam-dapr) for th
## Contributing
Check out [CONTRIBUTING](https://kubevela.io/docs/contributor/overview) to see how to develop with KubeVela.
Check out [CONTRIBUTING](https://kubevela.io/docs/contributor/overview) to see how to develop with KubeVela
## Report Vulnerability

View File

@@ -26,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
wfTypesv1alpha1 "github.com/kubevela/pkg/apis/oam/v1alpha1"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
@@ -204,6 +205,24 @@ type Revision struct {
RevisionHash string `json:"revisionHash,omitempty"`
}
// AppliedApplicationPolicy records minimal status information about an Application-scoped policy.
// This covers both global (auto-discovered) and explicit (spec-referenced) policies.
// Full details (transforms, labels, annotations, etc.) are stored in the ConfigMap referenced
// by ApplicationPoliciesConfigMap for persistent storage and observability.
type AppliedApplicationPolicy struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Applied bool `json:"applied"`
Reason string `json:"reason,omitempty"` // e.g., "enabled=false: namespace mismatch"
Source string `json:"source,omitempty"` // "global" or "explicit" - how the policy was applied
// Summary of changes (counts only - full details in ConfigMap)
SpecModified bool `json:"specModified,omitempty"`
LabelsCount int `json:"labelsCount,omitempty"` // Number of labels added
AnnotationsCount int `json:"annotationsCount,omitempty"` // Number of annotations added
HasContext bool `json:"hasContext,omitempty"` // Has additionalContext data
}
// AppStatus defines the observed state of Application
type AppStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
@@ -225,6 +244,12 @@ type AppStatus struct {
// Workflow record the status of workflow
Workflow *WorkflowStatus `json:"workflow,omitempty"`
// WorkflowRestartScheduledAt schedules a workflow restart at the specified time.
// This field is automatically set when the app.oam.dev/restart-workflow annotation is present,
// and is cleared after the restart is triggered. Use RFC3339 format or set to current time for immediate restart.
// +optional
WorkflowRestartScheduledAt *metav1.Time `json:"workflowRestartScheduledAt,omitempty"`
// LatestRevision of the application configuration it generates
// +optional
LatestRevision *Revision `json:"latestRevision,omitempty"`
@@ -232,6 +257,18 @@ type AppStatus struct {
// AppliedResources record the resources that the workflow step apply.
AppliedResources []ClusterObjectReference `json:"appliedResources,omitempty"`
// AppliedApplicationPolicies lists Application-scoped policies (both global and explicit)
// that were discovered and applied (or skipped) during reconciliation.
// This provides transparency for debugging policy effects on the Application spec.
// +optional
AppliedApplicationPolicies []AppliedApplicationPolicy `json:"appliedApplicationPolicies,omitempty"`
// ApplicationPoliciesConfigMap references the ConfigMap containing rendered policy outputs
// (transforms, additionalContext, etc.) for Application-scoped policies.
// Format: "application-policies-{namespace}-{name}"
// +optional
ApplicationPoliciesConfigMap string `json:"applicationPoliciesConfigMap,omitempty"`
// PolicyStatus records the status of policy
// Deprecated This field is only used by EnvBinding Policy which is deprecated.
PolicyStatus []PolicyStatus `json:"policy,omitempty"`
@@ -301,9 +338,9 @@ type ApplicationComponent struct {
// +kubebuilder:pruning:PreserveUnknownFields
Properties *runtime.RawExtension `json:"properties,omitempty"`
DependsOn []string `json:"dependsOn,omitempty"`
Inputs workflowv1alpha1.StepInputs `json:"inputs,omitempty"`
Outputs workflowv1alpha1.StepOutputs `json:"outputs,omitempty"`
DependsOn []string `json:"dependsOn,omitempty"`
Inputs wfTypesv1alpha1.StepInputs `json:"inputs,omitempty"`
Outputs wfTypesv1alpha1.StepOutputs `json:"outputs,omitempty"`
// Traits define the trait of one component, the type must be array to keep the order.
Traits []ApplicationTrait `json:"traits,omitempty"`

View File

@@ -21,6 +21,7 @@ limitations under the License.
package common
import (
oamv1alpha1 "github.com/kubevela/pkg/apis/oam/v1alpha1"
"github.com/kubevela/workflow/api/v1alpha1"
crossplane_runtime "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
v1 "k8s.io/api/core/v1"
@@ -48,6 +49,10 @@ func (in *AppStatus) DeepCopyInto(out *AppStatus) {
*out = new(WorkflowStatus)
(*in).DeepCopyInto(*out)
}
if in.WorkflowRestartScheduledAt != nil {
in, out := &in.WorkflowRestartScheduledAt, &out.WorkflowRestartScheduledAt
*out = (*in).DeepCopy()
}
if in.LatestRevision != nil {
in, out := &in.LatestRevision, &out.LatestRevision
*out = new(Revision)
@@ -58,6 +63,11 @@ func (in *AppStatus) DeepCopyInto(out *AppStatus) {
*out = make([]ClusterObjectReference, len(*in))
copy(*out, *in)
}
if in.AppliedApplicationPolicies != nil {
in, out := &in.AppliedApplicationPolicies, &out.AppliedApplicationPolicies
*out = make([]AppliedApplicationPolicy, len(*in))
copy(*out, *in)
}
if in.PolicyStatus != nil {
in, out := &in.PolicyStatus, &out.PolicyStatus
*out = make([]PolicyStatus, len(*in))
@@ -92,12 +102,12 @@ func (in *ApplicationComponent) DeepCopyInto(out *ApplicationComponent) {
}
if in.Inputs != nil {
in, out := &in.Inputs, &out.Inputs
*out = make(v1alpha1.StepInputs, len(*in))
*out = make(oamv1alpha1.StepInputs, len(*in))
copy(*out, *in)
}
if in.Outputs != nil {
in, out := &in.Outputs, &out.Outputs
*out = make(v1alpha1.StepOutputs, len(*in))
*out = make(oamv1alpha1.StepOutputs, len(*in))
copy(*out, *in)
}
if in.Traits != nil {
@@ -203,6 +213,21 @@ func (in *ApplicationTraitStatus) DeepCopy() *ApplicationTraitStatus {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AppliedApplicationPolicy) DeepCopyInto(out *AppliedApplicationPolicy) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedApplicationPolicy.
func (in *AppliedApplicationPolicy) DeepCopy() *AppliedApplicationPolicy {
if in == nil {
return nil
}
out := new(AppliedApplicationPolicy)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CUE) DeepCopyInto(out *CUE) {
*out = *in

View File

@@ -21,7 +21,7 @@ import (
k8sscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/scheme"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
wfTypesv1alpha1 "github.com/kubevela/pkg/apis/oam/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
)
@@ -57,7 +57,7 @@ var (
func init() {
SchemeBuilder.Register(&Policy{}, &PolicyList{})
SchemeBuilder.Register(&workflowv1alpha1.Workflow{}, &workflowv1alpha1.WorkflowList{})
SchemeBuilder.Register(&wfTypesv1alpha1.Workflow{}, &wfTypesv1alpha1.WorkflowList{})
_ = SchemeBuilder.AddToScheme(k8sscheme.Scheme)
}

View File

@@ -23,7 +23,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
wfTypesv1alpha1 "github.com/kubevela/pkg/apis/oam/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
@@ -42,9 +42,9 @@ type AppPolicy struct {
// Workflow defines workflow steps and other attributes
type Workflow struct {
Ref string `json:"ref,omitempty"`
Mode *workflowv1alpha1.WorkflowExecuteMode `json:"mode,omitempty"`
Steps []workflowv1alpha1.WorkflowStep `json:"steps,omitempty"`
Ref string `json:"ref,omitempty"`
Mode *wfTypesv1alpha1.WorkflowExecuteMode `json:"mode,omitempty"`
Steps []wfTypesv1alpha1.WorkflowStep `json:"steps,omitempty"`
}
// ApplicationSpec is the spec of Application

View File

@@ -19,8 +19,8 @@ package v1beta1
import (
"encoding/json"
wfTypesv1alpha1 "github.com/kubevela/pkg/apis/oam/v1alpha1"
"github.com/kubevela/pkg/util/compression"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
@@ -63,7 +63,7 @@ type ApplicationRevisionCompressibleFields struct {
Policies map[string]v1alpha1.Policy `json:"policies,omitempty"`
// Workflow records the external workflow
Workflow *workflowv1alpha1.Workflow `json:"workflow,omitempty"`
Workflow *wfTypesv1alpha1.Workflow `json:"workflow,omitempty"`
// ReferredObjects records the referred objects used in the ref-object typed components
// +kubebuilder:pruning:PreserveUnknownFields

View File

@@ -24,6 +24,19 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
)
// PolicyScope defines the scope at which a policy operates
type PolicyScope string
const (
// DefaultScope (empty string) means standard output-based policy (topology, override, etc.)
// These policies generate Kubernetes resources from their CUE templates
DefaultScope PolicyScope = ""
// ApplicationScope means the policy transforms the Application CR before parsing
// These policies use the transforms pattern and don't generate resources
ApplicationScope PolicyScope = "Application"
)
// PolicyDefinitionSpec defines the desired state of PolicyDefinition
type PolicyDefinitionSpec struct {
// Reference to the CustomResourceDefinition that defines this trait kind.
@@ -40,6 +53,30 @@ type PolicyDefinitionSpec struct {
//+optional
Version string `json:"version,omitempty"`
// Scope defines the scope at which this policy operates.
// - DefaultScope (empty/omitted): Standard output-based policies (topology, override, etc.)
// These generate Kubernetes resources from CUE templates with an 'output' field.
// - ApplicationScope: Transform-based policies that modify the Application CR before parsing.
// These use 'transforms' instead of 'output' and don't generate resources.
// Requires EnableApplicationScopedPolicies feature gate.
// +optional
Scope PolicyScope `json:"scope,omitempty"`
// Global indicates this policy should automatically apply to all Applications
// in this namespace (or all namespaces if in vela-system).
// Global policies cannot be explicitly referenced in Application specs.
// Requires EnableGlobalPolicies feature gate for discovery and
// EnableApplicationScopedPolicies feature gate for execution.
// +optional
Global bool `json:"global,omitempty"`
// Priority defines the order in which global policies are applied.
// Higher priority policies run first. Policies with the same priority
// are applied in alphabetical order by name.
// If not specified, defaults to 0.
// +optional
Priority int32 `json:"priority,omitempty"`
}
// PolicyDefinitionStatus is the status of PolicyDefinition

View File

@@ -21,7 +21,7 @@ limitations under the License.
package v1beta1
import (
"github.com/kubevela/workflow/api/v1alpha1"
"github.com/kubevela/pkg/apis/oam/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"

View File

@@ -151,6 +151,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
| `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` |
| `admissionWebhookTimeout` | Timeout seconds for admission webhooks | `10` |
| `kubeClient.qps` | The qps for reconcile clients | `400` |
| `kubeClient.burst` | The burst for reconcile clients | `600` |
| `authentication.enabled` | Enable authentication framework for applications | `false` |

View File

@@ -372,6 +372,50 @@ spec:
status:
description: AppStatus defines the observed state of Application
properties:
applicationPoliciesConfigMap:
description: |-
ApplicationPoliciesConfigMap references the ConfigMap containing rendered policy outputs
(transforms, additionalContext, etc.) for Application-scoped policies.
Format: "application-policies-{namespace}-{name}"
type: string
appliedApplicationPolicies:
description: |-
AppliedApplicationPolicies lists Application-scoped policies (both global and explicit)
that were discovered and applied (or skipped) during reconciliation.
This provides transparency for debugging policy effects on the Application spec.
items:
description: |-
AppliedApplicationPolicy records minimal status information about an Application-scoped policy.
This covers both global (auto-discovered) and explicit (spec-referenced) policies.
Full details (transforms, labels, annotations, etc.) are stored in the ConfigMap referenced
by ApplicationPoliciesConfigMap for persistent storage and observability.
properties:
annotationsCount:
type: integer
applied:
type: boolean
hasContext:
type: boolean
labelsCount:
type: integer
name:
type: string
namespace:
type: string
reason:
type: string
source:
type: string
specModified:
description: Summary of changes (counts only - full
details in ConfigMap)
type: boolean
required:
- applied
- name
- namespace
type: object
type: array
appliedResources:
description: AppliedResources record the resources that the workflow
step apply.
@@ -817,6 +861,13 @@ spec:
- suspend
- terminated
type: object
workflowRestartScheduledAt:
description: |-
WorkflowRestartScheduledAt schedules a workflow restart at the specified time.
This field is automatically set when the app.oam.dev/restart-workflow annotation is present,
and is cleared after the restart is triggered. Use RFC3339 format or set to current time for immediate restart.
format: date-time
type: string
type: object
type: object
componentDefinitions:
@@ -1203,6 +1254,17 @@ spec:
description: PolicyDefinitionSpec defines the desired state
of PolicyDefinition
properties:
cacheTTLSeconds:
default: -1
description: |-
CacheTTLSeconds defines how long the rendered policy output should be cached
before re-rendering. This is stored per-policy in the ConfigMap.
- -1 (default): Never refresh, always reuse cached result (deterministic)
- 0: Never cache, always re-render (useful for policies with external dependencies)
- >0: Cache for this many seconds before re-rendering
The prior cached result is available to the policy template as context.prior
format: int32
type: integer
definitionRef:
description: Reference to the CustomResourceDefinition that
defines this trait kind.
@@ -1218,11 +1280,27 @@ spec:
required:
- name
type: object
global:
description: |-
Global indicates this policy should automatically apply to all Applications
in this namespace (or all namespaces if in vela-system).
Global policies cannot be explicitly referenced in Application specs.
Requires EnableGlobalPolicies feature gate for discovery and
EnableApplicationScopedPolicies feature gate for execution.
type: boolean
manageHealthCheck:
description: |-
ManageHealthCheck means the policy will handle health checking and skip application controller
built-in health checking.
type: boolean
priority:
description: |-
Priority defines the order in which global policies are applied.
Higher priority policies run first. Policies with the same priority
are applied in alphabetical order by name.
If not specified, defaults to 0.
format: int32
type: integer
schematic:
description: |-
Schematic defines the data format and template of the encapsulation of the policy definition.
@@ -1319,6 +1397,15 @@ spec:
- configuration
type: object
type: object
scope:
description: |-
Scope defines the scope at which this policy operates.
- DefaultScope (empty/omitted): Standard output-based policies (topology, override, etc.)
These generate Kubernetes resources from CUE templates with an 'output' field.
- ApplicationScope: Transform-based policies that modify the Application CR before parsing.
These use 'transforms' instead of 'output' and don't generate resources.
Requires EnableApplicationScopedPolicies feature gate.
type: string
version:
type: string
type: object

View File

@@ -322,6 +322,50 @@ spec:
status:
description: AppStatus defines the observed state of Application
properties:
applicationPoliciesConfigMap:
description: |-
ApplicationPoliciesConfigMap references the ConfigMap containing rendered policy outputs
(transforms, additionalContext, etc.) for Application-scoped policies.
Format: "application-policies-{namespace}-{name}"
type: string
appliedApplicationPolicies:
description: |-
AppliedApplicationPolicies lists Application-scoped policies (both global and explicit)
that were discovered and applied (or skipped) during reconciliation.
This provides transparency for debugging policy effects on the Application spec.
items:
description: |-
AppliedApplicationPolicy records minimal status information about an Application-scoped policy.
This covers both global (auto-discovered) and explicit (spec-referenced) policies.
Full details (transforms, labels, annotations, etc.) are stored in the ConfigMap referenced
by ApplicationPoliciesConfigMap for persistent storage and observability.
properties:
annotationsCount:
type: integer
applied:
type: boolean
hasContext:
type: boolean
labelsCount:
type: integer
name:
type: string
namespace:
type: string
reason:
type: string
source:
type: string
specModified:
description: Summary of changes (counts only - full details
in ConfigMap)
type: boolean
required:
- applied
- name
- namespace
type: object
type: array
appliedResources:
description: AppliedResources record the resources that the workflow
step apply.
@@ -760,6 +804,13 @@ spec:
- suspend
- terminated
type: object
workflowRestartScheduledAt:
description: |-
WorkflowRestartScheduledAt schedules a workflow restart at the specified time.
This field is automatically set when the app.oam.dev/restart-workflow annotation is present,
and is cleared after the restart is triggered. Use RFC3339 format or set to current time for immediate restart.
format: date-time
type: string
type: object
type: object
served: true

View File

@@ -380,6 +380,17 @@ spec:
description: PolicyDefinitionSpec defines the desired state of
PolicyDefinition
properties:
cacheTTLSeconds:
default: -1
description: |-
CacheTTLSeconds defines how long the rendered policy output should be cached
before re-rendering. This is stored per-policy in the ConfigMap.
- -1 (default): Never refresh, always reuse cached result (deterministic)
- 0: Never cache, always re-render (useful for policies with external dependencies)
- >0: Cache for this many seconds before re-rendering
The prior cached result is available to the policy template as context.prior
format: int32
type: integer
definitionRef:
description: Reference to the CustomResourceDefinition that
defines this trait kind.
@@ -395,11 +406,27 @@ spec:
required:
- name
type: object
global:
description: |-
Global indicates this policy should automatically apply to all Applications
in this namespace (or all namespaces if in vela-system).
Global policies cannot be explicitly referenced in Application specs.
Requires EnableGlobalPolicies feature gate for discovery and
EnableApplicationScopedPolicies feature gate for execution.
type: boolean
manageHealthCheck:
description: |-
ManageHealthCheck means the policy will handle health checking and skip application controller
built-in health checking.
type: boolean
priority:
description: |-
Priority defines the order in which global policies are applied.
Higher priority policies run first. Policies with the same priority
are applied in alphabetical order by name.
If not specified, defaults to 0.
format: int32
type: integer
schematic:
description: |-
Schematic defines the data format and template of the encapsulation of the policy definition.
@@ -495,6 +522,15 @@ spec:
- configuration
type: object
type: object
scope:
description: |-
Scope defines the scope at which this policy operates.
- DefaultScope (empty/omitted): Standard output-based policies (topology, override, etc.)
These generate Kubernetes resources from CUE templates with an 'output' field.
- ApplicationScope: Transform-based policies that modify the Application CR before parsing.
These use 'transforms' instead of 'output' and don't generate resources.
Requires EnableApplicationScopedPolicies feature gate.
type: string
version:
type: string
type: object

View File

@@ -43,6 +43,17 @@ spec:
spec:
description: PolicyDefinitionSpec defines the desired state of PolicyDefinition
properties:
cacheTTLSeconds:
default: -1
description: |-
CacheTTLSeconds defines how long the rendered policy output should be cached
before re-rendering. This is stored per-policy in the ConfigMap.
- -1 (default): Never refresh, always reuse cached result (deterministic)
- 0: Never cache, always re-render (useful for policies with external dependencies)
- >0: Cache for this many seconds before re-rendering
The prior cached result is available to the policy template as context.prior
format: int32
type: integer
definitionRef:
description: Reference to the CustomResourceDefinition that defines
this trait kind.
@@ -58,11 +69,27 @@ spec:
required:
- name
type: object
global:
description: |-
Global indicates this policy should automatically apply to all Applications
in this namespace (or all namespaces if in vela-system).
Global policies cannot be explicitly referenced in Application specs.
Requires EnableGlobalPolicies feature gate for discovery and
EnableApplicationScopedPolicies feature gate for execution.
type: boolean
manageHealthCheck:
description: |-
ManageHealthCheck means the policy will handle health checking and skip application controller
built-in health checking.
type: boolean
priority:
description: |-
Priority defines the order in which global policies are applied.
Higher priority policies run first. Policies with the same priority
are applied in alphabetical order by name.
If not specified, defaults to 0.
format: int32
type: integer
schematic:
description: |-
Schematic defines the data format and template of the encapsulation of the policy definition.
@@ -156,6 +183,15 @@ spec:
- configuration
type: object
type: object
scope:
description: |-
Scope defines the scope at which this policy operates.
- DefaultScope (empty/omitted): Standard output-based policies (topology, override, etc.)
These generate Kubernetes resources from CUE templates with an 'output' field.
- ApplicationScope: Transform-based policies that modify the Application CR before parsing.
These use 'transforms' instead of 'output' and don't generate resources.
Requires EnableApplicationScopedPolicies feature gate.
type: string
version:
type: string
type: object

View File

@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.16.5
name: workflows.core.oam.dev
spec:
group: core.oam.dev
@@ -23,14 +22,19 @@ spec:
description: Workflow is the Schema for the workflow API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -59,6 +63,7 @@ spec:
inputs:
description: Inputs is the inputs of the step
items:
description: InputItem defines an input variable of WorkflowStep
properties:
from:
type: string
@@ -66,7 +71,6 @@ spec:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
@@ -75,12 +79,18 @@ spec:
alias:
type: string
type: object
mode:
description: Mode is only valid for sub steps, it defines the mode
of the sub steps
nullable: true
type: string
name:
description: Name is the unique name of the workflow step.
type: string
outputs:
description: Outputs is the outputs of the step
items:
description: OutputItem defines an output variable of WorkflowStep
properties:
name:
type: string
@@ -110,6 +120,7 @@ spec:
inputs:
description: Inputs is the inputs of the step
items:
description: InputItem defines an input variable of WorkflowStep
properties:
from:
type: string
@@ -117,7 +128,6 @@ spec:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
@@ -132,6 +142,7 @@ spec:
outputs:
description: Outputs is the outputs of the step
items:
description: OutputItem defines an output variable of WorkflowStep
properties:
name:
type: string
@@ -153,7 +164,6 @@ spec:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array
@@ -164,7 +174,6 @@ spec:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array

View File

@@ -45,6 +45,7 @@ webhooks:
- UPDATE
resources:
- applications
timeoutSeconds: {{ .Values.admissionWebhookTimeout }}
- clientConfig:
caBundle: {{ default "Cg==" (get $vals "comps") }}
service:
@@ -71,5 +72,6 @@ webhooks:
- UPDATE
resources:
- componentdefinitions
timeoutSeconds: {{ .Values.admissionWebhookTimeout }}
{{- end -}}

View File

@@ -47,7 +47,7 @@ webhooks:
- UPDATE
resources:
- traitdefinitions
timeoutSeconds: 5
timeoutSeconds: {{ .Values.admissionWebhookTimeout }}
- clientConfig:
caBundle: {{ default "Cg==" (get $vals "apps") }}
service:
@@ -74,6 +74,7 @@ webhooks:
- UPDATE
resources:
- applications
timeoutSeconds: {{ .Values.admissionWebhookTimeout }}
- clientConfig:
caBundle: {{ default "Cg==" (get $vals "comps") }}
service:
@@ -100,6 +101,7 @@ webhooks:
- UPDATE
resources:
- componentdefinitions
timeoutSeconds: {{ .Values.admissionWebhookTimeout }}
- clientConfig:
caBundle: {{ default "Cg==" (get $vals "policies") }}
service:
@@ -126,6 +128,7 @@ webhooks:
- UPDATE
resources:
- policydefinitions
timeoutSeconds: {{ .Values.admissionWebhookTimeout }}
- clientConfig:
caBundle: Cg==
service:
@@ -152,4 +155,5 @@ webhooks:
- UPDATE
resources:
- workflowstepdefinitions
timeoutSeconds: {{ .Values.admissionWebhookTimeout }}
{{- end -}}

View File

@@ -15,9 +15,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
)
import "vela/op"
output: op.#ApplyApplicationInParallel & {}

View File

@@ -16,9 +16,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
)
import "vela/op"
// apply application
output: op.#ApplyApplication & {}

View File

@@ -13,12 +13,8 @@ spec:
schematic:
cue:
template: |
import (
"strconv"
"strings"
"vela/kube"
"vela/builtin"
)
import "vela/kube"
import "vela/builtin"
output: kube.#Apply & {
$params: {

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
)
import "vela/kube"
apply: kube.#Apply & {
$params: parameter

View File

@@ -16,9 +16,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
)
import "vela/op"
// apply remaining components and traits
apply: op.#ApplyRemaining & {

View File

@@ -13,10 +13,8 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
"vela/builtin"
)
import "vela/kube"
import "vela/builtin"
apply: kube.#Apply & {
$params: value: {

View File

@@ -13,12 +13,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/config"
"vela/kube"
"vela/builtin"
"strings"
)
import "vela/config"
import "vela/kube"
import "vela/builtin"
cfg: config.#CreateConfig & {
$params: {
@@ -87,9 +84,9 @@ spec:
}
}
providerBasic: {
accessKey: string
secretKey: string
region: string
accessKey!: string
secretKey!: string
region!: string
}
#AlibabaProvider: {
providerBasic
@@ -141,5 +138,5 @@ spec:
type: "ucloud"
name: *"ucloud-provider" | string
}
parameter: *#AlibabaProvider | #AWSProvider | #AzureProvider | #BaiduProvider | #ECProvider | #GCPProvider | #TencentProvider | #UCloudProvider
parameter: #AlibabaProvider | #AWSProvider | #AzureProvider | #BaiduProvider | #ECProvider | #GCPProvider | #TencentProvider | #UCloudProvider

View File

@@ -13,13 +13,10 @@ spec:
schematic:
cue:
template: |
import (
"vela/builtin"
"vela/kube"
"vela/util"
"encoding/json"
"strings"
)
import "vela/builtin"
import "vela/kube"
import "vela/util"
import "strings"
url: {
if parameter.context.git != _|_ {

View File

@@ -14,10 +14,8 @@ spec:
schematic:
cue:
template: |
import (
"vela/metrics"
"vela/builtin"
)
import "vela/metrics"
import "vela/builtin"
check: metrics.#PromCheck & {
$params: {

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
)
import "vela/kube"
parameter: {
labelselector?: {...}

View File

@@ -12,11 +12,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/builtin"
"vela/query"
"strconv"
)
import "vela/builtin"
import "vela/query"
import "strconv"
collect: query.#CollectServiceEndpoints & {
$params: app: {

View File

@@ -16,6 +16,8 @@ spec:
schematic:
cue:
template: |
import "list"
#PatchParams: {
// +usage=Specify the name of the target container, if not set, use the component name
containerName: *"" | string
@@ -73,7 +75,7 @@ spec:
}
// +patchStrategy=replace
args: [for a in _args if _delArgs[a] == _|_ {a}] + [for a in _addArgs if _delArgs[a] == _|_ && _argsMap[a] == _|_ {a}]
args: list.Concat([[for a in _args if _delArgs[a] == _|_ {a}], [for a in _addArgs if _delArgs[a] == _|_ && _argsMap[a] == _|_ {a}]])
}
}
// +patchStrategy=open

View File

@@ -17,10 +17,9 @@ spec:
schematic:
cue:
template: |
import (
"strconv"
"strings"
)
import "strconv"
import "strings"
import "list"
#PatchParams: {
// +usage=Specify the name of the target container, if not set, use the component name
@@ -67,7 +66,7 @@ spec:
_basePortsMap: {for _basePort in _basePorts {(strings.ToLower(_basePort.protocol) + strconv.FormatInt(_basePort.containerPort, 10)): _basePort}}
_portsMap: {for port in _params.ports {(strings.ToLower(port.protocol) + strconv.FormatInt(port.containerPort, 10)): port}}
// +patchStrategy=replace
ports: [for portVar in _basePorts {
ports: list.Concat([[for portVar in _basePorts {
containerPort: portVar.containerPort
protocol: portVar.protocol
name: portVar.name
@@ -80,7 +79,7 @@ spec:
hostIP: _portsMap[_uniqueKey].hostIP
}
}
}] + [for port in _params.ports if _basePortsMap[strings.ToLower(port.protocol)+strconv.FormatInt(port.containerPort, 10)] == _|_ {
}], [for port in _params.ports if _basePortsMap[strings.ToLower(port.protocol)+strconv.FormatInt(port.containerPort, 10)] == _|_ {
if port.containerPort != _|_ {
containerPort: port.containerPort
}
@@ -93,7 +92,7 @@ spec:
if port.hostIP != _|_ {
hostIP: port.hostIP
}
}]
}]])
}
}
}

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/config"
)
import "vela/config"
deploy: config.#CreateConfig & {
$params: parameter

View File

@@ -11,6 +11,8 @@ spec:
schematic:
cue:
template: |
import "list"
mountsArray: {
pvc: *[
for v in parameter.volumeMounts.pvc {
@@ -130,7 +132,7 @@ spec:
},
] | []
}
volumesList: volumesArray.pvc + volumesArray.configMap + volumesArray.secret + volumesArray.emptyDir + volumesArray.hostPath
volumesList: list.Concat([volumesArray.pvc, volumesArray.configMap, volumesArray.secret, volumesArray.emptyDir, volumesArray.hostPath])
deDupVolumesArray: [
for val in [
for i, vi in volumesList {

View File

@@ -11,9 +11,7 @@ spec:
schematic:
cue:
template: |
import (
"strconv"
)
import "strconv"
mountsArray: [
if parameter.volumeMounts != _|_ && parameter.volumeMounts.pvc != _|_ for v in parameter.volumeMounts.pvc {

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/config"
)
import "vela/config"
deploy: config.#DeleteConfig & {
$params: parameter

View File

@@ -12,11 +12,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
"vela/builtin"
"encoding/yaml"
)
import "vela/kube"
import "vela/builtin"
import "encoding/yaml"
dependsOn: kube.#Read & {
$params: value: {

View File

@@ -14,9 +14,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
)
import "vela/op"
app: op.#DeployCloudResource & {
env: parameter.env

View File

@@ -14,10 +14,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/multicluster"
"vela/builtin"
)
import "vela/multicluster"
import "vela/builtin"
if parameter.auto == false {
suspend: builtin.#Suspend & {$params: message: "Waiting approval to the deploy step \"\(context.stepName)\""}

View File

@@ -15,9 +15,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
)
import "vela/op"
app: op.#ApplyEnvBindApp & {
env: parameter.env

View File

@@ -15,9 +15,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
)
import "vela/op"
app: op.#Steps & {
load: op.#Load

View File

@@ -16,6 +16,8 @@ spec:
schematic:
cue:
template: |
import "list"
#PatchParams: {
// +usage=Specify the name of the target container, if not set, use the component name
containerName: *"" | string
@@ -49,7 +51,7 @@ spec:
if _baseEnv != _|_ {
_baseEnvMap: {for envVar in _baseEnv {(envVar.name): envVar}}
// +patchStrategy=replace
env: [for envVar in _baseEnv if _delKeys[envVar.name] == _|_ && !_params.replace {
env: list.Concat([[for envVar in _baseEnv if _delKeys[envVar.name] == _|_ && !_params.replace {
name: envVar.name
if _params.env[envVar.name] != _|_ {
value: _params.env[envVar.name]
@@ -62,10 +64,10 @@ spec:
valueFrom: envVar.valueFrom
}
}
}] + [for k, v in _params.env if _delKeys[k] == _|_ && (_params.replace || _baseEnvMap[k] == _|_) {
}], [for k, v in _params.env if _delKeys[k] == _|_ && (_params.replace || _baseEnvMap[k] == _|_) {
name: k
value: v
}]
}]])
}
}
}

View File

@@ -14,10 +14,8 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
"vela/kube"
)
import "vela/op"
import "vela/kube"
object: {
apiVersion: "v1"

View File

@@ -14,10 +14,8 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
"vela/kube"
)
import "vela/op"
import "vela/kube"
meta: {
name: *context.name | string

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
)
import "vela/kube"
apply: kube.#Apply & {
$params: {

View File

@@ -12,11 +12,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
"encoding/base64"
"encoding/json"
)
import "vela/kube"
import "encoding/base64"
import "encoding/json"
secret: {
data: *parameter.data | {}

View File

@@ -15,10 +15,8 @@ spec:
schematic:
cue:
template: |
import (
"strconv"
"strings"
)
import "strconv"
import "strings"
outputs: service: {
apiVersion: "v1"
@@ -96,21 +94,17 @@ spec:
stage: PostDispatch
status:
customStatus: |-
message: *"" | string
service: context.outputs.service
message: *"" | string
if service.spec.type == "ClusterIP" {
message: "ClusterIP: \(service.spec.clusterIP)"
}
if service.spec.type == "LoadBalancer" {
status: service.status
isHealth: *false | bool
message: *"ExternalIP: Pending" | string
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
isHealth: true
}
if !isHealth {
message: "ExternalIP: Pending"
}
if isHealth {
message: "ExternalIP: \(status.loadBalancer.ingress[0].ip)"
}
}

View File

@@ -17,6 +17,7 @@ spec:
template: |
import "strconv"
let nameSuffix = {
if parameter.name != _|_ {"-" + parameter.name}
if parameter.name == _|_ {""}
@@ -160,13 +161,17 @@ spec:
if parameter.name == _|_ { "" }
}
let ingressMetaName = context.name + nameSuffix
let ig = [for i in context.outputs if (i.kind == "Ingress") && (i.metadata.name == ingressMetaName) {i}][0]
let igList = [for i in context.outputs if (i.kind == "Ingress") && (i.metadata.name == ingressMetaName) {i}]
ig: *_|_ | _
if len(igList) > 0 {
ig: igList[0]
}
igs: *{} | {}
if ig != _|_ if ig.status != _|_ if ig.status.loadbalancer != _|_ {
if ig != _|_ if ig.status != _|_ if ig.status.loadbalancer != _|_ if len(ig.status.loadbalancer.ingress) > 0 {
igs: ig.status.loadbalancer.ingress[0]
}
igr: *{} | {}
if ig != _|_ if ig.spec != _|_ {
if ig != _|_ if ig.spec != _|_ if len(ig.spec.rules) > 0 {
igr: ig.spec.rules[0]
}
if igs == _|_ {

View File

@@ -12,11 +12,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
"vela/util"
"encoding/base64"
)
import "vela/kube"
import "vela/util"
import "encoding/base64"
output: kube.#Read & {
$params: value: {

View File

@@ -69,11 +69,16 @@ spec:
message: "No loadBalancer found, visiting by using 'vela port-forward " + context.appName + "'\n"
}
if len(igs) > 0 {
let rules = context.outputs.ingress.spec.rules
host: *"" | string
if rules != _|_ if len(rules) > 0 if rules[0].host != _|_ {
host: rules[0].host
}
if igs[0].ip != _|_ {
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + igs[0].ip
message: "Visiting URL: " + host + ", IP: " + igs[0].ip
}
if igs[0].ip == _|_ {
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host
message: "Visiting URL: " + host
}
}
healthPolicy: 'isHealth: len(context.outputs.service.spec.clusterIP) > 0'

View File

@@ -62,11 +62,16 @@ spec:
message: "No loadBalancer found, visiting by using 'vela port-forward " + context.appName + "'\n"
}
if len(igs) > 0 {
let rules = context.outputs.ingress.spec.rules
host: *"" | string
if rules != _|_ if len(rules) > 0 if rules[0].host != _|_ {
host: rules[0].host
}
if igs[0].ip != _|_ {
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + igs[0].ip
message: "Visiting URL: " + host + ", IP: " + igs[0].ip
}
if igs[0].ip == _|_ {
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host
message: "Visiting URL: " + host
}
}
healthPolicy: 'isHealth: len(context.outputs.service.spec.clusterIP) > 0'

View File

@@ -17,6 +17,8 @@ spec:
schematic:
cue:
template: |
import "list"
patch: spec: template: spec: {
// +patchKey=name
containers: [{
@@ -43,10 +45,10 @@ spec:
}
// +patchKey=name
volumeMounts: [{
volumeMounts: list.Concat([[{
name: parameter.mountName
mountPath: parameter.initMountPath
}] + parameter.extraVolumeMounts
}], parameter.extraVolumeMounts])
}]
// +patchKey=name
volumes: [{

View File

@@ -11,7 +11,12 @@ spec:
schematic:
cue:
template: |
output: parameter.objects[0]
output: {
if len(parameter.objects) > 0 {
parameter.objects[0]
}
...
}
outputs: {
for i, v in parameter.objects {

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/config"
)
import "vela/config"
output: config.#ListConfig & {
$params: parameter

View File

@@ -19,9 +19,7 @@ spec:
schematic:
cue:
template: |
import (
"encoding/json"
)
import "encoding/json"
outputs: nocalhostService: {
apiVersion: "v1"

View File

@@ -12,14 +12,12 @@ spec:
schematic:
cue:
template: |
import (
"vela/http"
"vela/email"
"vela/kube"
"vela/util"
"encoding/base64"
"encoding/json"
)
import "vela/http"
import "vela/email"
import "vela/kube"
import "vela/util"
import "encoding/base64"
import "encoding/json"
parameter: {
// +usage=Please fulfill its url and message if you want to send Lark messages

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/builtin"
)
import "vela/builtin"
parameter: message: string

View File

@@ -49,11 +49,16 @@ spec:
message: "No loadBalancer found, visiting by using 'vela port-forward " + context.appName + " --route'\n"
}
if len(igs) > 0 {
let rules = context.outputs.ingress.spec.rules
host: *"" | string
if rules != _|_ if len(rules) > 0 if rules[0].host != _|_ {
host: rules[0].host
}
if igs[0].ip != _|_ {
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + igs[0].ip
message: "Visiting URL: " + host + ", IP: " + igs[0].ip
}
if igs[0].ip == _|_ {
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host
message: "Visiting URL: " + host
}
}
workloadRefPath: ""

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/config"
)
import "vela/config"
output: config.#ReadConfig & {
$params: parameter

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
)
import "vela/kube"
output: kube.#Read & {
$params: {

View File

@@ -13,11 +13,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
"vela/http"
"encoding/json"
)
import "vela/op"
import "vela/http"
import "encoding/json"
req: http.#HTTPDo & {
$params: {

View File

@@ -0,0 +1,115 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/restart-workflow.cue
apiVersion: core.oam.dev/v1beta1
kind: WorkflowStepDefinition
metadata:
annotations:
custom.definition.oam.dev/category: Workflow Control
definition.oam.dev/description: Schedule the current Application's workflow to restart at a specific time, after a duration, or at recurring intervals
labels:
custom.definition.oam.dev/scope: Application
name: restart-workflow
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
schematic:
cue:
template: |
import "vela/kube"
import "vela/builtin"
// Count how many parameters are provided
_paramCount: len([
if parameter.at != _|_ {1},
if parameter.after != _|_ {1},
if parameter.every != _|_ {1},
])
// Fail if not exactly one parameter is provided
if _paramCount != 1 {
validateParams: builtin.#Fail & {
$params: message: "Exactly one of 'at', 'after', or 'every' parameters must be specified (found \(_paramCount))"
}
}
// Build the bash script to calculate annotation value
_script: string
if parameter.at != _|_ {
// Fixed timestamp mode - use as-is
_script: """
VALUE="\(parameter.at)"
kubectl annotate application \(context.name) -n \(context.namespace) app.oam.dev/restart-workflow="$VALUE" --overwrite
"""
}
if parameter.after != _|_ {
// Relative time mode - calculate timestamp using date
// Convert duration format (5m, 1h, 2d) to seconds, then calculate
_script: """
DURATION="\(parameter.after)"
# Convert duration to seconds
SECONDS=0
if [[ "$DURATION" =~ ^([0-9]+)m$ ]]; then
SECONDS=$((${BASH_REMATCH[1]} * 60))
elif [[ "$DURATION" =~ ^([0-9]+)h$ ]]; then
SECONDS=$((${BASH_REMATCH[1]} * 3600))
elif [[ "$DURATION" =~ ^([0-9]+)d$ ]]; then
SECONDS=$((${BASH_REMATCH[1]} * 86400))
else
echo "ERROR: Invalid duration format: $DURATION (expected format: 5m, 1h, or 2d)"
exit 1
fi
# Calculate future timestamp using seconds offset
VALUE=$(date -u -d "@$(($(date +%s) + SECONDS))" +%Y-%m-%dT%H:%M:%SZ)
echo "Calculated timestamp for after '$DURATION' ($SECONDS seconds): $VALUE"
kubectl annotate application \(context.name) -n \(context.namespace) app.oam.dev/restart-workflow="$VALUE" --overwrite
"""
}
if parameter.every != _|_ {
// Recurring interval mode - pass duration directly
_script: """
VALUE="\(parameter.every)"
kubectl annotate application \(context.name) -n \(context.namespace) app.oam.dev/restart-workflow="$VALUE" --overwrite
"""
}
// Run kubectl to annotate the Application
job: kube.#Apply & {
$params: value: {
apiVersion: "batch/v1"
kind: "Job"
metadata: {
name: "\(context.name)-restart-workflow-\(context.stepSessionID)"
namespace: "vela-system"
}
spec: {
backoffLimit: 3
template: spec: {
containers: [{
name: "kubectl-annotate"
image: "bitnami/kubectl:latest"
command: ["/bin/sh", "-c"]
args: [_script]
}]
restartPolicy: "Never"
serviceAccountName: "kubevela-vela-core"
}
}
}
}
wait: builtin.#ConditionalWait & {
if job.$returns.value.status != _|_ if job.$returns.value.status.succeeded != _|_ {
$params: continue: job.$returns.value.status.succeeded > 0
}
}
parameter: {
// +usage=Schedule restart at a specific RFC3339 timestamp (e.g., "2025-01-15T14:30:00Z")
at?: string & =~"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?(Z|[+-][0-9]{2}:[0-9]{2})$"
// +usage=Schedule restart after a relative duration from now (e.g., "5m", "1h", "2d")
after?: string & =~"^[0-9]+(m|h|d)$"
// +usage=Schedule recurring restarts every specified duration (e.g., "5m", "1h", "24h")
every?: string & =~"^[0-9]+(m|h|d)$"
}

View File

@@ -14,9 +14,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/op"
)
import "vela/op"
app: op.#ShareCloudResource & {
env: parameter.env

View File

@@ -11,10 +11,8 @@ spec:
schematic:
cue:
template: |
import (
"strconv"
"strings"
)
import "strconv"
import "strings"
mountsArray: [
if parameter.volumeMounts != _|_ if parameter.volumeMounts.pvc != _|_ for v in parameter.volumeMounts.pvc {

View File

@@ -12,9 +12,7 @@ spec:
schematic:
cue:
template: |
import (
"vela/builtin"
)
import "vela/builtin"
suspend: builtin.#Suspend & {
$params: parameter

View File

@@ -12,11 +12,9 @@ spec:
schematic:
cue:
template: |
import (
"vela/kube"
"vela/builtin"
"vela/util"
)
import "vela/kube"
import "vela/builtin"
import "vela/util"
mountsArray: [
if parameter.storage != _|_ && parameter.storage.secret != _|_ for v in parameter.storage.secret {
@@ -126,8 +124,6 @@ spec:
}
parameter: {
// +usage=Specify the name of the addon.
addonName: string
// +usage=Specify the vela command
command: [...string]
// +usage=Specify the image

View File

@@ -12,13 +12,11 @@ spec:
schematic:
cue:
template: |
import (
"vela/http"
"vela/kube"
"vela/util"
"encoding/json"
"encoding/base64"
)
import "vela/http"
import "vela/kube"
import "vela/util"
import "encoding/json"
import "encoding/base64"
data: {
if parameter.data == _|_ {

View File

@@ -11,10 +11,8 @@ spec:
schematic:
cue:
template: |
import (
"strconv"
"strings"
)
import "strconv"
import "strings"
mountsArray: [
if parameter.volumeMounts != _|_ && parameter.volumeMounts.pvc != _|_ for v in parameter.volumeMounts.pvc {

View File

@@ -267,6 +267,9 @@ logFilePath: ""
## @param 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.
logFileMaxSize: 1024
## @param admissionWebhookTimeout Timeout seconds for admission webhooks
admissionWebhookTimeout: 10
## @skip admissionWebhooks
admissionWebhooks:
enabled: true

51
cmd/core/app/bootstrap.go Normal file
View File

@@ -0,0 +1,51 @@
/*
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 app
import (
"k8s.io/klog/v2"
)
// bootstrapProviderRegistry registers framework-level providers that need
// to be available globally. This is called early in prepareRun before
// controllers are initialized.
//
// The provider registry is a fallback mechanism for breaking import cycles
// that block development. Providers registered here enable immediate feature
// work while longer-term refactoring efforts can be planned.
//
// Best practices when adding a provider:
// 1. Document which packages have the cycle (in comments below)
// 2. Define narrow, focused interfaces (< 5 methods)
// 3. Consider opportunities for future refactoring to eliminate the cycle
// 4. Prefer constructor injection for new code without cycles
//
// See pkg/registry/README.md for feature overview and pkg/registry package docs for guidelines.
func bootstrapProviderRegistry() {
klog.V(2).InfoS("Bootstrapping provider registry")
// ────────────────────────────────────────────────────────────────────
// Add providers below following this pattern:
// ────────────────────────────────────────────────────────────────────
//
// ProviderInterface - Brief description
// Cycle: pkg/foo ↔ pkg/bar (explain the circular dependency)
// Note: Consider refactoring to extract shared interfaces
// registry.RegisterAs[ProviderInterface](implementation)
klog.V(2).InfoS("Provider registry bootstrap complete")
}

View File

@@ -0,0 +1,38 @@
/*
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 config
import (
"github.com/spf13/pflag"
standardcontroller "github.com/oam-dev/kubevela/pkg/controller"
)
// AdmissionConfig contains admission control configuration.
type AdmissionConfig struct {
// Fields will be populated based on what standardcontroller.AddAdmissionFlags sets
}
// NewAdmissionConfig creates a new AdmissionConfig with defaults.
func NewAdmissionConfig() *AdmissionConfig {
return &AdmissionConfig{}
}
// AddFlags registers admission configuration flags.
func (c *AdmissionConfig) AddFlags(fs *pflag.FlagSet) {
standardcontroller.AddAdmissionFlags(fs)
}

View File

@@ -0,0 +1,56 @@
/*
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 config
import (
"time"
"github.com/spf13/pflag"
commonconfig "github.com/oam-dev/kubevela/pkg/controller/common"
)
// ApplicationConfig contains application-specific configuration.
type ApplicationConfig struct {
ReSyncPeriod time.Duration
}
// NewApplicationConfig creates a new ApplicationConfig with defaults.
func NewApplicationConfig() *ApplicationConfig {
return &ApplicationConfig{
ReSyncPeriod: commonconfig.ApplicationReSyncPeriod,
}
}
// AddFlags registers application configuration flags.
func (c *ApplicationConfig) AddFlags(fs *pflag.FlagSet) {
fs.DurationVar(&c.ReSyncPeriod,
"application-re-sync-period",
c.ReSyncPeriod,
"Re-sync period for application to re-sync, also known as the state-keep interval.")
}
// SyncToApplicationGlobals syncs the parsed configuration values to application package global variables.
// This should be called after flag parsing to ensure the application controller uses the configured values.
//
// NOTE: This method exists for backward compatibility with legacy code that depends on global
// variables in the commonconfig package. Ideally, configuration should be injected rather than using globals.
//
// The flow is: CLI flags -> ApplicationConfig struct fields -> commonconfig globals (via this method)
func (c *ApplicationConfig) SyncToApplicationGlobals() {
commonconfig.ApplicationReSyncPeriod = c.ReSyncPeriod
}

View File

@@ -0,0 +1,40 @@
/*
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 config
import (
pkgclient "github.com/kubevela/pkg/controller/client"
"github.com/spf13/pflag"
)
// ClientConfig contains controller client configuration.
// This wraps the external package's client configuration flags.
type ClientConfig struct {
// Note: The actual configuration is managed by the pkgclient package
// This is a wrapper to maintain consistency with our config pattern
}
// NewClientConfig creates a new ClientConfig with defaults.
func NewClientConfig() *ClientConfig {
return &ClientConfig{}
}
// AddFlags registers client configuration flags.
// Delegates to the external package's flag registration.
func (c *ClientConfig) AddFlags(fs *pflag.FlagSet) {
pkgclient.AddTimeoutControllerClientFlags(fs)
}

View File

@@ -0,0 +1,67 @@
/*
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 config
import (
"github.com/spf13/pflag"
oamcontroller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
)
// ControllerConfig wraps the oamcontroller.Args configuration.
// While this appears to duplicate the Args struct, it serves as the new home for
// controller flag registration after the AddFlags method was moved here from
// the oamcontroller package during refactoring.
type ControllerConfig struct {
// Embed the existing Args struct to reuse its fields
oamcontroller.Args
}
// NewControllerConfig creates a new ControllerConfig with defaults.
func NewControllerConfig() *ControllerConfig {
return &ControllerConfig{
Args: oamcontroller.Args{
RevisionLimit: 50,
AppRevisionLimit: 10,
DefRevisionLimit: 20,
AutoGenWorkloadDefinition: true,
ConcurrentReconciles: 4,
IgnoreAppWithoutControllerRequirement: false,
IgnoreDefinitionWithoutControllerRequirement: false,
},
}
}
// AddFlags registers controller configuration flags.
// This method was moved here from oamcontroller.Args during refactoring
// to centralize configuration management.
func (c *ControllerConfig) AddFlags(fs *pflag.FlagSet) {
fs.IntVar(&c.RevisionLimit, "revision-limit", c.RevisionLimit,
"RevisionLimit is the maximum number of revisions that will be maintained. The default value is 50.")
fs.IntVar(&c.AppRevisionLimit, "application-revision-limit", c.AppRevisionLimit,
"application-revision-limit is the maximum number of application useless revisions that will be maintained, if the useless revisions exceed this number, older ones will be GCed first.The default value is 10.")
fs.IntVar(&c.DefRevisionLimit, "definition-revision-limit", c.DefRevisionLimit,
"definition-revision-limit is the maximum number of component/trait definition useless revisions that will be maintained, if the useless revisions exceed this number, older ones will be GCed first.The default value is 20.")
fs.BoolVar(&c.AutoGenWorkloadDefinition, "autogen-workload-definition", c.AutoGenWorkloadDefinition,
"Automatic generated workloadDefinition which componentDefinition refers to.")
fs.IntVar(&c.ConcurrentReconciles, "concurrent-reconciles", c.ConcurrentReconciles,
"concurrent-reconciles is the concurrent reconcile number of the controller. The default value is 4")
fs.BoolVar(&c.IgnoreAppWithoutControllerRequirement, "ignore-app-without-controller-version", c.IgnoreAppWithoutControllerRequirement,
"If true, application controller will not process the app without 'app.oam.dev/controller-version-require' annotation")
fs.BoolVar(&c.IgnoreDefinitionWithoutControllerRequirement, "ignore-definition-without-controller-version", c.IgnoreDefinitionWithoutControllerRequirement,
"If true, trait/component/workflowstep definition controller will not process the definition without 'definition.oam.dev/controller-version-require' annotation")
}

View File

@@ -0,0 +1,61 @@
/*
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 config
import (
"github.com/kubevela/pkg/cue/cuex"
"github.com/spf13/pflag"
)
// CUEConfig contains CUE language configuration.
type CUEConfig struct {
EnableExternalPackage bool
EnableExternalPackageWatch bool
}
// NewCUEConfig creates a new CUEConfig with defaults.
func NewCUEConfig() *CUEConfig {
return &CUEConfig{
EnableExternalPackage: cuex.EnableExternalPackageForDefaultCompiler,
EnableExternalPackageWatch: cuex.EnableExternalPackageWatchForDefaultCompiler,
}
}
// AddFlags registers CUE configuration flags.
func (c *CUEConfig) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&c.EnableExternalPackage,
"enable-external-package-for-default-compiler",
c.EnableExternalPackage,
"Enable loading third-party CUE packages into the default CUE compiler. When enabled, external CUE packages can be imported and used in CUE templates.")
fs.BoolVar(&c.EnableExternalPackageWatch,
"enable-external-package-watch-for-default-compiler",
c.EnableExternalPackageWatch,
"Enable watching for changes in external CUE packages and automatically reload them when modified. Requires enable-external-package-for-default-compiler to be enabled.")
}
// SyncToCUEGlobals syncs the parsed configuration values to CUE package global variables.
// This should be called after flag parsing to ensure the CUE compiler uses the configured values.
//
// NOTE: This method exists for backward compatibility with legacy code that depends on global
// variables in the cuex package. Ideally, the CUE compiler configuration should be injected
// rather than relying on globals.
//
// The flow is: CLI flags -> CUEConfig struct fields -> cuex globals (via this method)
func (c *CUEConfig) SyncToCUEGlobals() {
cuex.EnableExternalPackageForDefaultCompiler = c.EnableExternalPackage
cuex.EnableExternalPackageWatchForDefaultCompiler = c.EnableExternalPackageWatch
}

View File

@@ -0,0 +1,40 @@
/*
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 config
import (
"github.com/spf13/pflag"
utilfeature "k8s.io/apiserver/pkg/util/feature"
)
// FeatureConfig contains feature gate configuration.
// This wraps the Kubernetes feature gate system.
type FeatureConfig struct {
// Note: The actual configuration is managed by the utilfeature package
// This is a wrapper to maintain consistency with our config pattern
}
// NewFeatureConfig creates a new FeatureConfig with defaults.
func NewFeatureConfig() *FeatureConfig {
return &FeatureConfig{}
}
// AddFlags registers feature gate configuration flags.
// Delegates to the Kubernetes feature gate system.
func (c *FeatureConfig) AddFlags(fs *pflag.FlagSet) {
utilfeature.DefaultMutableFeatureGate.AddFlag(fs)
}

View File

@@ -0,0 +1,42 @@
/*
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 config
import (
utillog "github.com/kubevela/pkg/util/log"
"github.com/spf13/pflag"
)
// KLogConfig contains klog configuration.
// This wraps the Kubernetes logging configuration.
type KLogConfig struct {
// Reference to observability config for log settings
observability *ObservabilityConfig
}
// NewKLogConfig creates a new KLogConfig.
func NewKLogConfig(observability *ObservabilityConfig) *KLogConfig {
return &KLogConfig{
observability: observability,
}
}
// AddFlags registers klog configuration flags.
func (c *KLogConfig) AddFlags(fs *pflag.FlagSet) {
// Add base klog flags
utillog.AddFlags(fs)
}

View File

@@ -0,0 +1,49 @@
/*
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 config
import (
"time"
"github.com/spf13/pflag"
)
// KubernetesConfig contains Kubernetes API client configuration.
type KubernetesConfig struct {
QPS float64
Burst int
InformerSyncPeriod time.Duration
}
// NewKubernetesConfig creates a new KubernetesConfig with defaults.
func NewKubernetesConfig() *KubernetesConfig {
return &KubernetesConfig{
QPS: 50,
Burst: 100,
InformerSyncPeriod: 10 * time.Hour,
}
}
// AddFlags registers Kubernetes configuration flags.
func (c *KubernetesConfig) AddFlags(fs *pflag.FlagSet) {
fs.Float64Var(&c.QPS, "kube-api-qps", c.QPS,
"the qps for reconcile clients. Low qps may lead to low throughput. High qps may give stress to api-server. Raise this value if concurrent-reconciles is set to be high.")
fs.IntVar(&c.Burst, "kube-api-burst", c.Burst,
"the burst for reconcile clients. Recommend setting it qps*2.")
fs.DurationVar(&c.InformerSyncPeriod, "informer-sync-period", c.InformerSyncPeriod,
"The re-sync period for informer in controller-runtime. This is a system-level configuration.")
}

View File

@@ -0,0 +1,53 @@
/*
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 config
import (
"time"
pkgmulticluster "github.com/kubevela/pkg/multicluster"
"github.com/spf13/pflag"
)
// MultiClusterConfig contains multi-cluster configuration.
type MultiClusterConfig struct {
EnableClusterGateway bool
EnableClusterMetrics bool
ClusterMetricsInterval time.Duration
}
// NewMultiClusterConfig creates a new MultiClusterConfig with defaults.
func NewMultiClusterConfig() *MultiClusterConfig {
return &MultiClusterConfig{
EnableClusterGateway: false,
EnableClusterMetrics: false,
ClusterMetricsInterval: 15 * time.Second,
}
}
// AddFlags registers multi-cluster configuration flags.
func (c *MultiClusterConfig) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&c.EnableClusterGateway, "enable-cluster-gateway", c.EnableClusterGateway,
"Enable cluster-gateway to use multicluster, disabled by default.")
fs.BoolVar(&c.EnableClusterMetrics, "enable-cluster-metrics", c.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")
fs.DurationVar(&c.ClusterMetricsInterval, "cluster-metrics-interval", c.ClusterMetricsInterval,
"The interval that ClusterMetricsMgr will collect metrics from clusters, default value is 15 seconds.")
// Also register additional multicluster flags from external package
pkgmulticluster.AddFlags(fs)
}

View File

@@ -0,0 +1,54 @@
/*
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 config
import (
"github.com/spf13/pflag"
"github.com/oam-dev/kubevela/pkg/oam"
)
// OAMConfig contains OAM-specific configuration.
type OAMConfig struct {
SystemDefinitionNamespace string
}
// NewOAMConfig creates a new OAMConfig with defaults.
func NewOAMConfig() *OAMConfig {
return &OAMConfig{
SystemDefinitionNamespace: "vela-system",
}
}
// AddFlags registers OAM configuration flags.
func (c *OAMConfig) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&c.SystemDefinitionNamespace,
"system-definition-namespace",
c.SystemDefinitionNamespace,
"Define the namespace of the system-level definition")
}
// SyncToOAMGlobals syncs the parsed configuration values to OAM package global variables.
// This should be called after flag parsing to ensure the OAM runtime uses the configured values.
//
// NOTE: This method exists for backward compatibility with legacy code that depends on global
// variables in the oam package. Ideally, configuration should be injected rather than using globals.
//
// The flow is: CLI flags -> OAMConfig struct fields -> oam globals (via this method)
func (c *OAMConfig) SyncToOAMGlobals() {
oam.SystemDefinitionNamespace = c.SystemDefinitionNamespace
}

View File

@@ -0,0 +1,55 @@
/*
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 config
import (
"github.com/spf13/pflag"
)
// ObservabilityConfig contains metrics and logging configuration.
type ObservabilityConfig struct {
MetricsAddr string
LogFilePath string
LogFileMaxSize uint64
LogDebug bool
DevLogs bool
}
// NewObservabilityConfig creates a new ObservabilityConfig with defaults.
func NewObservabilityConfig() *ObservabilityConfig {
return &ObservabilityConfig{
MetricsAddr: ":8080",
LogFilePath: "",
LogFileMaxSize: 1024,
LogDebug: false,
DevLogs: false,
}
}
// AddFlags registers observability configuration flags.
func (c *ObservabilityConfig) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&c.MetricsAddr, "metrics-addr", c.MetricsAddr,
"The address the metric endpoint binds to.")
fs.StringVar(&c.LogFilePath, "log-file-path", c.LogFilePath,
"The file to write logs to.")
fs.Uint64Var(&c.LogFileMaxSize, "log-file-max-size", c.LogFileMaxSize,
"Defines the maximum size a log file can grow to, Unit is megabytes.")
fs.BoolVar(&c.LogDebug, "log-debug", c.LogDebug,
"Enable debug logs for development purpose")
fs.BoolVar(&c.DevLogs, "dev-logs", c.DevLogs,
"Enable ANSI color formatting for console logs (ignored when log-file-path is set)")
}

View File

@@ -0,0 +1,58 @@
/*
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 config
import (
"github.com/spf13/pflag"
standardcontroller "github.com/oam-dev/kubevela/pkg/controller"
commonconfig "github.com/oam-dev/kubevela/pkg/controller/common"
)
// PerformanceConfig contains performance and optimization configuration.
type PerformanceConfig struct {
PerfEnabled bool
}
// NewPerformanceConfig creates a new PerformanceConfig with defaults.
func NewPerformanceConfig() *PerformanceConfig {
return &PerformanceConfig{
PerfEnabled: commonconfig.PerfEnabled,
}
}
// AddFlags registers performance configuration flags.
func (c *PerformanceConfig) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&c.PerfEnabled,
"perf-enabled",
c.PerfEnabled,
"Enable performance logging for controllers, disabled by default.")
// Add optimization flags from the standard controller
standardcontroller.AddOptimizeFlags(fs)
}
// SyncToPerformanceGlobals syncs the parsed configuration values to performance package global variables.
// This should be called after flag parsing to ensure the performance monitoring uses the configured values.
//
// NOTE: This method exists for backward compatibility with legacy code that depends on global
// variables in the commonconfig package. Ideally, configuration should be injected rather than using globals.
//
// The flow is: CLI flags -> PerformanceConfig struct fields -> commonconfig globals (via this method)
func (c *PerformanceConfig) SyncToPerformanceGlobals() {
commonconfig.PerfEnabled = c.PerfEnabled
}

View File

@@ -0,0 +1,40 @@
/*
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 config
import (
"github.com/kubevela/pkg/util/profiling"
"github.com/spf13/pflag"
)
// ProfilingConfig contains profiling configuration.
// This wraps the external package's profiling configuration flags.
type ProfilingConfig struct {
// Note: The actual configuration is managed by the profiling package
// This is a wrapper to maintain consistency with our config pattern
}
// NewProfilingConfig creates a new ProfilingConfig with defaults.
func NewProfilingConfig() *ProfilingConfig {
return &ProfilingConfig{}
}
// AddFlags registers profiling configuration flags.
// Delegates to the external package's flag registration.
func (c *ProfilingConfig) AddFlags(fs *pflag.FlagSet) {
profiling.AddFlags(fs)
}

View File

@@ -0,0 +1,40 @@
/*
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 config
import (
ctrlrec "github.com/kubevela/pkg/controller/reconciler"
"github.com/spf13/pflag"
)
// ReconcileConfig contains controller reconciliation configuration.
// This wraps the external package's reconciler configuration flags.
type ReconcileConfig struct {
// Note: The actual configuration is managed by the ctrlrec package
// This is a wrapper to maintain consistency with our config pattern
}
// NewReconcileConfig creates a new ReconcileConfig with defaults.
func NewReconcileConfig() *ReconcileConfig {
return &ReconcileConfig{}
}
// AddFlags registers reconcile configuration flags.
// Delegates to the external package's flag registration.
func (c *ReconcileConfig) AddFlags(fs *pflag.FlagSet) {
ctrlrec.AddFlags(fs)
}

View File

@@ -0,0 +1,55 @@
/*
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 config
import (
"github.com/spf13/pflag"
"github.com/oam-dev/kubevela/pkg/resourcekeeper"
)
// ResourceConfig contains resource management configuration.
type ResourceConfig struct {
MaxDispatchConcurrent int
}
// NewResourceConfig creates a new ResourceConfig with defaults.
func NewResourceConfig() *ResourceConfig {
return &ResourceConfig{
MaxDispatchConcurrent: 10,
}
}
// AddFlags registers resource configuration flags.
func (c *ResourceConfig) AddFlags(fs *pflag.FlagSet) {
fs.IntVar(&c.MaxDispatchConcurrent,
"max-dispatch-concurrent",
c.MaxDispatchConcurrent,
"Set the max dispatch concurrent number, default is 10")
}
// SyncToResourceGlobals syncs the parsed configuration values to resource package global variables.
// This should be called after flag parsing to ensure the resource keeper uses the configured values.
//
// NOTE: This method exists for backward compatibility with legacy code that depends on global
// variables in the resourcekeeper package. The long-term goal should be to refactor to use
// dependency injection rather than globals.
//
// The flow is: CLI flags -> ResourceConfig struct fields -> resourcekeeper globals (via this method)
func (c *ResourceConfig) SyncToResourceGlobals() {
resourcekeeper.MaxDispatchConcurrent = c.MaxDispatchConcurrent
}

View File

View File

@@ -0,0 +1,65 @@
/*
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 config
import (
"time"
"github.com/spf13/pflag"
)
// ServerConfig contains server-level configuration.
type ServerConfig struct {
HealthAddr string
StorageDriver string
EnableLeaderElection bool
LeaderElectionNamespace string
LeaseDuration time.Duration
RenewDeadline time.Duration
RetryPeriod time.Duration
}
// NewServerConfig creates a new ServerConfig with defaults.
func NewServerConfig() *ServerConfig {
return &ServerConfig{
HealthAddr: ":9440",
StorageDriver: "Local",
EnableLeaderElection: false,
LeaderElectionNamespace: "",
LeaseDuration: 15 * time.Second,
RenewDeadline: 10 * time.Second,
RetryPeriod: 2 * time.Second,
}
}
// AddFlags registers server configuration flags.
func (c *ServerConfig) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&c.HealthAddr, "health-addr", c.HealthAddr,
"The address the health endpoint binds to.")
fs.StringVar(&c.StorageDriver, "storage-driver", c.StorageDriver,
"Application storage driver.")
fs.BoolVar(&c.EnableLeaderElection, "enable-leader-election", c.EnableLeaderElection,
"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
fs.StringVar(&c.LeaderElectionNamespace, "leader-election-namespace", c.LeaderElectionNamespace,
"Determines the namespace in which the leader election configmap will be created.")
fs.DurationVar(&c.LeaseDuration, "leader-election-lease-duration", c.LeaseDuration,
"The duration that non-leader candidates will wait to force acquire leadership")
fs.DurationVar(&c.RenewDeadline, "leader-election-renew-deadline", c.RenewDeadline,
"The duration that the acting controlplane will retry refreshing leadership before giving up")
fs.DurationVar(&c.RetryPeriod, "leader-election-retry-period", c.RetryPeriod,
"The duration the LeaderElector clients should wait between tries of actions")
}

View File

@@ -0,0 +1,40 @@
/*
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 config
import (
"github.com/kubevela/pkg/controller/sharding"
"github.com/spf13/pflag"
)
// ShardingConfig contains controller sharding configuration.
// This wraps the external package's sharding configuration flags.
type ShardingConfig struct {
// Note: The actual configuration is managed by the sharding package
// This is a wrapper to maintain consistency with our config pattern
}
// NewShardingConfig creates a new ShardingConfig with defaults.
func NewShardingConfig() *ShardingConfig {
return &ShardingConfig{}
}
// AddFlags registers sharding configuration flags.
// Delegates to the external package's flag registration.
func (c *ShardingConfig) AddFlags(fs *pflag.FlagSet) {
sharding.AddFlags(fs)
}

View File

@@ -0,0 +1,47 @@
/*
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 config
import (
"github.com/spf13/pflag"
)
// WebhookConfig contains webhook configuration.
type WebhookConfig struct {
UseWebhook bool
CertDir string
WebhookPort int
}
// NewWebhookConfig creates a new WebhookConfig with defaults.
func NewWebhookConfig() *WebhookConfig {
return &WebhookConfig{
UseWebhook: false,
CertDir: "/k8s-webhook-server/serving-certs",
WebhookPort: 9443,
}
}
// AddFlags registers webhook configuration flags.
func (c *WebhookConfig) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&c.UseWebhook, "use-webhook", c.UseWebhook,
"Enable Admission Webhook")
fs.StringVar(&c.CertDir, "webhook-cert-dir", c.CertDir,
"Admission webhook cert/key dir.")
fs.IntVar(&c.WebhookPort, "webhook-port", c.WebhookPort,
"admission webhook listen address")
}

View File

@@ -0,0 +1,69 @@
/*
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 config
import (
"github.com/spf13/pflag"
wfTypes "github.com/kubevela/workflow/pkg/types"
)
// WorkflowConfig contains workflow engine configuration.
type WorkflowConfig struct {
MaxWaitBackoffTime int
MaxFailedBackoffTime int
MaxStepErrorRetryTimes int
}
// NewWorkflowConfig creates a new WorkflowConfig with defaults.
func NewWorkflowConfig() *WorkflowConfig {
return &WorkflowConfig{
MaxWaitBackoffTime: 60,
MaxFailedBackoffTime: 300,
MaxStepErrorRetryTimes: 10,
}
}
// AddFlags registers workflow configuration flags.
func (c *WorkflowConfig) AddFlags(fs *pflag.FlagSet) {
fs.IntVar(&c.MaxWaitBackoffTime,
"max-workflow-wait-backoff-time",
c.MaxWaitBackoffTime,
"Set the max workflow wait backoff time, default is 60")
fs.IntVar(&c.MaxFailedBackoffTime,
"max-workflow-failed-backoff-time",
c.MaxFailedBackoffTime,
"Set the max workflow failed backoff time, default is 300")
fs.IntVar(&c.MaxStepErrorRetryTimes,
"max-workflow-step-error-retry-times",
c.MaxStepErrorRetryTimes,
"Set the max workflow step error retry times, default is 10")
}
// SyncToWorkflowGlobals syncs the parsed configuration values to workflow package global variables.
// This should be called after flag parsing to ensure the workflow engine uses the configured values.
//
// NOTE: This method exists for backward compatibility with legacy code that depends on global
// variables in the wfTypes package. The long-term goal should be to refactor the workflow
// package to accept configuration via dependency injection rather than globals.
//
// The flow is: CLI flags -> WorkflowConfig struct fields -> wfTypes globals (via this method)
func (c *WorkflowConfig) SyncToWorkflowGlobals() {
wfTypes.MaxWorkflowWaitBackoffTime = c.MaxWaitBackoffTime
wfTypes.MaxWorkflowFailedBackoffTime = c.MaxFailedBackoffTime
wfTypes.MaxWorkflowStepErrorRetryTimes = c.MaxStepErrorRetryTimes
}

View File

@@ -0,0 +1,229 @@
/*
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 crdvalidation
import (
"context"
"fmt"
"time"
"github.com/kubevela/pkg/util/compression"
"github.com/kubevela/pkg/util/k8s"
"github.com/kubevela/pkg/util/singleton"
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/cmd/core/app/hooks"
"github.com/oam-dev/kubevela/pkg/features"
"github.com/oam-dev/kubevela/pkg/oam"
)
// Hook validates that CRDs installed in the cluster are compatible with
// enabled feature gates. This prevents silent data corruption by failing
// fast at startup if CRDs are out of date.
type Hook struct {
client.Client
}
// NewHook creates a new CRD validation hook with the default singleton client
func NewHook() hooks.PreStartHook {
klog.V(3).InfoS("Initializing CRD validation hook", "client", "singleton")
return NewHookWithClient(singleton.KubeClient.Get())
}
// NewHookWithClient creates a new CRD validation hook with a specified client
// for improved testability and dependency injection
func NewHookWithClient(c client.Client) hooks.PreStartHook {
klog.V(3).InfoS("Initializing CRD validation hook with custom client")
return &Hook{Client: c}
}
// Name returns the hook name for logging
func (h *Hook) Name() string {
return "CRDValidation"
}
// Run executes the CRD validation logic. It checks if compression-related
// feature gates are enabled and validates that the ApplicationRevision CRD
// supports the required compression fields.
func (h *Hook) Run(ctx context.Context) error {
klog.InfoS("Starting CRD validation hook")
// Add a reasonable timeout to prevent indefinite hanging while allowing
// sufficient time for slower clusters or API servers under load.
// 2 minutes should be more than enough for any reasonable cluster setup
// while still protecting against indefinite hangs.
timeout := 2 * time.Minute
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
zstdEnabled := feature.DefaultMutableFeatureGate.Enabled(features.ZstdApplicationRevision)
gzipEnabled := feature.DefaultMutableFeatureGate.Enabled(features.GzipApplicationRevision)
klog.V(2).InfoS("Checking compression feature gates",
"zstdEnabled", zstdEnabled,
"gzipEnabled", gzipEnabled)
if !zstdEnabled && !gzipEnabled {
klog.InfoS("No compression features enabled, skipping CRD validation")
return nil
}
klog.InfoS("Compression features enabled, validating ApplicationRevision CRD compatibility")
if err := h.validateApplicationRevisionCRD(ctx, zstdEnabled, gzipEnabled); err != nil {
// Check if the error was due to context timeout
if ctx.Err() == context.DeadlineExceeded {
klog.ErrorS(err, "CRD validation timed out - API server may be slow or unresponsive",
"timeout", timeout.String(),
"suggestion", "Check API server health and network connectivity")
return fmt.Errorf("CRD validation timed out after %v: %w. API server may be slow or under heavy load", timeout, err)
}
klog.ErrorS(err, "CRD validation failed")
return fmt.Errorf("CRD validation failed: %w", err)
}
klog.InfoS("CRD validation completed successfully")
return nil
}
// validateApplicationRevisionCRD performs a round-trip test to ensure the
// ApplicationRevision CRD supports compression fields
func (h *Hook) validateApplicationRevisionCRD(ctx context.Context, zstdEnabled, gzipEnabled bool) error {
// Generate test resource
testName := fmt.Sprintf("core.pre-check.%d", time.Now().UnixNano())
namespace := k8s.GetRuntimeNamespace()
klog.V(2).InfoS("Creating test ApplicationRevision for CRD validation",
"name", testName,
"namespace", namespace)
// Ensure the namespace exists before attempting to create resources
if err := k8s.EnsureNamespace(ctx, h.Client, namespace); err != nil {
klog.ErrorS(err, "Failed to ensure runtime namespace exists",
"namespace", namespace)
return fmt.Errorf("runtime namespace %q does not exist or is not accessible: %w", namespace, err)
}
appRev := &v1beta1.ApplicationRevision{}
appRev.Name = testName
appRev.Namespace = namespace
appRev.SetLabels(map[string]string{oam.LabelPreCheck: types.VelaCoreName})
appRev.Spec.Application.Name = testName
appRev.Spec.Application.Spec.Components = []common.ApplicationComponent{}
// Set compression type based on enabled features
var compressionType compression.Type
if zstdEnabled {
compressionType = compression.Zstd
appRev.Spec.Compression.SetType(compression.Zstd)
klog.V(3).InfoS("Setting compression type", "type", "zstd")
} else if gzipEnabled {
compressionType = compression.Gzip
appRev.Spec.Compression.SetType(compression.Gzip)
klog.V(3).InfoS("Setting compression type", "type", "gzip")
}
// Register cleanup function
defer func() {
klog.V(2).InfoS("Cleaning up test ApplicationRevisions",
"namespace", namespace,
"label", oam.LabelPreCheck)
if err := h.Client.DeleteAllOf(ctx, &v1beta1.ApplicationRevision{},
client.InNamespace(namespace),
client.MatchingLabels{oam.LabelPreCheck: types.VelaCoreName}); err != nil {
klog.ErrorS(err, "Failed to clean up test ApplicationRevision resources",
"namespace", namespace)
} else {
klog.V(3).InfoS("Successfully cleaned up test ApplicationRevision resources")
}
}()
// Create test resource
klog.V(2).InfoS("Writing test ApplicationRevision to cluster")
if err := h.Client.Create(ctx, appRev); err != nil {
klog.ErrorS(err, "Failed to create test ApplicationRevision",
"name", testName,
"namespace", namespace)
return fmt.Errorf("failed to create test ApplicationRevision: %w", err)
}
klog.V(3).InfoS("Test ApplicationRevision created successfully")
// Read back the resource
key := client.ObjectKeyFromObject(appRev)
klog.V(2).InfoS("Reading back test ApplicationRevision from cluster",
"key", key.String())
if err := h.Client.Get(ctx, key, appRev); err != nil {
klog.ErrorS(err, "Failed to read back test ApplicationRevision",
"key", key.String())
return fmt.Errorf("failed to read test ApplicationRevision: %w", err)
}
klog.V(3).InfoS("Test ApplicationRevision read successfully")
// Validate round-trip integrity
klog.V(2).InfoS("Validating round-trip data integrity",
"expectedName", testName,
"actualName", appRev.Spec.Application.Name,
"expectedCompression", compressionType,
"actualCompression", appRev.Spec.Compression.Type)
// First check that basic data survived
if appRev.Spec.Application.Name != testName {
klog.ErrorS(nil, "CRD round-trip validation failed - basic data corruption detected",
"expectedName", testName,
"actualName", appRev.Spec.Application.Name,
"compressionType", compressionType,
"issue", "The ApplicationRevision CRD does not support compression fields")
return fmt.Errorf("the ApplicationRevision CRD is not updated. Compression cannot be used. Please upgrade your CRD to latest ones")
}
// Validate that compression fields survived the round-trip
switch compressionType {
case compression.Zstd:
if appRev.Spec.Compression.Type != compression.Zstd {
klog.ErrorS(nil, "CRD round-trip validation failed - zstd compression type lost",
"expected", compression.Zstd,
"actual", appRev.Spec.Compression.Type,
"issue", "The ApplicationRevision CRD does not support zstd compression fields")
return fmt.Errorf("ApplicationRevision CRD missing zstd compression support after round-trip; got=%v. Please upgrade your CRD to latest ones", appRev.Spec.Compression.Type)
}
case compression.Gzip:
if appRev.Spec.Compression.Type != compression.Gzip {
klog.ErrorS(nil, "CRD round-trip validation failed - gzip compression type lost",
"expected", compression.Gzip,
"actual", appRev.Spec.Compression.Type,
"issue", "The ApplicationRevision CRD does not support gzip compression fields")
return fmt.Errorf("ApplicationRevision CRD missing gzip compression support after round-trip; got=%v. Please upgrade your CRD to latest ones", appRev.Spec.Compression.Type)
}
case compression.Uncompressed:
// This case should never happen as we only set Zstd or Gzip above,
// but we need to handle it to satisfy the exhaustive linter
klog.V(3).InfoS("Compression type is uncompressed, which is unexpected in validation",
"compressionType", compressionType)
}
klog.V(2).InfoS("Round-trip validation passed - CRD supports compression",
"compressionType", compressionType)
return nil
}

View File

@@ -0,0 +1,274 @@
/*
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 crdvalidation_test
import (
"context"
"errors"
"testing"
"github.com/kubevela/pkg/util/compression"
"github.com/kubevela/pkg/util/k8s"
"github.com/kubevela/pkg/util/singleton"
"github.com/kubevela/pkg/util/test/bootstrap"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"strconv"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/cmd/core/app/hooks/crdvalidation"
"github.com/oam-dev/kubevela/pkg/features"
"github.com/oam-dev/kubevela/pkg/oam"
)
var _ = bootstrap.InitKubeBuilderForTest(bootstrap.WithCRDPath("./testdata"))
func TestCRDValidationHook(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "CRD Validation Hook Suite")
}
var _ = Describe("CRD validation hook", func() {
Context("with old CRD that lacks compression support", func() {
It("should detect incompatible CRD when zstd compression is enabled", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, true)
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.GzipApplicationRevision, false)
ctx := context.Background()
Expect(k8s.EnsureNamespace(ctx, singleton.KubeClient.Get(), types.DefaultKubeVelaNS)).Should(Succeed())
hook := crdvalidation.NewHook()
Expect(hook.Name()).Should(Equal("CRDValidation"))
err := hook.Run(ctx)
Expect(err).ShouldNot(Succeed())
// The old CRD doesn't preserve the application data at all, so we get a basic corruption error
Expect(err.Error()).Should(ContainSubstring("the ApplicationRevision CRD is not updated"))
})
It("should detect incompatible CRD when gzip compression is enabled", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, false)
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.GzipApplicationRevision, true)
ctx := context.Background()
Expect(k8s.EnsureNamespace(ctx, singleton.KubeClient.Get(), types.DefaultKubeVelaNS)).Should(Succeed())
hook := crdvalidation.NewHook()
err := hook.Run(ctx)
Expect(err).ShouldNot(Succeed())
// The old CRD doesn't preserve the application data at all, so we get a basic corruption error
Expect(err.Error()).Should(ContainSubstring("the ApplicationRevision CRD is not updated"))
})
})
It("should skip validation when compression features are disabled", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, false)
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.GzipApplicationRevision, false)
ctx := context.Background()
hook := crdvalidation.NewHook()
err := hook.Run(ctx)
Expect(err).Should(Succeed())
})
Context("with dependency injection", func() {
It("should use custom client when provided", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, true)
ctx := context.Background()
// Create a fake client that simulates a CRD with compression support
fakeClient := fake.NewClientBuilder().WithScheme(singleton.KubeClient.Get().Scheme()).Build()
// Pre-create the namespace
ns := &corev1.Namespace{}
ns.Name = types.DefaultKubeVelaNS
Expect(fakeClient.Create(ctx, ns)).Should(Succeed())
// Use NewHookWithClient to inject the fake client
hook := crdvalidation.NewHookWithClient(fakeClient)
Expect(hook.Name()).Should(Equal("CRDValidation"))
// Since fake client preserves all fields, validation should pass
err := hook.Run(ctx)
Expect(err).Should(Succeed())
})
})
Context("error scenarios", func() {
It("should handle Create errors gracefully", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, true)
ctx := context.Background()
// Create a client that fails on Create operations
mockClient := &mockFailingClient{
Client: fake.NewClientBuilder().WithScheme(singleton.KubeClient.Get().Scheme()).Build(),
failCreate: true,
}
hook := crdvalidation.NewHookWithClient(mockClient)
err := hook.Run(ctx)
Expect(err).ShouldNot(Succeed())
Expect(err.Error()).Should(ContainSubstring("failed to create test ApplicationRevision"))
})
It("should handle Get errors gracefully", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.GzipApplicationRevision, true)
ctx := context.Background()
// Create a client that fails on Get operations
mockClient := &mockFailingClient{
Client: fake.NewClientBuilder().WithScheme(singleton.KubeClient.Get().Scheme()).Build(),
failGet: true,
}
// Pre-create the namespace
ns := &corev1.Namespace{}
ns.Name = types.DefaultKubeVelaNS
Expect(mockClient.Client.Create(ctx, ns)).Should(Succeed())
hook := crdvalidation.NewHookWithClient(mockClient)
err := hook.Run(ctx)
Expect(err).ShouldNot(Succeed())
Expect(err.Error()).Should(ContainSubstring("failed to read test ApplicationRevision"))
})
It("should handle namespace creation errors", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, true)
ctx := context.Background()
// Create a client that fails namespace operations
mockClient := &mockFailingClient{
Client: fake.NewClientBuilder().WithScheme(singleton.KubeClient.Get().Scheme()).Build(),
failNamespaceOps: true,
}
hook := crdvalidation.NewHookWithClient(mockClient)
err := hook.Run(ctx)
Expect(err).ShouldNot(Succeed())
Expect(err.Error()).Should(ContainSubstring("runtime namespace"))
Expect(err.Error()).Should(ContainSubstring("does not exist or is not accessible"))
})
})
Context("cleanup verification", func() {
It("should clean up test resources after validation", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.ZstdApplicationRevision, true)
ctx := context.Background()
fakeClient := fake.NewClientBuilder().WithScheme(singleton.KubeClient.Get().Scheme()).Build()
// Pre-create the namespace
ns := &corev1.Namespace{}
ns.Name = types.DefaultKubeVelaNS
Expect(fakeClient.Create(ctx, ns)).Should(Succeed())
hook := crdvalidation.NewHookWithClient(fakeClient)
_ = hook.Run(ctx)
// Verify that test ApplicationRevisions are cleaned up
appRevList := &v1beta1.ApplicationRevisionList{}
err := fakeClient.List(ctx, appRevList,
client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{oam.LabelPreCheck: types.VelaCoreName})
Expect(err).Should(Succeed())
Expect(appRevList.Items).Should(HaveLen(0))
})
It("should clean up multiple test resources with same label", func() {
featuregatetesting.SetFeatureGateDuringTest(GinkgoT(), utilfeature.DefaultFeatureGate, features.GzipApplicationRevision, true)
ctx := context.Background()
fakeClient := fake.NewClientBuilder().WithScheme(singleton.KubeClient.Get().Scheme()).Build()
// Pre-create the namespace
ns := &corev1.Namespace{}
ns.Name = types.DefaultKubeVelaNS
Expect(fakeClient.Create(ctx, ns)).Should(Succeed())
// Pre-create multiple test ApplicationRevisions with the precheck label
for i := 0; i < 3; i++ {
appRev := &v1beta1.ApplicationRevision{}
appRev.Name = "old-test-" + strconv.Itoa(i)
appRev.Namespace = types.DefaultKubeVelaNS
appRev.SetLabels(map[string]string{oam.LabelPreCheck: types.VelaCoreName})
appRev.Spec.Compression.Type = compression.Gzip
Expect(fakeClient.Create(ctx, appRev)).Should(Succeed())
}
// Verify pre-existing resources
appRevList := &v1beta1.ApplicationRevisionList{}
err := fakeClient.List(ctx, appRevList,
client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{oam.LabelPreCheck: types.VelaCoreName})
Expect(err).Should(Succeed())
Expect(appRevList.Items).Should(HaveLen(3))
// Run the hook
hook := crdvalidation.NewHookWithClient(fakeClient)
_ = hook.Run(ctx)
// Verify all test resources are cleaned up
err = fakeClient.List(ctx, appRevList,
client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{oam.LabelPreCheck: types.VelaCoreName})
Expect(err).Should(Succeed())
Expect(appRevList.Items).Should(HaveLen(0))
})
})
})
// mockFailingClient is a test client that can simulate various failure scenarios
type mockFailingClient struct {
client.Client
failCreate bool
failGet bool
failNamespaceOps bool
}
func (m *mockFailingClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error {
if m.failCreate {
if _, ok := obj.(*v1beta1.ApplicationRevision); ok {
return errors.New("simulated create failure")
}
}
if m.failNamespaceOps {
if _, ok := obj.(*corev1.Namespace); ok {
return errors.New("simulated namespace creation failure")
}
}
return m.Client.Create(ctx, obj, opts...)
}
func (m *mockFailingClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
if m.failGet {
if _, ok := obj.(*v1beta1.ApplicationRevision); ok {
return errors.New("simulated get failure")
}
}
if m.failNamespaceOps {
if _, ok := obj.(*corev1.Namespace); ok {
return apierrors.NewNotFound(corev1.SchemeGroupVersion.WithResource("namespaces").GroupResource(), key.Name)
}
}
return m.Client.Get(ctx, key, obj, opts...)
}

Some files were not shown because too many files have changed in this diff Show More