Compare commits

..

47 Commits

Author SHA1 Message Date
dependabot[bot]
ef9b6f3cc1 Chore: (deps): Bump goreleaser/goreleaser-action from 5.0.0 to 6.3.0 (#6775)
Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 5.0.0 to 6.3.0.
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](7ec5c2b0c6...9c156ee8a1)

---
updated-dependencies:
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-06 10:24:31 +05:30
dependabot[bot]
144e96df31 Chore: (deps): Bump github.com/go-git/go-git/v5 from 5.13.1 to 5.16.0 (#6764)
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.13.1 to 5.16.0.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.13.1...v5.16.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-version: 5.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-03 12:55:40 +05:30
dependabot[bot]
5ee9c8b38c Chore: (deps): Bump github/codeql-action from 2.1.37 to 3.28.16 (#6770)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.1.37 to 3.28.16.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2.1.37...28deaeda66b76a05916b6923827895f2b14ab387)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.16
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-03 12:55:00 +05:30
Vishal Kumar
d3ce7ad118 Feat(validation): fail-fast CUE validation for required parameters (incl. dynamic sources) (#6774)
* Chore: Added fail fast validation logic of component having multiple steps including workflow, component etc.

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

* testing updated param filter logic

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

* Added validation logic for struct type parameter

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

* fixed code when struct type parameter is provided in component

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

* refactor: minor code improvements

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

* fixed go lint issue

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

* Chore: Add test cases for fail fast logic

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

* updated expect logic

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

* Added e2e test cases for required param validation

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

* Added feature gate in e2e test cases for required param validation

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

* Added feature gate make e2e_test file and removed for ginkgo test file

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

* Fixed code to quoted string

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

* Added logic and test case for policy type override

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

* Added license header

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

---------

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Vishal Kumar <vishal210893@gmail.com>
Co-authored-by: Amit Singh <singhamitch@outlook.com>
Co-authored-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
2025-05-03 12:54:05 +05:30
shivin
a1145f21fe Fix: update apps with topology policy during cluster join (#6768)
* functionality to get all application with a topology in cluster

Signed-off-by: vishal210893 <vishal210893@gmail.com>
Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* refactor code and unit tests

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* refactor code and unit tests

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* rearrange imports

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* remove calling of goroutine

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* update logic to set publich version annotation

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* removed unused constants

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* make reviewable

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* add license info for cluster_test.go

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* ignore errors in updateAppsWithTopologyPolicy

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* modify error message

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* gofmt

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* add retry logic to handle conflict errors

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* using cmd to print and add log for retried applications

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* using context as first argument

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* log namespace in error

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* optimize retry logic

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* add pagination for listing applications

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

---------

Signed-off-by: vishal210893 <vishal210893@gmail.com>
Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>
Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>
Co-authored-by: vishal210893 <vishal210893@gmail.com>
2025-05-01 14:31:11 +05:30
glaxman
edf3be272e fix(traitdefinition): podsecuritycontext - Make localhostProfile optional for other types and provide it only for Localhost. Fixes #6772 (#6773)
Signed-off-by: glaxman <508625+glaxman@users.noreply.github.com>
2025-05-01 09:29:03 +05:30
Oleg Tsymbal
b4f9db4af8 Fix(Helm): make tolerations, nodeSelector, affinity more generic (#6771)
* Fix(Helm): make tolerations, nodeSelector, affinity more generic

Signed-off-by: Oleg Tsymbal <dzirg44@gmail.com>

* Fix(Helm): make conditionals if and with consistent

Signed-off-by: Oleg Tsymbal <dzirg44@gmail.com>

* Fix(Helm): trigger the build to see if it is a problem with timeout

Signed-off-by: Oleg Tsymbal <dzirg44@gmail.com>

---------

Signed-off-by: Oleg Tsymbal <dzirg44@gmail.com>
2025-04-30 14:13:25 +05:30
PushparajShetty
78c0b2c04e Chore: update go and golangci version (#6767)
* update go and golangci version

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update golangci version

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update staticcheck version

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update staticcheck version

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update staticcheck version

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update golangci_lint version

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update golangci_lint version

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml and formating in go files

Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated .golangci.yaml and formating in go files

Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* updated makefile step

Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* fix formatting issue

Signed-off-by: Gowtham S <gowthams316@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update ginkgo tests

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* updated ginkgo tests

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* upgraded go/x/crypto to v0.37.0

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* go/kin-openapi version to v0.118.0 and go/x/net version upgraded to v0.39.0

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* upgrades go/x/oauth2 version to v0.29.0

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* update ginkgo test

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* upgrades alpine image version to 3.21

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* updates ginkgo tests

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

---------

Signed-off-by: Vaibhav Agrawal <vaibhav.agrawal0096@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>
Signed-off-by: Gowtham S <gowthams316@gmail.com>
Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>
2025-04-29 03:46:08 +08:00
Anoop Gopalakrishnan
5d42a3b507 Fix: Failing issue-commands workflow (#6766)
Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
2025-04-25 06:16:59 +08:00
alingse
1588736b4e Fix: call errors.Wrap with a nil value error err (#6739)
Signed-off-by: alingse <alingse@foxmail.com>
2025-04-22 03:56:57 +05:30
Amit Singh
27965fb8aa Chore: updates vuln dependencies versions (#6757)
* chore: updates vuln dependencies versions

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

* fix check-diff tests

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

* updated import for deprecated package

Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>

---------

Signed-off-by: Amit Singh <singhamitch@outlook.com>
Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>
Co-authored-by: Gowtham <gowthams316@gmail.com>
Co-authored-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>
Co-authored-by: PushparajShetty <116911361+PushparajShetty@users.noreply.github.com>
2025-04-18 10:22:27 +05:30
PushparajShetty
262daacb63 fix the initilization for trait in output section (#6762)
Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>
2025-04-18 10:21:54 +05:30
PushparajShetty
fb17af5e75 update workflow package to fix output compatibility (#6761)
Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>
2025-04-17 03:14:49 -07:00
jguionnet
5122eb575b Update score card action version (#6759)
Signed-off-by: jguionnet <jguionnet@guidewire.com>
2025-04-15 23:25:36 +05:30
Ayush Kumar
d93e292142 feat: add signed releases, SBOMs, and SLSA provenance (#6749)
- Add SPDX SBOMs for Vela Core and CLI images
- Sign and attest images to GHCR and DockerHub
- Generate and attest SLSA provenance
- Include SBOMs for binaries via GoReleaser
- Sign artifact checksums for integrity

Signed-off-by: Ayush <ayushshyam.official.888@gmail.com>
2025-04-15 11:22:37 +08:00
shivin
f9e15c55ad upgrade vulnerable packages (#6755)
Signed-off-by: Gowtham S <gowthams316@gmail.com>
2025-04-14 22:37:52 +05:30
jguionnet
af7f623cba Feat: added support for stateful set (#6638)
* StatefulSet Draft

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

* First running version

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

* Add generated component definition

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

* Adding an statefulset example inline with the component doc

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

* Adjustment to an example defining a simplistic statefulset and trait

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

* Fix PR Review comments

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

* After running make reviewable and more ...

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

---------

Signed-off-by: jguionnet <jguionnet@guidewire.com>
2025-04-12 07:17:21 +08:00
Ayush Shyam Kumar
d487012468 adds slsa generator to the workflow (#6747)
Signed-off-by: Shivin Gopalani <gopalanishivin@gmail.com>
Signed-off-by: Ayush <ayushshyam.official.888@gmail.com>
Co-authored-by: Ayush Kumar <aykumar@guidewire.com>
2025-04-09 14:17:56 -07:00
ClarenceLiu
fc8888cb4d Fix(CUE): remove duplicate tcpSocket in startup-probe (#6528)
Signed-off-by: ComingCL <1328004790@qq.com>
2025-04-03 21:34:15 +05:30
dependabot[bot]
9558cb8491 Chore: (deps): Bump docker/build-push-action from 6.3.0 to 6.15.0 (#6740)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.3.0 to 6.15.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](1a162644f9...471d1dc4e0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 22:32:21 +05:30
Chaitanyareddy0702
bde50df3e5 Fix: Vela not deleting the definition revisions after cleaning up the definitions (#6738)
Signed-off-by: svc-gh-gokarna_gwre <svc-gh-gokarna@guidewire.com>
Co-authored-by: svc-gh-gokarna_gwre <svc-gh-gokarna@guidewire.com>
2025-03-29 06:16:03 +08:00
Vishal Kumar
dba2676cd9 Fix: modified webservice componenet definition to define resource req and … (#6714)
* modified webservice componenet definition to define resource req and limit

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

* maintained backward compatibility and introduce new parameter limit for resource limit

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

* updated definition in cue file and run make reviewable command to generate component definition

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

---------

Signed-off-by: vishal210893 <vishal210893@gmail.com>
2025-03-27 05:50:27 +08:00
Brian Kane
8ee02c6506 Feat: Enable CueX compiler in component & trait templating (#6720)
* Feat: Enable CueX compiler in component & trait templating

* Feat: Enable CueX compiler in component & trait templating

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

---------

Signed-off-by: Brian Kane <briankane1@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-25 07:52:51 +08:00
shivin
0751c15ee5 Fix: support task component to be one-time run to completion (#6733)
* added metadata.name for Job to be combination of app name and component name

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

* make reviewable

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>

---------

Signed-off-by: Shivin Gopalani <sgopalani@guidewire.com>
Co-authored-by: Shivin Gopalani <sgopalani@guidewire.com>
2025-03-25 04:56:51 +05:30
dependabot[bot]
1a16e52e36 Chore: (deps): Bump docker/setup-qemu-action from 3.0.0 to 3.6.0 (#6735)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.0.0 to 3.6.0.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](68827325e0...29109295f8)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 02:36:44 +05:30
Jonatas Teixeira
853a077107 Fix(parser) - The app.Spec.Policies[idx].Name must be a valid string (#6723)
* Fix(parser) - Valid value must be an empty string or consist of alphanumeric characters, '-', '' or '.', and must start and end with an alphanumeric character

Signed-off-by: Jonatas Teixeira <jonatas.teixeira@hellofresh.com>

* Fix(e2e) - Increase waiting to prevent test start before port-forwared be finished

Signed-off-by: Jonatas Teixeira <jonatas.teixeira@hellofresh.com>

* Fix(e2e) - Adjust the time

Signed-off-by: Jonatas Teixeira <jonatas.teixeira@hellofresh.com>

* Fix(e2e) - Increase waiting to prevent test start before port-forwared be finished - By using gomega

Signed-off-by: Jonatas Teixeira <jonatas.teixeira@hellofresh.com>

* Fix(e2e) - Change vela command to get app status

Signed-off-by: Jonatas Teixeira <jonatas.teixeira@hellofresh.com>

---------

Signed-off-by: Jonatas Teixeira <jonatas.teixeira@hellofresh.com>
2025-03-25 02:28:45 +05:30
shivin
c5d9f69c9c Fix: removing detached clusters from resource trackers (#6728)
* removing detached clusters from resource trackers

Signed-off-by: Pushparaj Shetty KS <kspushparajshetty@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* resolve merge conflicts

Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* resolved code conflicts

Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>

* update TestGetAddonStatus test case

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

---------

Signed-off-by: Pushparaj Shetty KS <kspushparajshetty@gmail.com>
Signed-off-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>
Signed-off-by: Chaitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
Co-authored-by: Shivin Gopalani <sgopalani@guidewire.com>
Co-authored-by: Pushparaj Shetty K S <kspushparajshetty@gmail.com>
2025-03-19 07:35:06 +08:00
dependabot[bot]
e0f162e47d Chore: (deps): Bump docker/login-action from 3.0.0 to 3.4.0 (#6726)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.0.0 to 3.4.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](343f7c4344...74a5d14239)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-17 22:57:49 +05:30
Chaitanyareddy0702
d9fcebb9e8 Feat: support token retrieval via AuthInfo.Exec command (#6721)
Signed-off-by: co_gwre <co@guidewire.com>
Co-authored-by: co_gwre <co@guidewire.com>
2025-03-13 07:44:18 +05:30
Anoop Gopalakrishnan
c48ded1994 Fix: build failure due to deprecated actions/cache (#6711)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 35s
E2E MultiCluster Test / detect-noop (push) Successful in 2s
E2E Test / detect-noop (push) Successful in 3s
Go / detect-noop (push) Successful in 2s
license / Check for unapproved licenses (push) Failing after 8s
Registry / publish-core-images (push) Failing after 14s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 27s
Unit-Test / detect-noop (push) Successful in 2s
Definition-Lint / definition-doc (push) Failing after 7m7s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 1m51s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m36s
Go / staticcheck (push) Successful in 2m16s
Go / check-diff (push) Successful in 18m47s
Go / lint (push) Failing after 20m12s
Go / check-cli-image-build (push) Failing after 4m29s
Go / check-core-image-build (push) Successful in 6m31s
Unit-Test / unit-tests (push) Failing after 13m24s
Go / check-windows (push) Has been cancelled
* Fix(build): Upgrade actions/cache version

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

* Fix(build): Update actions/cache

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

---------

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
2025-03-05 12:03:01 +08:00
yyzxw
424e433963 Feat: add controller metrics (#6650)
Some checks failed
Definition-Lint / definition-doc (push) Failing after 4m24s
E2E MultiCluster Test / detect-noop (push) Successful in 24s
E2E Test / detect-noop (push) Successful in 20s
Go / detect-noop (push) Successful in 23s
license / Check for unapproved licenses (push) Failing after 2m40s
Registry / publish-core-images (push) Failing after 53s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 41s
Unit-Test / detect-noop (push) Successful in 16s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 1m25s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m12s
CodeQL / Analyze (go) (push) Failing after 16m11s
Go / staticcheck (push) Successful in 18m56s
Go / lint (push) Successful in 20m1s
Go / check-diff (push) Failing after 15m2s
Go / check-cli-image-build (push) Failing after 2m41s
Go / check-core-image-build (push) Successful in 18m10s
Unit-Test / unit-tests (push) Failing after 13m17s
Go / check-windows (push) Has been cancelled
* feat: add controller metrics

Signed-off-by: yyzxw <1020938856@qq.com>

* Fix: README changes after make reviewable

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

---------

Signed-off-by: yyzxw <1020938856@qq.com>
Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
Co-authored-by: Anoop Gopalakrishnan <2038273+anoop2811@users.noreply.github.com>
Co-authored-by: Anoop Gopalakrishnan <anoop2811@aol.in>
2025-03-02 17:02:58 -08:00
dependabot[bot]
b51957ef9f Chore: (deps): Bump golangci/golangci-lint-action from 6.1.1 to 6.5.0 (#6690)
Some checks failed
Definition-Lint / definition-doc (push) Failing after 6m35s
E2E MultiCluster Test / detect-noop (push) Successful in 19s
E2E Test / detect-noop (push) Successful in 16s
Go / detect-noop (push) Successful in 16s
license / Check for unapproved licenses (push) Failing after 2m38s
Registry / publish-core-images (push) Failing after 46s
CodeQL / Analyze (go) (push) Failing after 11m34s
Unit-Test / detect-noop (push) Successful in 2s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 48s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 13s
Go / staticcheck (push) Successful in 2m7s
E2E Test / e2e-tests (v1.29) (push) Failing after 2m23s
Go / lint (push) Successful in 12m8s
Go / check-diff (push) Failing after 15m33s
Go / check-core-image-build (push) Successful in 4m53s
Go / check-cli-image-build (push) Failing after 3m17s
Unit-Test / unit-tests (push) Failing after 5m4s
Go / check-windows (push) Has been cancelled
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6.1.1 to 6.5.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](971e284b60...2226d7cb06)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-02 09:25:57 -08:00
huochexizhan
cd0b0988f9 fix: fix incorrect nil return value (#6705)
Signed-off-by: huochexizhan <huochexizhan@outlook.com>
2025-03-02 09:23:56 -08:00
Taosh
ead624e553 chore: quick deploy button for kubevela (#6692)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 2m48s
E2E MultiCluster Test / detect-noop (push) Successful in 9s
E2E Test / detect-noop (push) Successful in 8s
Go / detect-noop (push) Successful in 8s
license / Check for unapproved licenses (push) Failing after 22s
Registry / publish-core-images (push) Failing after 22s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 35s
Unit-Test / detect-noop (push) Successful in 9s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 27s
E2E Test / e2e-tests (v1.29) (push) Failing after 24s
Definition-Lint / definition-doc (push) Failing after 6m49s
Go / staticcheck (push) Successful in 2m59s
Go / lint (push) Failing after 19m45s
Go / check-diff (push) Failing after 21m3s
Go / check-core-image-build (push) Failing after 5m16s
Go / check-cli-image-build (push) Failing after 3m11s
Unit-Test / unit-tests (push) Failing after 13m17s
Go / check-windows (push) Has been cancelled
Signed-off-by: 青炽 <hanyuntao.hyt@alibaba-inc.com>
Co-authored-by: 青炽 <hanyuntao.hyt@alibaba-inc.com>
2025-02-28 19:07:41 -08:00
Daniel Higuero
f5aed7aefd Update CODEOWNERS (#6695)
Remove dhiguero from codeowners
2025-02-28 19:02:20 -08:00
shivin
30249d5297 Fix: fix for skipping deletion of orphan resources (#6700)
* fix for skipping deletion of orphan resources

Signed-off-by: Pushparaj Shetty KS <kspushparajshetty@gmail.com>

* gofmt fix

Signed-off-by: Pushparaj Shetty KS <kspushparajshetty@gmail.com>

---------

Signed-off-by: Pushparaj Shetty KS <kspushparajshetty@gmail.com>
2025-02-28 19:00:31 -08:00
Anoop Gopalakrishnan
472e1f1e59 Fix: upddate deprecated action versions (#6702)
Some checks failed
Definition-Lint / definition-doc (push) Failing after 33s
E2E MultiCluster Test / detect-noop (push) Successful in 9s
E2E Test / detect-noop (push) Successful in 9s
Go / detect-noop (push) Successful in 9s
license / Check for unapproved licenses (push) Failing after 15s
CodeQL / Analyze (go) (push) Failing after 1m55s
Registry / publish-core-images (push) Failing after 24s
Unit-Test / detect-noop (push) Successful in 9s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 36s
E2E Test / e2e-tests (v1.29) (push) Failing after 29s
Go / staticcheck (push) Successful in 20m2s
Go / lint (push) Failing after 22m11s
Go / check-core-image-build (push) Successful in 8m59s
Go / check-cli-image-build (push) Successful in 2m41s
Go / check-diff (push) Failing after 15m22s
Unit-Test / unit-tests (push) Failing after 5m29s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 35s
Go / check-windows (push) Has been cancelled
2025-02-28 11:08:05 +08:00
Tianxin Dong
33cd16d425 chore: update workflow to fix the compatibility for outputs (#6701)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 1m38s
E2E MultiCluster Test / detect-noop (push) Successful in 27s
E2E Test / detect-noop (push) Successful in 21s
Go / detect-noop (push) Successful in 26s
Definition-Lint / definition-doc (push) Successful in 3m19s
Registry / publish-core-images (push) Failing after 38s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 28s
Unit-Test / detect-noop (push) Successful in 2s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 19s
E2E Test / e2e-tests (v1.29) (push) Failing after 18s
license / Check for unapproved licenses (push) Failing after 3m3s
Go / staticcheck (push) Successful in 3m8s
Go / lint (push) Failing after 19m52s
Go / check-core-image-build (push) Failing after 4m24s
Go / check-cli-image-build (push) Failing after 3m5s
Go / check-diff (push) Successful in 25m18s
Unit-Test / unit-tests (push) Failing after 12m41s
Go / check-windows (push) Has been cancelled
Signed-off-by: FogDong <fog@bentoml.com>
2025-02-27 00:16:28 +05:30
Amit Singh
793ba55455 fix: switches to new helm repo url (#6694)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 2m2s
Definition-Lint / definition-doc (push) Failing after 7m6s
E2E MultiCluster Test / detect-noop (push) Successful in 25s
E2E Test / detect-noop (push) Successful in 35s
Go / detect-noop (push) Successful in 17s
license / Check for unapproved licenses (push) Failing after 2m49s
Registry / publish-core-images (push) Failing after 55s
Unit-Test / detect-noop (push) Successful in 23s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 2m27s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m37s
Go / staticcheck (push) Successful in 19m8s
Go / lint (push) Failing after 19m44s
Go / check-diff (push) Failing after 15m16s
Go / check-core-image-build (push) Failing after 4m5s
Go / check-cli-image-build (push) Failing after 3m1s
Unit-Test / unit-tests (push) Failing after 13m10s
Go / check-windows (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Failing after 51s
Signed-off-by: Chitanya Reddy Onteddu <chaitanyareddy0702@gmail.com>
2025-02-20 20:41:12 +05:30
Tianxin Dong
711c9f0053 fix: fix addon check (#6687)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 2m21s
Definition-Lint / definition-doc (push) Failing after 7m18s
E2E MultiCluster Test / detect-noop (push) Successful in 26s
E2E Test / detect-noop (push) Successful in 19s
Go / detect-noop (push) Successful in 19s
license / Check for unapproved licenses (push) Failing after 2m57s
Registry / publish-core-images (push) Failing after 45s
Unit-Test / detect-noop (push) Successful in 21s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 1m39s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m21s
Go / staticcheck (push) Successful in 17m18s
Go / lint (push) Failing after 19m39s
Go / check-diff (push) Failing after 14m58s
Go / check-core-image-build (push) Failing after 3m51s
Go / check-cli-image-build (push) Failing after 3m4s
Unit-Test / unit-tests (push) Failing after 12m46s
Go / check-windows (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Failing after 56s
Signed-off-by: FogDong <fog@bentoml.com>
2025-02-12 13:18:39 +08:00
Kanchan Dhamane
bc15e5b359 Feat: Semantic versioning support for Definitions (#6648)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 1m43s
Definition-Lint / definition-doc (push) Failing after 6m13s
E2E MultiCluster Test / detect-noop (push) Successful in 24s
E2E Test / detect-noop (push) Successful in 17s
Go / detect-noop (push) Successful in 21s
license / Check for unapproved licenses (push) Failing after 2m38s
Registry / publish-core-images (push) Failing after 40s
Unit-Test / detect-noop (push) Successful in 20s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 1m55s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m18s
Go / staticcheck (push) Successful in 18m35s
Go / lint (push) Failing after 19m38s
Go / check-diff (push) Failing after 15m7s
Go / check-core-image-build (push) Failing after 3m45s
Go / check-cli-image-build (push) Failing after 2m23s
Unit-Test / unit-tests (push) Failing after 12m43s
Go / check-windows (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Failing after 48s
* feature: Add Semantic versioning to KubeVela Definitions

Fixes https://github.com/kubevela/kubevela/issues/6435
Fixes https://github.com/kubevela/kubevela/issues/6534

Changes:
- Adds an optional "Version" field for all Definition Specs.
- Adds the following new validations to Webhooks for Definitions:
	- Validate the "Version" field follows Semantic versioning.
	- Dis-allow conflicting versioning fields ( Name annotation, Spec.Version)
- Adds the following new validations to Webhooks for Application:
	- Dis-allow the use of both the "publishVersion" & "autoUpdate" annotations.
- Enahnce "multiStageComponentApply" feature to support auto updates.

Boy Scout Changes:
- Fixes Plugin e2e tests broken by the fix for 6534.
- Fixes the dryRun and livediff commands to respect the "-n" namespace flag.
- Fixes the Application ValidationWebhook to respect the "-n" namespace flag.

Co-authored-by: Rahul Kumar <35751394+bugbounce@users.noreply.github.com>
Co-authored-by: Chaitanya Reddy <chaitanyareddy0702@gmail.com>
Co-authored-by: Vibhor Chinda <vibhorchinda@gmail.com>
Co-authored-by: Shivin Gopalani <gopalanishivin@gmail.com>

Signed-off-by: kanchan-dhamane <74534570+kanchan-dhamane@users.noreply.github.com>

* feature: Add KEP to define the proposal

Signed-off-by: kanchan-dhamane <74534570+kanchan-dhamane@users.noreply.github.com>

* fix: Rebase and fix merge conflicts

Signed-off-by: kanchan-dhamane <74534570+kanchan-dhamane@users.noreply.github.com>

* Fix: Adds unit test cases

Signed-off-by: kanchan-dhamane <74534570+kanchan-dhamane@users.noreply.github.com>

---------

Signed-off-by: kanchan-dhamane <74534570+kanchan-dhamane@users.noreply.github.com>
Co-authored-by: bugbounce <35751394+bugbounce@users.noreply.github.com>
2025-02-03 11:09:28 +08:00
Eko Simanjuntak
d0d7beb700 fix: return error before accesing mapping resource (#6660)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 2m18s
Definition-Lint / definition-doc (push) Failing after 6m5s
E2E MultiCluster Test / detect-noop (push) Successful in 18s
E2E Test / detect-noop (push) Successful in 21s
Go / detect-noop (push) Successful in 19s
license / Check for unapproved licenses (push) Failing after 2m30s
Registry / publish-core-images (push) Failing after 49s
Unit-Test / detect-noop (push) Successful in 18s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 1m28s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m17s
Go / staticcheck (push) Successful in 18m20s
Go / lint (push) Failing after 19m38s
Go / check-diff (push) Failing after 15m6s
Go / check-core-image-build (push) Failing after 4m1s
Go / check-cli-image-build (push) Failing after 3m2s
Unit-Test / unit-tests (push) Failing after 13m29s
Go / check-windows (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Failing after 41s
Signed-off-by: Eko Simanjuntak <ecojuntak@gmail.com>
2025-01-25 00:36:13 +05:30
dependabot[bot]
e63d8c33ec Chore: (deps): Bump github.com/go-git/go-git/v5 from 5.8.1 to 5.13.1 (#6668)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 1m30s
Definition-Lint / definition-doc (push) Failing after 6m23s
E2E MultiCluster Test / detect-noop (push) Successful in 22s
E2E Test / detect-noop (push) Successful in 24s
Go / detect-noop (push) Successful in 27s
license / Check for unapproved licenses (push) Failing after 2m46s
Registry / publish-core-images (push) Failing after 1m5s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 46s
Unit-Test / detect-noop (push) Successful in 26s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 3m12s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m13s
Go / staticcheck (push) Successful in 19m3s
Go / lint (push) Failing after 19m42s
Go / check-diff (push) Failing after 11m44s
Go / check-core-image-build (push) Failing after 3m8s
Go / check-cli-image-build (push) Failing after 2m32s
Unit-Test / unit-tests (push) Failing after 12m55s
Go / check-windows (push) Has been cancelled
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.8.1 to 5.13.1.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.8.1...v5.13.1)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 01:56:32 +05:30
dependabot[bot]
3779f828ae Chore: (deps): Bump docker/setup-buildx-action from 3.0.0 to 3.8.0 (#6678)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.0.0 to 3.8.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](f95db51fdd...6524bf65af)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 01:54:37 +05:30
dependabot[bot]
4d744a35d4 Chore: (deps): Bump golang.org/x/crypto from 0.25.0 to 0.32.0 (#6672)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 1m54s
Definition-Lint / definition-doc (push) Failing after 7m11s
E2E MultiCluster Test / detect-noop (push) Successful in 25s
E2E Test / detect-noop (push) Successful in 25s
Go / detect-noop (push) Successful in 21s
license / Check for unapproved licenses (push) Failing after 2m40s
Registry / publish-core-images (push) Failing after 38s
Unit-Test / detect-noop (push) Successful in 30s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 3m26s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m13s
Go / staticcheck (push) Successful in 20m3s
Go / lint (push) Failing after 19m36s
Go / check-diff (push) Failing after 15m14s
Go / check-core-image-build (push) Failing after 3m22s
Go / check-cli-image-build (push) Failing after 2m16s
Unit-Test / unit-tests (push) Failing after 12m30s
Go / check-windows (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Failing after 53s
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.25.0 to 0.32.0.
- [Commits](https://github.com/golang/crypto/compare/v0.25.0...v0.32.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 03:09:33 +08:00
Thomas Schuetz
9f09436359 Feat: add securityContext and podSecurityContext traits (#6666)
Some checks failed
Definition-Lint / definition-doc (push) Failing after 1m45s
CodeQL / Analyze (go) (push) Failing after 1m49s
E2E MultiCluster Test / detect-noop (push) Successful in 18s
E2E Test / detect-noop (push) Successful in 26s
Go / detect-noop (push) Successful in 21s
Registry / publish-core-images (push) Failing after 1m24s
license / Check for unapproved licenses (push) Failing after 2m53s
Unit-Test / detect-noop (push) Successful in 26s
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Failing after 1m56s
E2E Test / e2e-tests (v1.29) (push) Failing after 1m24s
Sync SDK / sync_sdk (push) Failing after 23m1s
Go / staticcheck (push) Successful in 19m14s
Go / check-diff (push) Failing after 15m19s
Go / check-core-image-build (push) Failing after 4m25s
Go / lint (push) Failing after 21m4s
Go / check-cli-image-build (push) Failing after 3m26s
Unit-Test / unit-tests (push) Failing after 8m53s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 20s
Go / check-windows (push) Has been cancelled
* feat: add securityContext and podSecurityContext traits

Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
Signed-off-by: Thomas Schütz <thomas.schuetz@karriere.at>

* Fix: broken runner config for workglow (#6669)

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
Signed-off-by: Thomas Schütz <thomas.schuetz@karriere.at>

* fix: fix spaces at for statements

Signed-off-by: Thomas Schütz <thomas.schuetz@karriere.at>

---------

Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
Signed-off-by: Thomas Schütz <thomas.schuetz@karriere.at>
Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
Co-authored-by: Anoop Gopalakrishnan <2038273+anoop2811@users.noreply.github.com>
2025-01-10 22:24:22 +05:30
Anoop Gopalakrishnan
c6765c6ff0 Fix: broken runner config for workglow (#6669)
Some checks failed
CodeQL / Analyze (go) (push) Failing after 8m37s
Definition-Lint / definition-doc (push) Failing after 6m9s
E2E Test / detect-noop (push) Successful in 20s
Go / detect-noop (push) Successful in 25s
license / Check for unapproved licenses (push) Failing after 3m7s
E2E MultiCluster Test / detect-noop (push) Failing after 10m51s
Registry / publish-core-images (push) Failing after 1m5s
Scorecards supply-chain security / Scorecards analysis (push) Failing after 4m5s
Unit-Test / detect-noop (push) Successful in 20s
E2E Test / e2e-tests (v1.29) (push) Failing after 12m25s
Go / staticcheck (push) Successful in 18m25s
Go / lint (push) Failing after 20m3s
Go / check-core-image-build (push) Failing after 4m15s
Go / check-cli-image-build (push) Failing after 3m8s
Go / check-diff (push) Failing after 17m20s
Unit-Test / unit-tests (push) Failing after 13m22s
Go / check-windows (push) Has been cancelled
E2E MultiCluster Test / e2e-multi-cluster-tests (v1.29) (push) Has been cancelled
Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
2025-01-06 13:37:59 +08:00
143 changed files with 7025 additions and 821 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 @dhiguero
design/ @barnettZQG @leejanee @wonderflow @Somefive @jefree-cat @FogDong @anoop2811 @dhiguero
* @barnettZQG @wonderflow @leejanee @Somefive @jefree-cat @FogDong @wangyikewxgm @chivalryq @anoop2811
design/ @barnettZQG @leejanee @wonderflow @Somefive @jefree-cat @FogDong @anoop2811
# Owner of Core Controllers
pkg/controller/core.oam.dev @Somefive @FogDong @barnettZQG @wonderflow @wangyikewxgm @chivalryq @anoop2811 @dhiguero
pkg/controller/core.oam.dev @Somefive @FogDong @barnettZQG @wonderflow @wangyikewxgm @chivalryq @anoop2811
# Owner of Standard Controllers
pkg/controller/standard.oam.dev @wangyikewxgm @barnettZQG @wonderflow @Somefive @anoop2811 @dhiguero @FogDong
pkg/controller/standard.oam.dev @wangyikewxgm @barnettZQG @wonderflow @Somefive @anoop2811 @FogDong
# Owner of CUE
pkg/cue @leejanee @FogDong @Somefive @anoop2811 @dhiguero
pkg/stdlib @leejanee @FogDong @Somefive @anoop2811 @dhiguero
pkg/cue @leejanee @FogDong @Somefive @anoop2811
pkg/stdlib @leejanee @FogDong @Somefive @anoop2811
# Owner of Workflow
pkg/workflow @leejanee @FogDong @Somefive @wangyikewxgm @chivalryq @anoop2811 @dhiguero
pkg/workflow @leejanee @FogDong @Somefive @wangyikewxgm @chivalryq @anoop2811
# Owner of vela templates
vela-templates/ @Somefive @barnettZQG @wonderflow @FogDong @wangyikewxgm @chivalryq @anoop2811 @dhiguero
vela-templates/ @Somefive @barnettZQG @wonderflow @FogDong @wangyikewxgm @chivalryq @anoop2811
# Owner of vela CLI
references/cli/ @Somefive @StevenLeiZhang @charlie0129 @wangyikewxgm @chivalryq @anoop2811 @dhiguero @FogDong
references/cli/ @Somefive @StevenLeiZhang @charlie0129 @wangyikewxgm @chivalryq @anoop2811 @FogDong
# Owner of vela addon framework
pkg/addon/ @wangyikewxgm @wonderflow @charlie0129 @anoop2811 @dhiguero @FogDong
pkg/addon/ @wangyikewxgm @wonderflow @charlie0129 @anoop2811 @FogDong
# Owner of resource keeper and tracker
pkg/resourcekeeper @Somefive @FogDong @chivalryq @anoop2811 @dhiguero
pkg/resourcetracker @Somefive @FogDong @chivalryq @anoop2811 @dhiguero
pkg/resourcekeeper @Somefive @FogDong @chivalryq @anoop2811
pkg/resourcetracker @Somefive @FogDong @chivalryq @anoop2811
.github/ @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811 @dhiguero
makefiles @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811 @dhiguero
go.* @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811 @dhiguero
.github/ @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811
makefiles @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811
go.* @chivalryq @wonderflow @Somefive @FogDong @wangyikewxgm @anoop2811

View File

@@ -26,12 +26,12 @@ jobs:
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- name: Initialize CodeQL
uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
uses: github/codeql-action/autobuild@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16

View File

@@ -16,10 +16,10 @@ jobs:
core-api-test:
runs-on: ubuntu-22.04
steps:
- name: Set up Go 1.22
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
- name: Set up Go 1.23.8
uses: actions/setup-go@v5
env:
GO_VERSION: '1.22'
GO_VERSION: '1.23.8'
with:
go-version: ${{ env.GO_VERSION }}
id: go

View File

@@ -16,7 +16,7 @@ permissions:
env:
# Common versions
GO_VERSION: '1.22'
GO_VERSION: '1.23.8'
jobs:
definition-doc:

View File

@@ -18,7 +18,7 @@ permissions:
env:
# Common versions
GO_VERSION: '1.22'
GO_VERSION: '1.23.8'
jobs:
@@ -39,7 +39,7 @@ jobs:
continue-on-error: true
e2e-multi-cluster-tests:
runs-on: self-hosted
runs-on: ubuntu-22.04
needs: [ detect-noop ]
if: needs.detect-noop.outputs.noop != 'true'
strategy:

View File

@@ -18,7 +18,7 @@ permissions:
env:
# Common versions
GO_VERSION: '1.22'
GO_VERSION: '1.23.8'
jobs:
@@ -39,7 +39,7 @@ jobs:
continue-on-error: true
e2e-tests:
runs-on: self-hosted
runs-on: ubuntu-22.04
needs: [ detect-noop ]
if: needs.detect-noop.outputs.noop != 'true'
strategy:

View File

@@ -11,16 +11,15 @@ on:
- master
- release-*
permissions: # added using https://github.com/step-security/secure-workflows
permissions: # added using https://github.com/step-security/secure-workflows
contents: read
env:
# Common versions
GO_VERSION: '1.22'
GOLANGCI_VERSION: 'v1.54.2'
GO_VERSION: "1.23.8"
GOLANGCI_VERSION: "v1.60.1"
jobs:
detect-noop:
runs-on: ubuntu-22.04
outputs:
@@ -64,8 +63,8 @@ jobs:
needs: detect-noop
if: needs.detect-noop.outputs.noop != 'true'
permissions:
contents: read # for actions/checkout to fetch code
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
contents: read # for actions/checkout to fetch code
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
steps:
- name: Setup Go
@@ -83,7 +82,7 @@ jobs:
# version, but we prefer this action because it leaves 'annotations' (i.e.
# it comments on PRs to point out linter violations).
- name: Lint
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
uses: golangci/golangci-lint-action@v6
with:
version: ${{ env.GOLANGCI_VERSION }}
@@ -106,10 +105,10 @@ jobs:
- name: Setup node
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
with:
node-version: '14'
node-version: "14"
- name: Cache Go Dependencies
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
uses: actions/cache@v4
with:
path: .work/pkg
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
@@ -128,7 +127,7 @@ jobs:
run: |
export PATH=$(pwd)/bin/:$PATH
make check-diff
- name: Cleanup binary
run: make build-cleanup
@@ -149,7 +148,7 @@ jobs:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go Dependencies
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
uses: actions/cache@v4
with:
path: .work/pkg
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
@@ -174,11 +173,11 @@ jobs:
with:
submodules: true
- name: Set up QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- name: Build Test for vela core
uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: .
file: Dockerfile
@@ -194,11 +193,11 @@ jobs:
with:
submodules: true
- name: Set up QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- name: Build Test for CLI
uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: .
file: Dockerfile.cli
file: Dockerfile.cli

View File

@@ -25,15 +25,15 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
with:
node-version: '14'
cache: 'npm'
node-version: "14"
cache: "npm"
cache-dependency-path: ./actions/package-lock.json
- name: Install Dependencies
run: npm ci --production --prefix ./actions
- name: Run Commands
uses: ./actions/commands
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GH_KUBEVELA_COMMAND_WORKFLOW }}
configPath: issue-commands
backport:

View File

@@ -1,23 +1,45 @@
name: Registry
on:
push:
branches:
- master
tags:
- "v*"
- 'v*'
workflow_dispatch: {}
permissions:
contents: read
jobs:
publish-core-images:
publish-vela-images:
name: Build and Push Vela Images
permissions:
packages: write
id-token: write
attestations: write
contents: write
runs-on: ubuntu-22.04
outputs:
vela_core_image: ${{ steps.meta-vela-core.outputs.image }}
vela_core_digest: ${{ steps.meta-vela-core.outputs.digest }}
vela_core_dockerhub_image: ${{ steps.meta-vela-core.outputs.dockerhub_image }}
vela_cli_image: ${{ steps.meta-vela-cli.outputs.image }}
vela_cli_digest: ${{ steps.meta-vela-cli.outputs.digest }}
vela_cli_dockerhub_image: ${{ steps.meta-vela-cli.outputs.dockerhub_image }}
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- name: Get the version
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.1
- name: Install Crane
uses: imjasonh/setup-crane@00c9e93efa4e1138c9a7a5c594acd6c75a2fbf0c # v0.1
- name: Install Cosign
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # main
with:
cosign-release: 'v2.5.0'
- name: Get the image version
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/}
@@ -25,34 +47,41 @@ jobs:
VERSION=latest
fi
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
- name: Get git revision
id: vars
shell: bash
run: |
echo "git_revision=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Login ghcr.io
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
- name: Login to GHCR
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login docker.io
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
- name: Login to DockerHub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
- uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
- name: Setup QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
with:
driver-opts: image=moby/buildkit:master
- uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
name: Build & Pushing vela-core for Dockerhub, GHCR
- name: Build & Push Vela Core for Dockerhub, GHCR
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: .
file: Dockerfile
labels: |-
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
platforms: linux/amd64,linux/arm64
@@ -61,16 +90,55 @@ jobs:
GITVERSION=git-${{ steps.vars.outputs.git_revision }}
VERSION=${{ steps.get_version.outputs.VERSION }}
GOPROXY=https://proxy.golang.org
tags: |-
tags: |
docker.io/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
- uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
name: Build & Pushing CLI for Dockerhub, GHCR
- name: Get Vela Core Image Digest
id: meta-vela-core
run: |
GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/oamdev/vela-core
DOCKER_IMAGE=docker.io/oamdev/vela-core
TAG=${{ steps.get_version.outputs.VERSION }}
DIGEST=$(crane digest $GHCR_IMAGE:$TAG)
echo "image=$GHCR_IMAGE" >> $GITHUB_OUTPUT
echo "dockerhub_image=$DOCKER_IMAGE" >> $GITHUB_OUTPUT
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
- name: Generate SBOM for Vela Core Image
id: generate_vela_core_sbom
uses: anchore/sbom-action@v0.17.0
with:
image: ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
registry-username: ${{ github.actor }}
registry-password: ${{ secrets.GITHUB_TOKEN }}
format: spdx-json
artifact-name: sbom-vela-core.spdx.json
output-file: ${{ github.workspace }}/sbom-vela-core.spdx.json
- name: Sign Vela Core Image and Attest SBOM
env:
COSIGN_EXPERIMENTAL: 'true'
run: |
echo "signing vela core images..."
cosign sign --yes ghcr.io/${{ github.repository_owner }}/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
cosign sign --yes docker.io/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
echo "attesting SBOM against the vela core image..."
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-core.spdx.json --type spdx \
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-core.spdx.json --type spdx \
docker.io/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
- name: Build & Push Vela CLI for Dockerhub, GHCR
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: .
file: Dockerfile.cli
labels: |-
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
platforms: linux/amd64,linux/arm64
@@ -79,6 +147,100 @@ jobs:
GITVERSION=git-${{ steps.vars.outputs.git_revision }}
VERSION=${{ steps.get_version.outputs.VERSION }}
GOPROXY=https://proxy.golang.org
tags: |-
tags: |
docker.io/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
- name: Get Vela CLI Image Digest
id: meta-vela-cli
run: |
GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli
DOCKER_IMAGE=docker.io/oamdev/vela-cli
TAG=${{ steps.get_version.outputs.VERSION }}
DIGEST=$(crane digest $GHCR_IMAGE:$TAG)
echo "image=$GHCR_IMAGE" >> $GITHUB_OUTPUT
echo "dockerhub_image=$DOCKER_IMAGE" >> $GITHUB_OUTPUT
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
- name: Generate SBOM for Vela CLI Image
id: generate_sbom
uses: anchore/sbom-action@v0.17.0
with:
image: ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
registry-username: ${{ github.actor }}
registry-password: ${{ secrets.GITHUB_TOKEN }}
format: spdx-json
artifact-name: sbom-vela-cli.spdx.json
output-file: ${{ github.workspace }}/sbom-vela-cli.spdx.json
- name: Sign Vela CLI Image and Attest SBOM
env:
COSIGN_EXPERIMENTAL: 'true'
run: |
echo "signing vela CLI images..."
cosign sign --yes ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
cosign sign --yes docker.io/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
echo "attesting SBOM against the vela cli image..."
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-cli.spdx.json --type spdx \
ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-cli.spdx.json --type spdx \
docker.io/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
- name: Publish SBOMs as release artifacts
uses: anchore/sbom-action/publish-sbom@v0.17.0
provenance-ghcr:
name: Generate and Push Provenance to GCHR
needs: publish-vela-images
if: startsWith(github.ref, 'refs/tags/')
strategy:
matrix:
include:
- name: 'Vela Core Image'
image: ${{ needs.publish-vela-images.outputs.vela_core_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_core_digest }}
- name: 'Vela CLI Image'
image: ${{ needs.publish-vela-images.outputs.vela_cli_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_cli_digest }}
permissions:
id-token: write
contents: write
actions: read
packages: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 # has to be sem var
with:
image: ${{ matrix.image }}
digest: ${{ matrix.digest }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
provenance-dockerhub:
name: Generate and Push Provenance to DockerHub
needs: publish-vela-images
if: startsWith(github.ref, 'refs/tags/')
strategy:
matrix:
include:
- name: 'Vela Core Image'
image: ${{ needs.publish-vela-images.outputs.vela_core_dockerhub_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_core_digest }}
- name: 'Vela CLI Image'
image: ${{ needs.publish-vela-images.outputs.vela_cli_dockerhub_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_cli_digest }}
permissions:
id-token: write
contents: write
packages: write
actions: read
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: ${{ matrix.image }}
digest: ${{ matrix.digest }}
registry-username: oamdev
secrets:
registry-password: ${{ secrets.DOCKER_PASSWORD }}

View File

@@ -3,14 +3,16 @@ name: Release
on:
push:
tags:
- "v*"
workflow_dispatch: { }
- 'v*'
workflow_dispatch: {}
permissions:
contents: read
jobs:
build:
goreleaser:
name: goreleaser
runs-on: ubuntu-22.04
permissions:
contents: write
actions: read
@@ -20,27 +22,54 @@ jobs:
pull-requests: read
repository-projects: read
statuses: read
runs-on: ubuntu-22.04
name: goreleaser
id-token: write
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
with:
fetch-depth: 0
- run: git fetch --force --tags
- name: Get Git tags
run: git fetch --force --tags
- name: Set up Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
with:
go-version: 1.22
go-version: 1.23.8
cache: true
- uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
- name: Install Cosign
uses: sigstore/cosign-installer@main
with:
cosign-release: 'v2.5.0'
- name: Install syft
uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
with:
distribution: goreleaser
version: 1.14.1
args: release --rm-dist --timeout 60m
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate hashes
id: hash
if: startsWith(github.ref, 'refs/tags/')
run: |
set -euo pipefail
HASHES=$(find dist -type f -exec sha256sum {} \; | base64 -w0)
echo "hashes=$HASHES" >> "$GITHUB_OUTPUT"
upload-plugin-homebrew:
name: upload-sha256sums
needs: goreleaser
runs-on: ubuntu-22.04
if: ${{ !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') }}
permissions:
contents: write
actions: read
@@ -50,10 +79,6 @@ jobs:
pull-requests: read
repository-projects: read
statuses: read
needs: build
runs-on: ubuntu-22.04
if: ${{ !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') }}
name: upload-sha256sums
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
@@ -67,3 +92,16 @@ jobs:
tag: ${{ github.ref }}
revision: ${{ github.sha }}
force: false
provenance-vela-bins:
name: generate provenance for binaries
needs: [goreleaser]
if: startsWith(github.ref, 'refs/tags/')
permissions:
id-token: write
contents: write
actions: read
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 # has to be sem var
with:
base64-subjects: '${{ needs.goreleaser.outputs.hashes }}'
upload-assets: true

View File

@@ -28,7 +28,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # tag=v2.3.1
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # tag=v2.4.1
with:
results_file: results.sarif
results_format: sarif
@@ -47,7 +47,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@134dcf33c0b9454c4b17a936843d7e21dccdc335 # v4.3.6
with:
name: SARIF file
path: results.sarif
@@ -55,6 +55,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
with:
sarif_file: results.sarif

View File

@@ -18,8 +18,8 @@ permissions:
env:
# Common versions
GO_VERSION: '1.22'
GOLANGCI_VERSION: 'v1.54.2'
GO_VERSION: '1.23.8'
GOLANGCI_VERSION: 'v1.60.1'
jobs:
sdk-tests:

View File

@@ -11,7 +11,7 @@ permissions:
contents: read
env:
GO_VERSION: '1.22'
GO_VERSION: '1.23.8'
jobs:
sync-core-api:

View File

@@ -15,7 +15,7 @@ permissions:
contents: read
env:
GO_VERSION: '1.22'
GO_VERSION: '1.23.8'
jobs:
sync_sdk:

View File

@@ -27,7 +27,7 @@ jobs:
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@366883a76d75dcee5428da5c3ae7abf9386e35ac # v2.26.2
uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
if: always()
with:
sarif_file: 'trivy-results.sarif'

View File

@@ -5,7 +5,7 @@ on:
branches:
- master
- release-*
workflow_dispatch: { }
workflow_dispatch: {}
pull_request:
branches:
- master
@@ -16,13 +16,12 @@ permissions:
env:
# Common versions
GO_VERSION: '1.22'
GO_VERSION: "1.23.8"
jobs:
detect-noop:
permissions:
actions: write # for fkirc/skip-duplicate-actions to skip or stop workflow runs
actions: write # for fkirc/skip-duplicate-actions to skip or stop workflow runs
runs-on: ubuntu-22.04
outputs:
noop: ${{ steps.noop.outputs.should_skip }}
@@ -53,7 +52,7 @@ jobs:
submodules: true
- name: Cache Go Dependencies
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
uses: actions/cache@v4
with:
path: .work/pkg
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}

View File

@@ -1,18 +1,6 @@
run:
timeout: 10m
skip-files:
- "zz_generated\\..+\\.go$"
- ".*_test.go$"
skip-dirs:
- "hack"
- "e2e"
output:
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
format: colored-line-number
linters-settings:
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
@@ -23,24 +11,12 @@ linters-settings:
# default is false: such cases aren't reported by default.
check-blank: false
# [deprecated] comma-separated list of pairs of the form pkg:regex
# the regex is used to ignore names within pkg. (default "fmt:.*").
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
ignore: fmt:.*,io/ioutil:^Read.*
exhaustive:
# indicates that switch statements are to be considered exhaustive if a
# 'default' case is present, even if all enum members aren't listed in the
# switch
default-signifies-exhaustive: true
govet:
# report about shadowed variables
check-shadowing: false
revive:
# minimal confidence for issues, default is 0.8
min-confidence: 0.8
gofmt:
# simplify code: gofmt with `-s` option, true by default
@@ -55,9 +31,6 @@ linters-settings:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
dupl:
# tokens count to trigger issue, 150 by default
@@ -73,13 +46,6 @@ linters-settings:
# tab width in spaces. Default to 1.
tab-width: 1
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
@@ -107,9 +73,13 @@ linters-settings:
# Allow only slices initialized with a length of zero. Default is false.
always: false
revive:
rules:
- name: unused-parameter
disabled: true
linters:
enable:
- megacheck
- govet
- gocyclo
- gocritic
@@ -121,11 +91,10 @@ linters:
- misspell
- nakedret
- exportloopref
- unused
- gosimple
- staticcheck
disable:
- deadcode
- scopelint
- structcheck
- varcheck
- rowserrcheck
- sqlclosecheck
- errchkjson
@@ -137,8 +106,28 @@ linters:
issues:
exclude-files:
- "zz_generated\\..+\\.go$"
- ".*_test.go$"
exclude-dirs:
- "hack"
- "e2e"
# Excluding configuration per-path and per-linter
exclude-rules:
- path: .*\.go
linters:
- errcheck
text: "fmt\\."
# Ignore unchecked errors from io/ioutil functions starting with Read
- path: .*\.go
linters:
- errcheck
text: "io/ioutil.*Read"
# Exclude some linters from running on tests files.
- path: _test(ing)?\.go
linters:
@@ -227,7 +216,7 @@ issues:
new: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-per-linter: 0
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
max-same-issues: 0

View File

@@ -31,6 +31,28 @@ builds:
ldflags:
- -s -w -X github.com/oam-dev/kubevela/version.VelaVersion={{ .Version }} -X github.com/oam-dev/kubevela/version.GitRevision=git-{{.ShortCommit}}
sboms:
- id: kubevela-binaries-sboms
artifacts: binary
documents:
- "${artifact}-{{ .Version }}-{{ .Os }}-{{ .Arch }}.spdx.sbom.json"
signs:
- id: kubevela-cosign-keyless
artifacts: checksum # sign the checksum file over individual artifacts
signature: "${artifact}-keyless.sig"
certificate: "${artifact}-keyless.pem"
cmd: cosign
args:
- "sign-blob"
- "--yes"
- "--output-signature"
- "${artifact}-keyless.sig"
- "--output-certificate"
- "${artifact}-keyless.pem"
- "${artifact}"
output: true
archives:
- format: tar.gz
id: vela-cli-tgz

View File

@@ -1,6 +1,6 @@
ARG BASE_IMAGE
# Build the manager binary
FROM golang:1.22-alpine3.18 as builder
FROM golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1 AS builder
WORKDIR /workspace
# Copy the Go Modules manifests

View File

@@ -1,6 +1,6 @@
ARG BASE_IMAGE
# Build the cli binary
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22-alpine@sha256:d1a601b64de09e2fa38c95e55838961811d5ca11062a8f4230a5c434b3ae2a34 as builder
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1 AS builder
ARG GOPROXY
ENV GOPROXY=${GOPROXY:-https://proxy.golang.org}
WORKDIR /workspace

View File

@@ -1,6 +1,6 @@
ARG BASE_IMAGE
# Build the manager binary
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22-alpine@sha256:d1a601b64de09e2fa38c95e55838961811d5ca11062a8f4230a5c434b3ae2a34 as builder
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1 AS builder
WORKDIR /workspace
# Copy the Go Modules manifests

View File

@@ -61,7 +61,7 @@ staticcheck: staticchecktool
## lint: Run the golangci-lint
lint: golangci
@$(INFO) lint
@$(GOLANGCILINT) run --fix --verbose --skip-dirs 'scaffold'
@$(GOLANGCILINT) run --fix --verbose --exclude-dirs 'scaffold'
## reviewable: Run the reviewable
reviewable: manifests fmt vet lint staticcheck helm-doc-gen sdk_fmt

View File

@@ -59,6 +59,14 @@ and share the large growing community [addons](https://kubevela.net/docs/referen
* [Installation](https://kubevela.io/docs/install)
* [Deploy Your Application](https://kubevela.io/docs/quick-start)
### Get Your Own Demo with Alibaba Cloud
- install KubeVela on a Serverless K8S cluster in 3 minutes, try:
<a href="https://acs.console.aliyun.com/quick-deploy?repo=kubevela/kubevela&branch=master" target="_blank">
<img src="https://img.alicdn.com/imgextra/i1/O1CN01aiPSuA1Wiz7wkgF5u_!!6000000002823-55-tps-399-70.svg" width="200" alt="Deploy on Alibaba Cloud">
</a>
## Documentation
Full documentation is available on the [KubeVela website](https://kubevela.io/).

View File

@@ -102,16 +102,16 @@ func (in *GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstruct
}
// FindDeleteOption find delete option for target resource
func (in *GarbageCollectPolicySpec) FindDeleteOption(manifest *unstructured.Unstructured) []client.DeleteOption {
func (in *GarbageCollectPolicySpec) FindDeleteOption(manifest *unstructured.Unstructured) (bool, []client.DeleteOption) {
for _, rule := range in.Rules {
if rule.Selector.Match(manifest) && rule.Propagation != nil {
switch *rule.Propagation {
case GarbageCollectPropagationOrphan:
return []client.DeleteOption{client.PropagationPolicy(metav1.DeletePropagationOrphan)}
return true, []client.DeleteOption{client.PropagationPolicy(metav1.DeletePropagationOrphan)}
case GarbageCollectPropagationCascading:
return []client.DeleteOption{client.PropagationPolicy(metav1.DeletePropagationBackground)}
return false, []client.DeleteOption{client.PropagationPolicy(metav1.DeletePropagationBackground)}
}
}
}
return nil
return false, nil
}

View File

@@ -27,6 +27,9 @@ import (
// ComponentDefinitionSpec defines the desired state of ComponentDefinition
type ComponentDefinitionSpec struct {
// +optional
Version string `json:"version,omitempty"`
// Workload is a workload type descriptor
Workload common.WorkloadTypeDescriptor `json:"workload"`

View File

@@ -164,6 +164,9 @@ type TraitDefinitionSpec struct {
// pre-process and post-process respectively.
// +optional
Stage StageType `json:"stage,omitempty"`
// +optional
Version string `json:"version,omitempty"`
}
// StageType describes how the manifests should be dispatched.

View File

@@ -37,6 +37,9 @@ type PolicyDefinitionSpec struct {
// ManageHealthCheck means the policy will handle health checking and skip application controller
// built-in health checking.
ManageHealthCheck bool `json:"manageHealthCheck,omitempty"`
//+optional
Version string `json:"version,omitempty"`
}
// PolicyDefinitionStatus is the status of PolicyDefinition

View File

@@ -33,6 +33,9 @@ type WorkflowStepDefinitionSpec struct {
// Only CUE schematic is supported for now.
// +optional
Schematic *common.Schematic `json:"schematic,omitempty"`
// +optional
Version string `json:"version,omitempty"`
}
// WorkflowStepDefinitionStatus is the status of WorkflowStepDefinition

View File

@@ -102,23 +102,25 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
### MultiCluster parameters
| Name | Description | Value |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------- |
| `multicluster.enabled` | Whether to enable multi-cluster | `true` |
| `multicluster.metrics.enabled` | Whether to enable multi-cluster metrics collect | `false` |
| `multicluster.clusterGateway.direct` | controller will connect to ClusterGateway directly instead of going to Kubernetes APIServer | `true` |
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.9.0-alpha.2` |
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
| `multicluster.clusterGateway.resources.requests.cpu` | ClusterGateway cpu request | `50m` |
| `multicluster.clusterGateway.resources.requests.memory` | ClusterGateway memory request | `20Mi` |
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `500m` |
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |
| `multicluster.clusterGateway.secureTLS.enabled` | Whether to enable secure TLS | `true` |
| `multicluster.clusterGateway.secureTLS.certPath` | Path to the certificate file | `/etc/k8s-cluster-gateway-certs` |
| `multicluster.clusterGateway.secureTLS.certManager.enabled` | Whether to enable cert-manager | `false` |
| Name | Description | Value |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------- |
| `multicluster.enabled` | Whether to enable multi-cluster | `true` |
| `multicluster.metrics.enabled` | Whether to enable multi-cluster metrics collect | `false` |
| `multicluster.clusterGateway.direct` | controller will connect to ClusterGateway directly instead of going to Kubernetes APIServer | `true` |
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.9.0-alpha.2` |
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
| `multicluster.clusterGateway.resources.requests.cpu` | ClusterGateway cpu request | `50m` |
| `multicluster.clusterGateway.resources.requests.memory` | ClusterGateway memory request | `20Mi` |
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `500m` |
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |
| `multicluster.clusterGateway.secureTLS.enabled` | Whether to enable secure TLS | `true` |
| `multicluster.clusterGateway.secureTLS.certPath` | Path to the certificate file | `/etc/k8s-cluster-gateway-certs` |
| `multicluster.clusterGateway.secureTLS.certManager.enabled` | Whether to enable cert-manager | `false` |
| `multicluster.clusterGateway.serviceMonitor.enabled` | Whether to enable service monitor | `false` |
| `multicluster.clusterGateway.serviceMonitor.additionalLabels` | Additional labels for service monitor | `{}` |
### Test parameters
@@ -131,29 +133,32 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
### Common parameters
| Name | Description | Value |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Override name | `""` |
| `fullnameOverride` | Fullname override | `""` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | Tolerations | `[]` |
| `affinity` | Affinity | `{}` |
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
| `logDebug` | Enable debug logs for development purpose | `false` |
| `logFilePath` | If non-empty, write log files in this path | `""` |
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
| `kubeClient.qps` | The qps for reconcile clients | `400` |
| `kubeClient.burst` | The burst for reconcile clients | `600` |
| `authentication.enabled` | Enable authentication for application | `false` |
| `authentication.withUser` | Application authentication will impersonate as the request User | `true` |
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |
| `sharding.enabled` | When sharding enabled, the controller will run as master mode. Refer to https://github.com/kubevela/kubevela/blob/master/design/vela-core/sharding.md for details. | `false` |
| `sharding.schedulableShards` | The shards available for scheduling. If empty, dynamic discovery will be used. | `""` |
| Name | Description | Value |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Override name | `""` |
| `fullnameOverride` | Fullname override | `""` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | Tolerations | `[]` |
| `affinity` | Affinity | `{}` |
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
| `logDebug` | Enable debug logs for development purpose | `false` |
| `logFilePath` | If non-empty, write log files in this path | `""` |
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
| `kubeClient.qps` | The qps for reconcile clients | `400` |
| `kubeClient.burst` | The burst for reconcile clients | `600` |
| `authentication.enabled` | Enable authentication for application | `false` |
| `authentication.withUser` | Application authentication will impersonate as the request User | `true` |
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |
| `sharding.enabled` | When sharding enabled, the controller will run as master mode. Refer to https://github.com/kubevela/kubevela/blob/master/design/vela-core/sharding.md for details. | `false` |
| `sharding.schedulableShards` | The shards available for scheduling. If empty, dynamic discovery will be used. | `""` |
| `core.metrics.enabled` | Enable metrics for vela-core | `false` |
| `core.metrics.serviceMonitor.enabled` | Enable service monitor for metrics | `false` |
| `core.metrics.serviceMonitor.additionalLabels` | Additional labels for service monitor | `{}` |
## Uninstallation

View File

@@ -1053,6 +1053,8 @@ spec:
for the abstraction
type: string
type: object
version:
type: string
workload:
description: Workload is a workload type descriptor
properties:
@@ -1356,6 +1358,8 @@ spec:
- configuration
type: object
type: object
version:
type: string
type: object
status:
description: PolicyDefinitionStatus is the status of PolicyDefinition
@@ -1651,6 +1655,8 @@ spec:
for the abstraction
type: string
type: object
version:
type: string
workloadRefPath:
description: WorkloadRefPath indicates where/if a trait
accepts a workloadRef object
@@ -2059,6 +2065,8 @@ spec:
- configuration
type: object
type: object
version:
type: string
type: object
status:
description: WorkflowStepDefinitionStatus is the status of WorkflowStepDefinition

View File

@@ -195,6 +195,8 @@ spec:
the abstraction
type: string
type: object
version:
type: string
workload:
description: Workload is a workload type descriptor
properties:

View File

@@ -241,6 +241,8 @@ spec:
for the abstraction
type: string
type: object
version:
type: string
workload:
description: Workload is a workload type descriptor
properties:
@@ -489,6 +491,8 @@ spec:
- configuration
type: object
type: object
version:
type: string
type: object
status:
description: PolicyDefinitionStatus is the status of PolicyDefinition
@@ -774,6 +778,8 @@ spec:
for the abstraction
type: string
type: object
version:
type: string
workloadRefPath:
description: WorkloadRefPath indicates where/if a trait accepts
a workloadRef object
@@ -992,6 +998,8 @@ spec:
- configuration
type: object
type: object
version:
type: string
type: object
status:
description: WorkflowStepDefinitionStatus is the status of WorkflowStepDefinition

View File

@@ -156,6 +156,8 @@ spec:
- configuration
type: object
type: object
version:
type: string
type: object
status:
description: PolicyDefinitionStatus is the status of PolicyDefinition

View File

@@ -225,6 +225,8 @@ spec:
the abstraction
type: string
type: object
version:
type: string
workloadRefPath:
description: WorkloadRefPath indicates where/if a trait accepts a
workloadRef object

View File

@@ -152,6 +152,8 @@ spec:
- configuration
type: object
type: object
version:
type: string
type: object
status:
description: WorkflowStepDefinitionStatus is the status of WorkflowStepDefinition

View File

@@ -2,7 +2,7 @@
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "kubevela.fullname" . }}-admission-create
name: {{ template "kubevela.fullname" . }}-admission-create
namespace: {{ .Release.Namespace }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
@@ -17,7 +17,7 @@ spec:
{{- end }}
template:
metadata:
name: {{ template "kubevela.fullname" . }}-admission-create
name: {{ template "kubevela.fullname" . }}-admission-create
labels:
app: {{ template "kubevela.name" . }}-admission-create
{{- include "kubevela.labels" . | nindent 8 }}
@@ -39,17 +39,26 @@ spec:
- --cert-name=tls.crt
restartPolicy: OnFailure
serviceAccountName: {{ template "kubevela.fullname" . }}-admission
{{- with .Values.admissionWebhooks.patch.nodeSelector }}
{{- if .Values.admissionWebhooks.patch.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- toYaml .Values.admissionWebhooks.patch.nodeSelector | nindent 8 }}
{{- else if .Values.nodeSelector }}
nodeSelector:
{{- toYaml .Values.nodeSelector | nindent 8 }}
{{- end }}
{{- with .Values.admissionWebhooks.patch.affinity }}
{{- if .Values.admissionWebhooks.patch.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- toYaml .Values.admissionWebhooks.patch.affinity | nindent 8 }}
{{- else if .Values.affinity }}
affinity:
{{- toYaml .Values.affinity | nindent 8 }}
{{- end }}
{{- with .Values.admissionWebhooks.patch.tolerations }}
{{- if .Values.admissionWebhooks.patch.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- toYaml .Values.admissionWebhooks.patch.tolerations | nindent 8 }}
{{- else if .Values.tolerations }}
tolerations:
{{- toYaml .Values.tolerations | nindent 8 }}
{{- end }}
securityContext:
runAsGroup: 2000

View File

@@ -2,7 +2,7 @@
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "kubevela.fullname" . }}-admission-patch
name: {{ template "kubevela.fullname" . }}-admission-patch
namespace: {{ .Release.Namespace }}
annotations:
"helm.sh/hook": post-install,post-upgrade
@@ -17,7 +17,7 @@ spec:
{{- end }}
template:
metadata:
name: {{ template "kubevela.fullname" . }}-admission-patch
name: {{ template "kubevela.fullname" . }}-admission-patch
labels:
app: {{ template "kubevela.name" . }}-admission-patch
{{- include "kubevela.labels" . | nindent 8 }}
@@ -41,13 +41,26 @@ spec:
{{- end }}
restartPolicy: OnFailure
serviceAccountName: {{ template "kubevela.fullname" . }}-admission
{{- with .Values.admissionWebhooks.patch.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- if .Values.admissionWebhooks.patch.nodeSelector }}
nodeSelector:
{{- toYaml .Values.admissionWebhooks.patch.nodeSelector | nindent 8 }}
{{- else if .Values.nodeSelector }}
nodeSelector:
{{- toYaml .Values.nodeSelector | nindent 8 }}
{{- end }}
{{- with .Values.admissionWebhooks.patch.tolerations }}
{{- if .Values.admissionWebhooks.patch.affinity }}
affinity:
{{- toYaml .Values.admissionWebhooks.patch.affinity | nindent 8 }}
{{- else if .Values.affinity }}
affinity:
{{- toYaml .Values.affinity | nindent 8 }}
{{- end }}
{{- if .Values.admissionWebhooks.patch.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- toYaml .Values.admissionWebhooks.patch.tolerations | nindent 8 }}
{{- else if .Values.tolerations }}
tolerations:
{{- toYaml .Values.tolerations | nindent 8 }}
{{- end }}
securityContext:
runAsGroup: 2000

View File

@@ -14,13 +14,13 @@ webhooks:
service:
name: {{ template "kubevela.name" . }}-webhook
namespace: {{ .Release.Namespace }}
path: /validating-core-oam-dev-v1alpha2-traitdefinitions
path: /validating-core-oam-dev-v1beta1-traitdefinitions
{{- if .Values.admissionWebhooks.patch.enabled }}
failurePolicy: Ignore
{{- else }}
failurePolicy: {{ .Values.admissionWebhooks.failurePolicy }}
{{- end }}
name: validating.core.oam.dev.v1alpha2.traitdefinitions
name: validating.core.oam.dev.v1beta1.traitdefinitions
sideEffects: None
admissionReviewVersions:
- v1beta1
@@ -35,7 +35,6 @@ webhooks:
- UPDATE
resources:
- traitdefinitions
scope: Cluster
timeoutSeconds: 5
- clientConfig:
caBundle: Cg==

View File

@@ -124,6 +124,7 @@ spec:
- protocol: TCP
port: {{ .Values.multicluster.clusterGateway.port }}
targetPort: {{ .Values.multicluster.clusterGateway.port }}
name: default
---
# 1. Check whether APIService ""v1alpha1.cluster.core.oam.dev" is already present in the cluster
# 2.a If the APIService doesn't exist, create it.
@@ -189,4 +190,4 @@ subjects:
- kind: ServiceAccount
name: {{ include "kubevela.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{ end }}
{{ end }}

View File

@@ -95,6 +95,18 @@ spec:
runAsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
---
apiVersion: batch/v1
kind: Job
@@ -138,4 +150,16 @@ spec:
runAsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
{{ end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{ end }}

View File

@@ -0,0 +1,59 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/podsecuritycontext.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Adds security context to the pod spec in path 'spec.template.spec.securityContext'.
name: podsecuritycontext
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:
template: |
patch: spec: template: spec: securityContext: {
if parameter.appArmorProfile != _|_ {
appArmorProfile: parameter.appArmorProfile
}
if parameter.fsGroup != _|_ {
fsGroup: parameter.fsGroup
}
if parameter.runAsGroup != _|_ {
runAsGroup: parameter.runAsGroup
}
if parameter.runAsUser != _|_ {
runAsUser: parameter.runAsUser
}
if parameter.seccompProfile != _|_ {
seccompProfile: parameter.seccompProfile
}
runAsNonRoot: parameter.runAsNonRoot
}
parameter: {
// +usage=Specify the AppArmor profile for the pod
appArmorProfile?: {
type: "RuntimeDefault" | "Unconfined" | "Localhost"
// +usage: localhostProfile is required when type is 'Localhost'
localhostProfile?: string
}
fsGroup?: int
runAsGroup?: int
// +usage=Specify the UID to run the entrypoint of the container process
runAsUser?: int
// +usage=Specify if the container runs as a non-root user
runAsNonRoot: *true | bool
// +usage=Specify the seccomp profile for the pod
seccompProfile?: {
type: "RuntimeDefault" | "Unconfined" | "Localhost"
// +usage: localhostProfile is required when type is 'Localhost'
localhostProfile?: string
}
}

View File

@@ -0,0 +1,107 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/securitycontext.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Adds security context to the container spec in path 'spec.template.spec.containers.[].securityContext'.
name: securitycontext
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:
template: |
#PatchParams: {
// +usage=Specify the name of the target container, if not set, use the component name
containerName: *"" | string
addCapabilities?: [...string]
allowPrivilegeEscalation: *false | bool
dropCapabilities?: [...string]
privileged: *false | bool
readOnlyRootFilesystem: *false | bool
runAsNonRoot: *true | bool
runAsUser?: int
runAsGroup?: int
}
PatchContainer: {
_params: #PatchParams
name: _params.containerName
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [for _container_ in _baseContainers if _container_.name == name {_container_}]
_baseContainer: *_|_ | {...}
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
}
if len(_matchContainers_) > 0 {
securityContext: {
capabilities: {
if _params.addCapabilities != _|_ {
add: _params.addCapabilities
}
if _params.dropCapabilities != _|_ {
drop: _params.dropCapabilities
}
}
if _params.runAsUser != _|_ {
runAsUser: _params.runAsUser
}
if _params.runAsGroup != _|_ {
runAsGroup: _params.runAsGroup
}
allowPrivilegeEscalation: _params.allowPrivilegeEscalation
readOnlyRootFilesystem: _params.readOnlyRootFilesystem
privileged: _params.privileged
runAsNonRoot: _params.runAsNonRoot
}
}
}
patch: spec: template: spec: {
if parameter.containers == _|_ {
// +patchKey=name
containers: [{
PatchContainer & {_params: {
if parameter.containerName == "" {
containerName: context.name
}
if parameter.containerName != "" {
containerName: parameter.containerName
}
allowPrivilegeEscalation: parameter.allowPrivilegeEscalation
readOnlyRootFilesystem: parameter.readOnlyRootFilesystem
privileged: parameter.privileged
runAsNonRoot: parameter.runAsNonRoot
runAsUser: parameter.runAsUser
runAsGroup: parameter.runAsGroup
addCapabilities: parameter.addCapabilities
dropCapabilities: parameter.dropCapabilities
}}
}]
}
if parameter.containers != _|_ {
// +patchKey=name
containers: [for c in parameter.containers {
if c.containerName == "" {
err: "containerName must be set for containers"
}
if c.containerName != "" {
PatchContainer & {_params: c}
}
}]
}
}
parameter: #PatchParams | close({
// +usage=Specify the container image for multiple containers
containers: [...#PatchParams]
})
errs: [for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]

View File

@@ -98,9 +98,6 @@ spec:
if _params.periodSeconds != _|_ {
periodSeconds: _params.periodSeconds
}
if _params.tcpSocket != _|_ {
tcpSocket: _params.tcpSocket
}
if _params.timeoutSeconds != _|_ {
timeoutSeconds: _params.timeoutSeconds
}

View File

@@ -0,0 +1,605 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/statefulset.cue
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
annotations:
definition.oam.dev/description: Describes long-running, scalable, containerized services used to manage stateful application, like database.
name: statefulset
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
schematic:
cue:
template: |
import (
"strconv"
"strings"
)
mountsArray: [
if parameter.volumeMounts != _|_ if parameter.volumeMounts.pvc != _|_ for v in parameter.volumeMounts.pvc {
{
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.configMap != _|_ for v in parameter.volumeMounts.configMap {
{
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.secret != _|_ for v in parameter.volumeMounts.secret {
{
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.emptyDir != _|_ for v in parameter.volumeMounts.emptyDir {
{
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.hostPath != _|_ for v in parameter.volumeMounts.hostPath {
{
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
]
volumesList: [
if parameter.volumeMounts != _|_ if parameter.volumeMounts.pvc != _|_ for v in parameter.volumeMounts.pvc {
{
name: v.name
persistentVolumeClaim: claimName: v.claimName
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.configMap != _|_ for v in parameter.volumeMounts.configMap {
{
name: v.name
configMap: {
defaultMode: v.defaultMode
name: v.cmName
if v.items != _|_ {
items: v.items
}
}
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.secret != _|_ for v in parameter.volumeMounts.secret {
{
name: v.name
secret: {
defaultMode: v.defaultMode
secretName: v.secretName
if v.items != _|_ {
items: v.items
}
}
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.emptyDir != _|_ for v in parameter.volumeMounts.emptyDir {
{
name: v.name
emptyDir: medium: v.medium
}
},
if parameter.volumeMounts != _|_ if parameter.volumeMounts.hostPath != _|_ for v in parameter.volumeMounts.hostPath {
{
name: v.name
hostPath: path: v.path
}
},
]
deDupVolumesArray: [
for val in [
for i, vi in volumesList {
for j, vj in volumesList if j < i && vi.name == vj.name {
_ignore: true
}
vi
},
] if val._ignore == _|_ {
val
},
]
output: {
apiVersion: "apps/v1"
kind: "StatefulSet"
spec: {
selector: matchLabels: "app.oam.dev/component": context.name
template: {
metadata: {
labels: {
if parameter.labels != _|_ {
parameter.labels
}
if parameter.addRevisionLabel {
"app.oam.dev/revision": context.revision
}
"app.oam.dev/name": context.appName
"app.oam.dev/component": context.name
}
if parameter.annotations != _|_ {
annotations: parameter.annotations
}
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["port"] != _|_ if parameter["ports"] == _|_ {
ports: [{
containerPort: parameter.port
}]
}
if parameter["ports"] != _|_ {
ports: [for v in parameter.ports {
{
containerPort: {
if v.containerPort != _|_ {v.containerPort}
if v.containerPort == _|_ {v.port}
}
protocol: v.protocol
if v.name != _|_ {
name: v.name
}
if v.name == _|_ {
_name: {
if v.containerPort != _|_ {"port-" + strconv.FormatInt(v.containerPort, 10)}
if v.containerPort == _|_ {"port-" + strconv.FormatInt(v.port, 10)}
}
name: *_name | string
if v.protocol != "TCP" {
name: _name + "-" + strings.ToLower(v.protocol)
}
}
}}]
}
if parameter["imagePullPolicy"] != _|_ {
imagePullPolicy: parameter.imagePullPolicy
}
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
if parameter["args"] != _|_ {
args: parameter.args
}
if parameter["env"] != _|_ {
env: parameter.env
}
if context["config"] != _|_ {
env: context.config
}
if parameter["cpu"] != _|_ {
resources: {
limits: cpu: parameter.cpu
requests: cpu: parameter.cpu
}
}
if parameter["memory"] != _|_ {
resources: {
limits: memory: parameter.memory
requests: memory: parameter.memory
}
}
if parameter["volumes"] != _|_ if parameter["volumeMounts"] == _|_ {
volumeMounts: [for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
}}]
}
if parameter["volumeMounts"] != _|_ {
volumeMounts: mountsArray
}
if parameter["livenessProbe"] != _|_ {
livenessProbe: parameter.livenessProbe
}
if parameter["readinessProbe"] != _|_ {
readinessProbe: parameter.readinessProbe
}
}]
if parameter["hostAliases"] != _|_ {
// +patchKey=ip
hostAliases: parameter.hostAliases
}
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [for v in parameter.imagePullSecrets {
name: v
},
]
}
if parameter["volumes"] != _|_ if parameter["volumeMounts"] == _|_ {
volumes: [for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {
persistentVolumeClaim: claimName: v.claimName
}
if v.type == "configMap" {
configMap: {
defaultMode: v.defaultMode
name: v.cmName
if v.items != _|_ {
items: v.items
}
}
}
if v.type == "secret" {
secret: {
defaultMode: v.defaultMode
secretName: v.secretName
if v.items != _|_ {
items: v.items
}
}
}
if v.type == "emptyDir" {
emptyDir: medium: v.medium
}
}
}]
}
if parameter["volumeMounts"] != _|_ {
volumes: deDupVolumesArray
}
}
}
}
}
exposePorts: [
if parameter.ports != _|_ for v in parameter.ports if v.expose == true {
port: v.port
if v.containerPort != _|_ {targetPort: v.containerPort}
if v.containerPort == _|_ {targetPort: v.port}
if v.name != _|_ {name: v.name}
if v.name == _|_ {
_name: {
if v.containerPort != _|_ {
"port-" + strconv.FormatInt(v.containerPort, 10)
}
if v.containerPort == _|_ {
"port-" + strconv.FormatInt(v.port, 10)
}
}
name: *_name | string
if v.protocol != "TCP" {
name: _name + "-" + strings.ToLower(v.protocol)
}
}
if v.nodePort != _|_ if parameter.exposeType == "NodePort" {
nodePort: v.nodePort
}
if v.protocol != _|_ {
protocol: v.protocol
}
},
]
outputs: {
if len(exposePorts) != 0 {
statefulsetsExpose: {
apiVersion: "v1"
kind: "Service"
metadata: name: context.name
spec: {
selector: "app.oam.dev/component": context.name
ports: exposePorts
type: parameter.exposeType
}
}
}
}
parameter: {
// +usage=Specify the labels in the workload
labels?: [string]: string
// +usage=Specify the annotations in the workload
annotations?: [string]: string
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Specify image pull policy for your service
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
// +usage=Specify image pull secrets for your service
imagePullSecrets?: [...string]
// +ignore
// +usage=Deprecated field, please use ports instead
// +short=p
port?: int
// +usage=Which ports do you want customer traffic sent to, defaults to 80
ports?: [...{
// +usage=Number of port to expose on the pod's IP address
port: int
// +usage=Number of container port to connect to, defaults to port
containerPort?: int
// +usage=Name of the port
name?: string
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
protocol: *"TCP" | "UDP" | "SCTP"
// +usage=Specify if the port should be exposed
expose: *false | bool
// +usage=exposed node port. Only Valid when exposeType is NodePort
nodePort?: int
}]
// +ignore
// +usage=Specify what kind of Service you want. options: "ClusterIP", "NodePort", "LoadBalancer"
exposeType: *"ClusterIP" | "NodePort" | "LoadBalancer"
// +ignore
// +usage=If addRevisionLabel is true, the revision label will be added to the underlying pods
addRevisionLabel: *false | bool
// +usage=Commands to run in the container
cmd?: [...string]
// +usage=Arguments to the entrypoint
args?: [...string]
// +usage=Define arguments by using environment variables
env?: [...{
// +usage=Environment variable name
name: string
// +usage=The value of the environment variable
value?: string
// +usage=Specifies a source the value of this var should come from
valueFrom?: {
// +usage=Selects a key of a secret in the pod's namespace
secretKeyRef?: {
// +usage=The name of the secret in the pod's namespace to select from
name: string
// +usage=The key of the secret to select from. Must be a valid secret key
key: string
}
// +usage=Selects a key of a config map in the pod's namespace
configMapKeyRef?: {
// +usage=The name of the config map in the pod's namespace to select from
name: string
// +usage=The key of the config map to select from. Must be a valid secret key
key: string
}
}
}]
// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
cpu?: string
// +usage=Specifies the attributes of the memory resource required for the container.
memory?: string
volumeMounts?: {
// +usage=Mount PVC type volume
pvc?: [...{
name: string
mountPath: string
subPath?: string
// +usage=The name of the PVC
claimName: string
}]
// +usage=Mount ConfigMap type volume
configMap?: [...{
name: string
mountPath: string
subPath?: string
defaultMode: *420 | int
cmName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}]
// +usage=Mount Secret type volume
secret?: [...{
name: string
mountPath: string
subPath?: string
defaultMode: *420 | int
secretName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}]
// +usage=Mount EmptyDir type volume
emptyDir?: [...{
name: string
mountPath: string
subPath?: string
medium: *"" | "Memory"
}]
// +usage=Mount HostPath type volume
hostPath?: [...{
name: string
mountPath: string
subPath?: string
path: string
}]
}
// +usage=Deprecated field, use volumeMounts instead.
volumes?: [...{
name: string
mountPath: string
// +usage=Specify volume type, options: "pvc","configMap","secret","emptyDir", default to emptyDir
type: *"emptyDir" | "pvc" | "configMap" | "secret"
if type == "pvc" {
claimName: string
}
if type == "configMap" {
defaultMode: *420 | int
cmName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}
if type == "secret" {
defaultMode: *420 | int
secretName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}
if type == "emptyDir" {
medium: *"" | "Memory"
}
}]
// +usage=Instructions for assessing whether the container is alive.
livenessProbe?: #HealthProbe
// +usage=Instructions for assessing whether the container is in a suitable state to serve traffic.
readinessProbe?: #HealthProbe
// +usage=Specify the hostAliases to add
hostAliases?: [...{
ip: string
hostnames: [...string]
}]
}
#HealthProbe: {
// +usage=Instructions for assessing container health by executing a command. Either this attribute or the httpGet attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the httpGet attribute and the tcpSocket attribute.
exec?: {
// +usage=A command to be executed inside the container to assess its health. Each space delimited token of the command is a separate array element. Commands exiting 0 are considered to be successful probes, whilst all other exit codes are considered failures.
command: [...string]
}
// +usage=Instructions for assessing container health by executing an HTTP GET request. Either this attribute or the exec attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the tcpSocket attribute.
httpGet?: {
// +usage=The endpoint, relative to the port, to which the HTTP GET request should be directed.
path: string
// +usage=The TCP socket within the container to which the HTTP GET request should be directed.
port: int
host?: string
scheme?: *"HTTP" | string
httpHeaders?: [...{
name: string
value: string
}]
}
// +usage=Instructions for assessing container health by probing a TCP socket. Either this attribute or the exec attribute or the httpGet attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the httpGet attribute.
tcpSocket?: {
// +usage=The TCP socket within the container that should be probed to assess container health.
port: int
}
// +usage=Number of seconds after the container is started before the first probe is initiated.
initialDelaySeconds: *0 | int
// +usage=How often, in seconds, to execute the probe.
periodSeconds: *10 | int
// +usage=Number of seconds after which the probe times out.
timeoutSeconds: *1 | int
// +usage=Minimum consecutive successes for the probe to be considered successful after having failed.
successThreshold: *1 | int
// +usage=Number of consecutive failures required to determine the container is not alive (liveness probe) or not ready (readiness probe).
failureThreshold: *3 | int
}
status:
customStatus: |-
ready: {
readyReplicas: *0 | int
} & {
if context.output.status.readyReplicas != _|_ {
readyReplicas: context.output.status.readyReplicas
}
}
message: "Ready:\(ready.readyReplicas)/\(context.output.spec.replicas)"
healthPolicy: |-
ready: {
updatedReplicas: *0 | int
readyReplicas: *0 | int
replicas: *0 | int
observedGeneration: *0 | int
} & {
if context.output.status.updatedReplicas != _|_ {
updatedReplicas: context.output.status.updatedReplicas
}
if context.output.status.readyReplicas != _|_ {
readyReplicas: context.output.status.readyReplicas
}
if context.output.status.replicas != _|_ {
replicas: context.output.status.replicas
}
if context.output.status.observedGeneration != _|_ {
observedGeneration: context.output.status.observedGeneration
}
}
_isHealth: (context.output.spec.replicas == ready.readyReplicas) && (context.output.spec.replicas == ready.updatedReplicas) && (context.output.spec.replicas == ready.replicas) && (ready.observedGeneration == context.output.metadata.generation || ready.observedGeneration > context.output.metadata.generation)
isHealth: *_isHealth | bool
if context.output.metadata.annotations != _|_ {
if context.output.metadata.annotations["app.oam.dev/disable-health-check"] != _|_ {
isHealth: true
}
}
workload:
definition:
apiVersion: apps/v1
kind: StatefulSet
type: statefulsets.apps

View File

@@ -14,6 +14,7 @@ spec:
output: {
apiVersion: "batch/v1"
kind: "Job"
metadata: name: "\(context.appName)-\(context.name)"
spec: {
parallelism: parameter.count
completions: parameter.count

View File

@@ -207,16 +207,32 @@ spec:
}
if parameter["cpu"] != _|_ {
resources: {
limits: cpu: parameter.cpu
requests: cpu: parameter.cpu
if (parameter.limit.cpu != _|_) {
resources: {
requests: cpu: parameter.cpu
limits: cpu: parameter.limit.cpu
}
}
if (parameter.limit.cpu == _|_) {
resources: {
limits: cpu: parameter.cpu
requests: cpu: parameter.cpu
}
}
}
if parameter["memory"] != _|_ {
resources: {
limits: memory: parameter.memory
requests: memory: parameter.memory
if (parameter.limit.memory != _|_) {
resources: {
limits: memory: parameter.limit.memory
requests: memory: parameter.memory
}
}
if (parameter.limit.memory == _|_) {
resources: {
limits: memory: parameter.memory
requests: memory: parameter.memory
}
}
}
@@ -421,6 +437,11 @@ spec:
// +usage=Specifies the attributes of the memory resource required for the container.
memory?: string
limit?: {
cpu?: string
memory?: string
}
volumeMounts?: {
// +usage=Mount PVC type volume
pvc?: [...{

View File

@@ -399,3 +399,82 @@ spec:
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.core.metrics.enabled }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "kubevela.fullname" . }}-metrics
namespace: {{ .Release.Namespace }}
labels:
component: vela-core-controller
spec:
ports:
- name: http
protocol: TCP
port: 9443
targetPort: 9443
- name: metrics
protocol: TCP
port: 8080
targetPort: 8080
selector:
{{- include "kubevela.selectorLabels" . | nindent 4 }}
{{ if .Values.sharding.enabled }}
controller.core.oam.dev/shard-id: master
{{ end }}
{{- end -}}
{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.core.metrics.enabled .Values.core.metrics.serviceMonitor.enabled }}
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "kubevela.fullname" . }}-metrics
namespace: {{ .Release.Namespace }}
labels:
{{- with .Values.core.metrics.serviceMonitor.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
endpoints:
- honorLabels: true
interval: 10s
path: /metrics
port: metrics
scheme: http
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
component: vela-core-controller
{{- end -}}
{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.multicluster.metrics.enabled .Values.multicluster.clusterGateway.serviceMonitor.enabled }}
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "kubevela.fullname" . }}-cluster-gateway-metrics
namespace: {{ .Release.Namespace }}
labels:
{{- with .Values.multicluster.clusterGateway.serviceMonitor.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
endpoints:
- honorLabels: true
interval: 10s
path: /metrics
port: default
scheme: http
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
{{- include "kubevela-cluster-gateway.selectorLabels" . | nindent 4 }}
{{- end -}}

View File

@@ -48,3 +48,15 @@ spec:
echo "Application and its components are created"
restartPolicy: Never
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 4 }}
{{- end }}

View File

@@ -158,12 +158,17 @@ featureGates:
## @param multicluster.clusterGateway.secureTLS.enabled Whether to enable secure TLS
## @param multicluster.clusterGateway.secureTLS.certPath Path to the certificate file
## @param multicluster.clusterGateway.secureTLS.certManager.enabled Whether to enable cert-manager
## @param multicluster.clusterGateway.serviceMonitor.enabled Whether to enable service monitor
## @param multicluster.clusterGateway.serviceMonitor.additionalLabels Additional labels for service monitor
multicluster:
enabled: true
metrics:
enabled: false
clusterGateway:
direct: true
serviceMonitor:
enabled: false
additionalLabels: { }
replicaCount: 1
port: 9443
image:
@@ -296,4 +301,14 @@ authentication:
## @param sharding.schedulableShards The shards available for scheduling. If empty, dynamic discovery will be used.
sharding:
enabled: false
schedulableShards: ""
schedulableShards: ""
## @param core.metrics.enabled Enable metrics for vela-core
## @param core.metrics.serviceMonitor.enabled Enable service monitor for metrics
## @param core.metrics.serviceMonitor.additionalLabels Additional labels for service monitor
core:
metrics:
enabled: false
serviceMonitor:
enabled: false
additionalLabels: {}

View File

@@ -20,6 +20,8 @@ import (
"strconv"
"time"
"github.com/kubevela/pkg/cue/cuex"
pkgclient "github.com/kubevela/pkg/controller/client"
ctrlrec "github.com/kubevela/pkg/controller/reconciler"
"github.com/kubevela/pkg/controller/sharding"
@@ -35,7 +37,6 @@ import (
oamcontroller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/resourcekeeper"
"github.com/oam-dev/kubevela/pkg/workflow/providers"
)
// CoreOptions contains everything necessary to create and run vela-core
@@ -129,8 +130,8 @@ func (s *CoreOptions) Flags() cliflag.NamedFlagSets {
gfs.BoolVar(&s.EnableClusterGateway, "enable-cluster-gateway", s.EnableClusterGateway, "Enable cluster-gateway to use multicluster, disabled by default.")
gfs.BoolVar(&s.EnableClusterMetrics, "enable-cluster-metrics", s.EnableClusterMetrics, "Enable cluster-metrics-management to collect metrics from clusters with cluster-gateway, disabled by default. When this param is enabled, enable-cluster-gateway should be enabled")
gfs.DurationVar(&s.ClusterMetricsInterval, "cluster-metrics-interval", s.ClusterMetricsInterval, "The interval that ClusterMetricsMgr will collect metrics from clusters, default value is 15 seconds.")
gfs.BoolVar(&providers.EnableExternalPackageForDefaultCompiler, "enable-external-package-for-default-compiler", providers.EnableExternalPackageForDefaultCompiler, "Enable external package for default compiler")
gfs.BoolVar(&providers.EnableExternalPackageWatchForDefaultCompiler, "enable-external-package-watch-for-default-compiler", providers.EnableExternalPackageWatchForDefaultCompiler, "Enable external package watch for default compiler")
gfs.BoolVar(&cuex.EnableExternalPackageForDefaultCompiler, "enable-external-package-for-default-compiler", cuex.EnableExternalPackageForDefaultCompiler, "Enable external package for default compiler")
gfs.BoolVar(&cuex.EnableExternalPackageWatchForDefaultCompiler, "enable-external-package-watch-for-default-compiler", cuex.EnableExternalPackageWatchForDefaultCompiler, "Enable external package watch for default compiler")
s.ControllerArgs.AddFlags(fss.FlagSet("controllerArgs"), s.ControllerArgs)

View File

@@ -21,7 +21,9 @@ import (
"time"
"github.com/google/go-cmp/cmp"
"github.com/kubevela/pkg/cue/cuex"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
oamcontroller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
)
@@ -96,3 +98,26 @@ func TestCoreOptions_Flags(t *testing.T) {
t.Errorf("Flags() diff: %v", cmp.Diff(opt, expected, cmp.AllowUnexported(CoreOptions{})))
}
}
func TestCuexOptions_Flags(t *testing.T) {
pflag.NewFlagSet("test", pflag.ContinueOnError)
cuex.EnableExternalPackageForDefaultCompiler = false
cuex.EnableExternalPackageWatchForDefaultCompiler = false
opts := &CoreOptions{
ControllerArgs: &oamcontroller.Args{},
}
fss := opts.Flags()
args := []string{
"--enable-external-package-for-default-compiler=true",
"--enable-external-package-watch-for-default-compiler=true",
}
err := fss.FlagSet("generic").Parse(args)
if err != nil {
return
}
assert.True(t, cuex.EnableExternalPackageForDefaultCompiler, "The --enable-external-package-for-default-compiler flag should be enabled")
assert.True(t, cuex.EnableExternalPackageWatchForDefaultCompiler, "The --enable-external-package-watch-for-default-compiler flag should be enabled")
}

View File

@@ -0,0 +1,321 @@
# Versioning Support for KubeVela Definitions
<!-- toc -->
- [Versioning Support for KubeVela Definitions](#versioning-support-for-kubevela-definitions)
- [Summary](#summary)
- [Scope](#scope)
- [Motivation](#motivation)
- [Goals](#goals)
- [Non-Goals](#non-goals)
- [Acceptance Criteria](#acceptance-criteria)
- [Current Implementation](#current-implementation)
- [Versioning](#versioning)
- [Auto Upgrade](#auto-upgrade)
- [Reference:](#reference)
- [Proposal](#proposal)
- [Details](#details)
- [Issues](#issues)
- [Examples](#examples)
<!-- /toc -->
## Summary
Support Semantic versioning for KubeVela Components and a way to allow fine control over auto-upgrades of KubeVela Applications to new versions of a Component. The implementation should include support for consistent versioning across environments/clusters, meaning specific Revisions/Versions of a Component should have consistent behaviour.
## Scope
Although, this document limits the scope of discussion to ComponentDefinition Revisions/Versions, due to the current implementation, the changes will most likely apply to all [`Definition`](https://kubevela.io/docs/getting-started/definition/) types. These changes are planned to be explored and validated as part of the implementation.
## Motivation
OAM/KubeVela Definitions (referred to as ComponentDefinitions of Components in the rest
of the document) are the basic building blocks of the KubeVela platform. They
expose a contract similar to an API contract, which evolves from minor to major
versions. Applications are composed of Components that the KubeVela engine stitches
together.
KubeVela creates a `DefinitionRevision` for all changes in a Component `spec`.
Currently, Applications can refer to a particular Revision of a Component.
But, this versioning scheme has the following issues:
- The `DefinitionRevision` does not denote the type of the change (patch/bug, minor or major). This hinders automation of automatic upgrades.
- The current scheme also doesn't allow much control over automatic upgrades to new Component Revisions. KubeVela automatically upgrades/reconciles the Application to the
latest when no Component Revision is specified.
> While we don't ideally want Application developers to bother with such details, there are use cases where
> an automatic upgrade to the latest Component version is not desired.
### Goals
- Support Component versioning with Semantic Versions.
- Allow pinning specific and non-specific versions of a Component in the
KubeVela Application.
### Non-Goals
- Support for version range in Application. For eg. "type: my-component@>1.2.0"
## Acceptance Criteria
**User Story: Component version specification**
>**AS A** Component author\
>**I SHOULD** be able to publish every version of my Component with the Semantic Versioning scheme\
>**SO THAT** an Application developer can use a specific version of the Component.
**BDD Acceptance Criteria**
>**GIVEN** an updated ComponentDefinition Specification \
>**AND** a version denoted by the ComponentDefinition is set to V\
>**WHEN** the Component is applied to KubeVela\
>**THEN** `V` should be listed as one of the many versions in the DefinitionRevision list
**User Story: Application Component version specification**
>**AS AN** Application developer\
>**I SHOULD** be able to specify a version (complete or partial) for every Component used\
>**SO THAT** I can control which version are deployed.
**BDD Acceptance Criteria**
>Scenario 1: Use the version specified in the Application manifest when deploying the service\
>**GIVEN** a Component A with versions 1.2.2 | 1.2.3\
>**AND** a Component B with versions 4.4.2 | 4.5.6\
>**AND** an Application composed of A 1.2.2 and B 4.4.2\
>**WHEN** the Application is deployed\
>**THEN** it uses Component A 1.2.2 and B 4.4.2
>
>**Variant:** Use the latest version for the part of the SemVer that is not specified.\
>**GIVEN** component A latest version is 1.2.3
>**AND** Component B latest version is 4.5.6
>**AND** an Application composed of A 1.2 and B 4\
>**WHEN** the Application is deployed\
>**THEN** it uses Component A 1.2.3 and B 4.5.6
> Scenario 2: Behaviour when auto-upgrade is disabled \
> **GIVEN** a component A with version 1.2.3\
> **AND** an Application composed of A-1.2.3\
> **IF** Auto-upgrade is disabled\
> **WHEN** a new version of Component A (A-1.2.5) is released\
> **THEN** the Application should continue to use A-1.2.3
>
> **Variant** Behaviour when auto-upgrade is disabled and exact version is unavailable.\
> **GIVEN** a component A with version 1.2.3\
> **AND** a new Application composed of A-1.2.2\
> **IF** Auto-upgrade is disabled\
> **WHEN** the Application is applied\
> **THEN** the Application deployment should fail.
>
> **Variant** Behaviour when auto-upgrade is disabled and exact version is unavailable.\
> **GIVEN** a component A with version 1.2.3\
> **AND** a new Application composed of A-1.2\
> **IF** Auto-upgrade is disabled\
> **WHEN** the Application is applied\
> **THEN** the Application deployment should fail.
> Scenario 3: Behaviour when auto-upgrade is enabled \
> **GIVEN** a component A with version 1.2.3\
> **AND** an Application composed of A-1.2\
> **IF** Auto-upgrade is enabled\
> **THEN** the Application should use A-1.2.3
> **AND WHEN** a new version of Component A (A-1.2.5) is released\
> **THEN** the Application should update to use A-1.2.5
>
> **Variant** Behaviour when auto-upgrade is enabled and exact version is unavailable \
> **GIVEN** a component A with version 1.2.3\
> **AND** a new Application composed of A-1.2.2\
> **IF** Auto-upgrade is enabled\
> **WHEN** the Application is applied\
> **THEN** the Application deployment should fail.
>
> **Variant** Behaviour when auto-upgrade is enabled and exact version is unavailable \
> **GIVEN** a component A with version 1.2.3\
> **AND** a new Application composed of A-1.2\
> **IF** Auto-upgrade is enabled\
> **WHEN** the Application is applied\
> **THEN** the Application deployment should use A-1.2.3.
> Scenario 4: Expectations of consistent versioning across Environments/Clusters. \
> **GIVEN** a component A with versions 1.2.1|1.2.2|2.2.1\
> **AND** an Application composed of A-1.2.2\
> **IF** the Application needs to be deployed across Environments (Dev, Prod etc)\
> **OR** the Application needs to be deployed in multiple clusters managed independently\
> **WHEN** the Application is deployed across Environments/Clusters \
> **THEN** The Application should behave consistently, as in all the clusters A-1.2.2 map to the same ComponentDefinition changes.
## Current Implementation
### Versioning
Currently, KubeVela has some support for controlling Definition versions based on K8s annotations and DefinitionRevisions. The annotation `definitionrevision.oam.dev/name` can be used to version the ComponentDefinition. For example if the following annotation is added to a ComponentDefinition, it produces a new DefinitionRevision and names the ComponentDefinition as `component-name-v4.4` .
> definitionrevision.oam.dev/name: "4.4"
This Component can then be referred in the Application as follows:
>"component-name@v4.4" - `NamedDefinitionRevision`
Alternatively, since DefinitionRevisions are maintained even if a **"named"** Revision is not specified via the annotation `definitionrevision.oam.dev/name`, Applications can still refer to a particular Revision of a Component via the auto-incrementing Revision numbers.
>"component-name@v2" - `DefinitionRevision`
![version](./kubevela-version.png)
This versioning scheme, although convenient, has the following issues:
- Applications which do not explicitly specify a target Revision of a ComponentDefinition, the "latest" applied revision of the ComponentDefinition is used. In scenarios where a cluster has to be replicated or re-created, this means that the sequence in which revisions of a ComponentDefinition are applied becomes important. Implicitly, this also means that the Component maintainers need to keep all Revisions of a ComponentDefinition in their deployment pipeline.\
If `definitionrevision.oam.dev/name` annotation is not added to ComponentDefinitions, even if the Applications are explicit about a Component Revision, there is currently no guarantee that the Application behaviour will be consistent across Environments/Clusters. For example, a `Dev` environment will typically have more churn in Revisions than a `Prod` one and a reference to Component Revision `v3` in an Application will not be the same in both environments.
### Auto Upgrade
KubeVela utilises the annotation `app.oam.dev/autoUpdate` for automatic upgrade.
Application reconciliation behaviour when the `app.oam.dev/autoUpdate` annotation is specified in the Application:
- If a ComponentDefinition Revision is not specified, the Application will always use the latest available Revision.
- If a ComponentDefinition Revision is specified and a new Revision is released after the Application was created, the latest changes will not reflect in the Application.
Note: This feature is not documented in KubeVela documentation.
#### Reference:
- https://kubevela.io/docs/platform-engineers/x-def-version/
- [Auto Upgrade PR](https://github.com/kubevela/kubevela/pull/3217)
## Proposal
### Introduce `spec.version` as an optional field in the Definition
- Add an optional field `version` in the Definition `spec` and use it to generate the ComponentDefinition Revisions.
- Update the auto-upgrade behaviour to also allow limiting upgrades for an Application within a specified Definition version range. The existing annotation `app.oam.dev/autoUpdate` for enabling automatic updates will be used for this new behaviour and will maintain backward compatibility.
- Implement Validating webhook to:
- Ensure that the values of the annotation `definitionrevision.oam.dev/version`, `definitionrevision.oam.dev/name` or `spec.version` field adhere to semantic versioning.
- Ensure that the `definitionrevision.oam.dev/name` annotation and the `spec.version` field are not present together in the ComponentDefinition to avoid conflicts.
- Ensure that `app.oam.dev/publishVersion` and `app.oam.dev/autoUpdate` both annotation are not present in Application to avoid conflicts.
### Issues
The following issues assume adherence to strict backward compatibility, meaning the `definitionrevision.oam.dev/name` annotation should continue to work as is.
- It does not resolve inconsistent versioning behaviour across Environments/Clusters when explicit versions are not specified or named DefinitionRevisions are not used.
## Examples
1. Create a `configmap-component` ComponentDefinition with `1.2.5` version
```
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: configmap-component
namespace: vela-system
spec:
version: 1.2.5
schematic:
cue:
template: |
output: {
apiVersion: "v1"
kind: "ConfigMap"
metadata: {
name: "comptest"
}
data: {
version: "125"
}
}
workload:
definition:
apiVersion: v1
kind: ConfigMap
```
2. Create a `configmap-component` ComponentDefinition with `2.0.5` version
```apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: configmap-component
namespace: vela-system
spec:
version: 2.5.0
schematic:
cue:
template: |
output: {
apiVersion: "v1"
kind: "ConfigMap"
metadata: {
name: "comptest"
}
data: {
version: "250"
}
}
workload:
definition:
apiVersion: v1
kind: ConfigMap
```
3. List DefinitionRevisions
```
kubectl get definitionrevision -n vela-system | grep -i my-component
my-component-v1.2.5 1 1a4f3ac77e4fcfef Component
my-component-v2.5.0 2 e61e9b5e55b01c2b Component
```
4. Create Application using `configmap-component@v1.2` version and enable the Auto Update using `app.oam.dev/autoUpdate` annotation.
```apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: test-app
namespace: test
annotations:
app.oam.dev/autoUpdate: "true"
spec:
components:
- name: test
type: my-component@v1
```
Expected Behavior:
- Application will use `configmap-component@v1.2.5`, as `1.2.5` is highest version in specified range(`1`).
5. Create a `configmap-component` ComponentDefinition with `1.2.7` version
```
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: configmap-component
namespace: vela-system
spec:
version: 1.2.7
schematic:
cue:
template: |
output: {
apiVersion: "v1"
kind: "ConfigMap"
metadata: {
name: "comptest"
}
data: {
version: "127"
}
}
workload:
definition:
apiVersion: v1
kind: ConfigMap
```
Expected Behavior:
- After the Application is reconciled, it will use `configmap-component@v1.2.7`, as `1.2.7` is the latest version within the specified range (1).
6. List Definitionrevision
```kubectl get definitionrevision -n vela-system | grep -i my-component
my-component-v1.2.5 1 1a4f3ac77e4fcfef Component
my-component-v1.2.7 3 86d7fb1a36566dea Component
my-component-v2.5.0 2 e61e9b5e55b01c2b Component```

View File

@@ -1,4 +1,10 @@
# How to use
The Kubevela platform out of the box provides supported and complete `StatefulSet` component and `Storage` trait. This example is just provided for education.
Please check also the online documentation:
* [Trait Definition](https://kubevela.io/docs/platform-engineers/traits/customize-trait/)
* [Component Definition](https://kubevela.io/docs/platform-engineers/components/custom-component/)
# Yet another example defining a custom component and custom trait
1. define a stateful component with StatefulSet as output

View File

@@ -15,6 +15,6 @@ spec:
properties:
volumeClaimTemplates:
- name: test
requests: 10Gi
storageClassName: cbs
requests: 1Gi
storageClassName: local-path
mountPath: /usr/share/nginx/html

View File

@@ -0,0 +1,249 @@
/*
Copyright 2024 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 e2e
import (
"context"
"fmt"
"math/rand"
"strconv"
"strings"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
oamcommon "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/e2e"
"github.com/oam-dev/kubevela/pkg/utils/common"
)
var _ = Describe("Application Auto update", Ordered, func() {
ctx := context.Background()
var k8sClient client.Client
var namespace string
var ns corev1.Namespace
var err error
var velaCommandPrefix string
BeforeEach(func() {
k8sClient, err = common.NewK8sClient()
Expect(err).NotTo(HaveOccurred())
By("Create namespace for app-autoupdate-e2e-test")
namespace = randomNamespaceName("app-autoupdate-e2e-test")
ns = corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}
k8sClient.Create(ctx, &ns)
velaCommandPrefix = fmt.Sprintf("vela -n %s", namespace)
})
AfterEach(func() {
By("Clean up resources after a test")
k8sClient.DeleteAllOf(ctx, &v1beta1.Application{}, client.InNamespace(namespace))
k8sClient.DeleteAllOf(ctx, &v1beta1.ComponentDefinition{}, client.InNamespace(namespace))
k8sClient.DeleteAllOf(ctx, &v1beta1.DefinitionRevision{}, client.InNamespace(namespace))
Expect(k8sClient.Delete(ctx, &ns)).Should(BeNil())
})
It("dry-run command", func() {
By("Create configmap-component with 1.2.0 version")
component := configMapComponent.DeepCopy()
component.SetNamespace(namespace)
Expect(k8sClient.Create(ctx, component)).Should(Succeed())
By("Execute a dry-run for application having configmap-component@v1 component")
output, err := e2e.Exec(fmt.Sprintf("%s dry-run -f data/app.yaml", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring(fmt.Sprintf(dryRunResult1, namespace)))
By("Create application using configmap-component@v1 component")
_, err = e2e.Exec(fmt.Sprintf("%s up -f data/app.yaml", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
By("Create configmap-component with 1.4.0 version")
updatedComponent := new(v1beta1.ComponentDefinition)
updatedComponentVersion := "1.4.0"
Eventually(func() error {
err := k8sClient.Get(ctx, client.ObjectKey{Name: "configmap-component", Namespace: namespace}, updatedComponent)
if err != nil {
return err
}
updatedComponent.Spec.Schematic.CUE.Template = strings.Replace(configMapOutputTemplate, updatedComponent.Spec.Version, updatedComponentVersion, 1)
updatedComponent.Spec.Version = updatedComponentVersion
return k8sClient.Update(ctx, updatedComponent)
}, 15*time.Second, time.Second).Should(BeNil())
By("Execute a dry-run for application having configmap-component@v1 component")
output, err = e2e.Exec(fmt.Sprintf("%s dry-run -f data/app.yaml", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring(fmt.Sprintf(dryRunResult2, namespace, namespace)))
})
It("live-diff between application file and revision", func() {
By("Create configmap-component with 1.2.0 version")
component := configMapComponent.DeepCopy()
component.SetNamespace(namespace)
Expect(k8sClient.Create(ctx, component)).Should(Succeed())
By("Create application using configmap-component@v1 component")
_, err = e2e.Exec(fmt.Sprintf("%s up -f data/app.yaml", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
By("Create configmap-component with 1.4.0 version")
updatedComponent := new(v1beta1.ComponentDefinition)
updatedComponentVersion := "1.4.0"
Eventually(func() error {
err := k8sClient.Get(ctx, client.ObjectKey{Name: "configmap-component", Namespace: namespace}, updatedComponent)
if err != nil {
return err
}
updatedComponent.Spec.Schematic.CUE.Template = strings.Replace(configMapOutputTemplate, updatedComponent.Spec.Version, updatedComponentVersion, 1)
updatedComponent.Spec.Version = updatedComponentVersion
return k8sClient.Update(ctx, updatedComponent)
}, 15*time.Second, time.Second).Should(BeNil())
By("Execute a live-diff command for application file and previous application")
output, err := e2e.Exec(fmt.Sprintf("%s live-diff -f data/app.yaml -r app-with-auto-update-v1", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring(liveDiffResult))
})
It("live-diff between revisions", func() {
By("Create configmap-component with 1.2.0 version")
component := configMapComponent.DeepCopy()
component.SetNamespace(namespace)
Expect(k8sClient.Create(ctx, component)).Should(Succeed())
By("Create application using configmap-component@v1 component")
_, err = e2e.Exec(fmt.Sprintf("%s up -f data/app.yaml", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
By("Create configmap-component with 1.4.0 version")
updatedComponent := new(v1beta1.ComponentDefinition)
updatedComponentVersion := "1.4.0"
Eventually(func() error {
err := k8sClient.Get(ctx, client.ObjectKey{Name: "configmap-component", Namespace: namespace}, updatedComponent)
if err != nil {
return err
}
updatedComponent.Spec.Schematic.CUE.Template = strings.Replace(configMapOutputTemplate, updatedComponent.Spec.Version, updatedComponentVersion, 1)
updatedComponent.Spec.Version = updatedComponentVersion
return k8sClient.Update(ctx, updatedComponent)
}, 15*time.Second, time.Second).Should(BeNil())
By("Create application using configmap-component@v1 component")
_, err = e2e.Exec(fmt.Sprintf("%s up -f data/app.yaml", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
By("Execute a live-diff command for previous two application versions")
output, err := e2e.Exec(fmt.Sprintf("%s live-diff --revision app-with-auto-update-v2,app-with-auto-update-v1", velaCommandPrefix))
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("Application (app-with-auto-update) has no change"))
})
})
var configMapComponent = &v1beta1.ComponentDefinition{
TypeMeta: metav1.TypeMeta{
Kind: "ComponentDefinition",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap-component",
},
Spec: v1beta1.ComponentDefinitionSpec{
Version: "1.2.0",
Schematic: &oamcommon.Schematic{
CUE: &oamcommon.CUE{
Template: configMapOutputTemplate,
},
},
},
}
var configMapOutputTemplate = `output: {
apiVersion: "v1"
kind: "ConfigMap"
metadata: name: "comptest"
data: {
expectedVersion: "1.2.0"
}
}`
func randomNamespaceName(basic string) string {
return fmt.Sprintf("%s-%s", basic, strconv.FormatInt(rand.Int63(), 16))
}
var dryRunResult1 = `---
# Application(app-with-auto-update) -- Component(test)
---
apiVersion: v1
data:
expectedVersion: 1.2.0
kind: ConfigMap
metadata:
annotations:
app.oam.dev/autoUpdate: "true"
labels:
app.oam.dev/appRevision: ""
app.oam.dev/component: test
app.oam.dev/name: app-with-auto-update
app.oam.dev/namespace: %[1]s
app.oam.dev/resourceType: WORKLOAD
workload.oam.dev/type: configmap-component-v1
name: comptest
namespace: %[1]s
---`
var dryRunResult2 = `---
# Application(app-with-auto-update) -- Component(test)
---
apiVersion: v1
data:
expectedVersion: 1.4.0
kind: ConfigMap
metadata:
annotations:
app.oam.dev/autoUpdate: "true"
labels:
app.oam.dev/appRevision: ""
app.oam.dev/component: test
app.oam.dev/name: app-with-auto-update
app.oam.dev/namespace: %[1]s
app.oam.dev/resourceType: WORKLOAD
workload.oam.dev/type: configmap-component-v1
name: comptest
namespace: %[1]s
---
`
var liveDiffResult = `
- expectedVersion: 1.2.0
+ expectedVersion: 1.4.0
`

View File

@@ -128,6 +128,15 @@ var ApplicationExecContext = func(context string, appName string) bool {
var ApplicationPortForwardContext = func(context string, appName string) bool {
return ginkgo.It(context+": should get output of port-forward successfully", func() {
ginkgo.By(fmt.Sprintf("waiting for the application [%s] to reach the desired status", appName))
gomega.Eventually(func() string {
cli := fmt.Sprintf("vela status %s", appName)
output, err := e2e.Exec(cli)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return output
}, 90*time.Second, 1*time.Second).Should(gomega.ContainSubstring("running"))
ginkgo.By("executing port-forward")
cli := fmt.Sprintf("vela port-forward %s 8080:80 ", appName)
output, err := e2e.ExecAndTerminate(cli)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
@@ -184,8 +193,10 @@ var ApplicationInitIntercativeCliContext = func(context string, appName string,
})
}
// debug test
var ApplicationDeleteWithWaitOptions = func(context string, appName string) bool {
return ginkgo.It(context+": should print successful deletion information", func() {
return ginkgo.It(context+": should print successful deletion information ", func() {
time.Sleep(1 * time.Minute)
cli := fmt.Sprintf("vela delete %s --wait -y", appName)
output, err := e2e.LongTimeExec(cli, 10*time.Second)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

View File

@@ -0,0 +1,10 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-with-auto-update
annotations:
app.oam.dev/autoUpdate: "true"
spec:
components:
- name: test
type: configmap-component@v1

View File

@@ -56,7 +56,7 @@ func ExecAndTerminate(cli string) (string, error) {
if err != nil {
return string(output), err
}
time.Sleep(3 * time.Second)
time.Sleep(10 * time.Second)
s := session.Terminate()
return string(s.Out.Contents()) + string(s.Err.Contents()), nil
}

View File

@@ -462,24 +462,26 @@ spec:
- backend
podDisruptive: true
schematic:
kube:
template:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
cue:
template: |
output: {
apiVersion: "v1"
kind: "Service"
metadata: {
name: "my-service"
}
spec:{
ports: [{
protocol: "TCP"
port: 80
targetPort: 9376
parameters:
- name: targetPort
required: true
type: number
fieldPaths:
- "spec.template.spec.ports[0].targetPort"
description: "target port num for service provider."
targetPort: parameters.targetPort
}]
}
parameters:{
//+usage=target port num for service provider
targetPort: *9376 | int
}
}
`
var componentWithDeepCue = `

82
go.mod
View File

@@ -1,11 +1,12 @@
module github.com/oam-dev/kubevela
go 1.22.0
go 1.23.8
require (
cuelang.org/go v0.9.2
github.com/AlecAivazis/survey/v2 v2.1.1
github.com/FogDong/uitable v0.0.5
github.com/Masterminds/semver v1.5.0
github.com/Masterminds/semver/v3 v3.2.1
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
@@ -20,15 +21,15 @@ require (
github.com/ettle/strcase v0.2.0
github.com/fatih/color v1.16.0
github.com/fluxcd/helm-controller/api v0.32.2
github.com/fluxcd/source-controller/api v0.24.4
github.com/fluxcd/source-controller/api v0.30.0
github.com/form3tech-oss/jwt-go v3.2.5+incompatible
github.com/gdamore/tcell/v2 v2.6.0
github.com/getkin/kin-openapi v0.118.0
github.com/go-git/go-git/v5 v5.8.1
github.com/go-logr/logr v1.4.1
github.com/go-git/go-git/v5 v5.16.0
github.com/go-logr/logr v1.4.2
github.com/go-resty/resty/v2 v2.8.0
github.com/golang/mock v1.6.0
github.com/google/go-cmp v0.6.0
github.com/google/go-cmp v0.7.0
github.com/google/go-containerregistry v0.18.0
github.com/google/go-github/v32 v32.1.0
github.com/gosuri/uitable v0.0.4
@@ -36,8 +37,9 @@ require (
github.com/hashicorp/hcl/v2 v2.18.0
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
github.com/imdario/mergo v0.3.16
github.com/jeremywohl/flatten/v2 v2.0.0-20211013061545-07e4a09fb8e4
github.com/kubevela/pkg v1.9.3-0.20241203070234-2cf98778c0a9
github.com/kubevela/workflow v0.6.1-0.20241210074645-d8a85b26c862
github.com/kubevela/workflow v0.6.2
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/magiconair/properties v1.8.7
github.com/mattn/go-runewidth v0.0.15
@@ -48,8 +50,8 @@ require (
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28
github.com/oam-dev/terraform-controller v0.8.0
github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/ginkgo/v2 v2.14.0
github.com/onsi/gomega v1.30.0
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.34.1
github.com/openkruise/kruise-api v1.4.0
github.com/openkruise/rollouts v0.3.0
github.com/pelletier/go-toml v1.9.5
@@ -60,19 +62,19 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/tidwall/gjson v1.14.4
github.com/wercker/stern v0.0.0-20190705090245-4fa46dd6987f
github.com/xanzy/go-gitlab v0.91.1
github.com/xlab/treeprint v1.2.0
gitlab.com/gitlab-org/api/client-go v0.127.0
go.uber.org/multierr v1.11.0
golang.org/x/crypto v0.25.0
golang.org/x/mod v0.17.0
golang.org/x/oauth2 v0.20.0
golang.org/x/sync v0.7.0
golang.org/x/term v0.22.0
golang.org/x/text v0.16.0
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
golang.org/x/crypto v0.37.0
golang.org/x/mod v0.21.0
golang.org/x/oauth2 v0.29.0
golang.org/x/sync v0.13.0
golang.org/x/term v0.31.0
golang.org/x/text v0.24.0
golang.org/x/tools v0.26.0
gomodules.xyz/jsonpatch/v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.14.4
@@ -105,15 +107,13 @@ require (
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.12.2 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/alessio/shellescape v1.4.1 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
@@ -127,9 +127,9 @@ require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/containerd/containerd v1.7.24 // indirect
github.com/containerd/containerd v1.7.27 // indirect
github.com/containerd/errdefs v0.3.0 // indirect
github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
@@ -137,15 +137,14 @@ require (
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/creack/pty v1.1.18 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/cli v26.0.0+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v26.0.0+incompatible // indirect
github.com/docker/docker v28.0.4+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.1 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
github.com/emicklei/proto v1.10.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
@@ -154,7 +153,7 @@ require (
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fluxcd/pkg/apis/acl v0.0.3 // indirect
github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect
github.com/fluxcd/pkg/apis/kustomize v1.0.0 // indirect
github.com/fluxcd/pkg/apis/meta v1.0.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
@@ -163,7 +162,7 @@ require (
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.4.1 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
@@ -171,18 +170,18 @@ require (
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gobuffalo/flect v1.0.2 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/cel-go v0.17.7 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 // indirect
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
@@ -194,7 +193,7 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -230,7 +229,6 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
@@ -238,19 +236,19 @@ require (
github.com/openshift/library-go v0.0.0-20230327085348-8477ec72b725 // indirect
github.com/perimeterx/marshmallow v1.1.4 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/rubenv/sql-migrate v1.5.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/skeema/knownhosts v1.2.0 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
@@ -276,15 +274,15 @@ require (
go.starlark.net v0.0.0-20240329153429-e6e8e7ce1b7a // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/time v0.10.0 // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
google.golang.org/grpc v1.63.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/evanphx/json-patch.v5 v5.9.0 // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
@@ -309,7 +307,7 @@ require (
replace (
cloud.google.com/go => cloud.google.com/go v0.100.2
github.com/docker/cli => github.com/docker/cli v24.0.9+incompatible
github.com/docker/docker => github.com/docker/docker v24.0.9+incompatible
github.com/docker/docker => github.com/docker/docker v25.0.6+incompatible
github.com/docker/docker-credential-helpers => github.com/docker/docker-credential-helpers v0.7.0
github.com/wercker/stern => github.com/oam-dev/stern v1.13.2
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00

180
go.sum
View File

@@ -63,14 +63,12 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
@@ -136,7 +134,6 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
@@ -157,9 +154,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
@@ -178,10 +174,10 @@ github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u9
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
github.com/containerd/containerd v1.7.24 h1:zxszGrGjrra1yYJW/6rhm9cJ1ZQ8rkKBR48brqsa7nA=
github.com/containerd/containerd v1.7.24/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII=
github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0=
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
@@ -215,8 +211,8 @@ github.com/crossplane/crossplane-runtime v1.16.0 h1:lz+l0wEB3qowdTmN7t0PZkfuNSvf
github.com/crossplane/crossplane-runtime v1.16.0/go.mod h1:Pz2tdGVMF6KDGzHZOkvKro0nKc8EzK0sb/nSA7pH4Dc=
github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d h1:VNJA1nSKA8Xna5wjUIMItHlWmEej8Bb9fZ3vCNtIAX0=
github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d/go.mod h1:SyTryzw/zYJIogw3H2IRcYdV5gsSoVMJiKGElcQK09I=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/dave/jennifer v1.6.1 h1:T4T/67t6RAA5AIV6+NP8Uk/BIsXgDoqEowgycdQQLuk=
github.com/dave/jennifer v1.6.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -232,8 +228,8 @@ github.com/docker/cli v24.0.9+incompatible h1:OxbimnP/z+qVjDLpq9wbeFU3Nc30XhSe+L
github.com/docker/cli v24.0.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg=
github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
@@ -242,8 +238,6 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
@@ -251,8 +245,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
@@ -297,14 +291,14 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fluxcd/helm-controller/api v0.32.2 h1:ETkZmMEHY/qu6a9AjP6en35WrpN7NnVmhOe7IvOB7jE=
github.com/fluxcd/helm-controller/api v0.32.2/go.mod h1:xzQgNoaPOg77zFUqvnaX0Fn3lPA3iGDLoz8q4wiEyLA=
github.com/fluxcd/pkg/apis/acl v0.0.3 h1:Lw0ZHdpnO4G7Zy9KjrzwwBmDZQuy4qEjaU/RvA6k1lc=
github.com/fluxcd/pkg/apis/acl v0.0.3/go.mod h1:XPts6lRJ9C9fIF9xVWofmQwftvhY25n1ps7W9xw0XLU=
github.com/fluxcd/pkg/apis/acl v0.1.0 h1:EoAl377hDQYL3WqanWCdifauXqXbMyFuK82NnX6pH4Q=
github.com/fluxcd/pkg/apis/acl v0.1.0/go.mod h1:zfEZzz169Oap034EsDhmCAGgnWlcWmIObZjYMusoXS8=
github.com/fluxcd/pkg/apis/kustomize v1.0.0 h1:5T2b/mRZiGWtP7fvSU8gZOApIc06H6SdLX3MlsE6LRo=
github.com/fluxcd/pkg/apis/kustomize v1.0.0/go.mod h1:XaDYlKxrf9D2zZWcZ0BnSIqGtcm8mdNtJGzZWYjCnQo=
github.com/fluxcd/pkg/apis/meta v1.0.0 h1:i9IGHd/VNEZELX7mepkiYFbJxs2J5znaB4cN9z2nPm8=
github.com/fluxcd/pkg/apis/meta v1.0.0/go.mod h1:04ZdpZYm1x+aL93K4daNHW1UX6E8K7Gyf5za9OhrE+U=
github.com/fluxcd/source-controller/api v0.24.4 h1:m54sS1rJlgJf5j9qDRgKLhbPJAnJ9dY+VrstPKj0aQo=
github.com/fluxcd/source-controller/api v0.24.4/go.mod h1:b0MmMPGE8gcpgSyGXe5m7see77tBW26eZrvGkkPstUs=
github.com/fluxcd/source-controller/api v0.30.0 h1:rPVPpwXcYG2n0DTRcRagfGDiccvCib5S09K5iMjlpRU=
github.com/fluxcd/source-controller/api v0.30.0/go.mod h1:UkjAqQ6QAXNNesNQDTArTeiTp+UuhOUIA+JyFhGP/+Q=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8=
@@ -330,18 +324,18 @@ github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BH
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ=
github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
@@ -359,8 +353,8 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
@@ -393,8 +387,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
@@ -423,8 +417,9 @@ github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
@@ -476,8 +471,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.18.0 h1:ShE7erKNPqRh5ue6Z9DUOlk04WsnFWPO6YGr3OxnfoQ=
github.com/google/go-containerregistry v0.18.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
@@ -491,8 +486,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 h1:WzfWbQz/Ze8v6l++GGbGNFZnUShVpP/0xffCPLL+ax8=
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 h1:SJ+NtwL6QaZ21U+IrK7d0gGgpjGGvd2kz+FzTHVzdqI=
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC9t8wNnpPdctvtSUOPUUg4SHeE6vR1Ir2hmg=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
@@ -539,15 +534,15 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
@@ -593,6 +588,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jellydator/ttlcache/v3 v3.0.1 h1:cHgCSMS7TdQcoprXnWUptJZzyFsqs18Lt8VVhRuZYVU=
github.com/jellydator/ttlcache/v3 v3.0.1/go.mod h1:WwTaEmcXQ3MTjOm4bsZoDFiCu/hMvNWLO1w67RXz6h4=
github.com/jeremywohl/flatten/v2 v2.0.0-20211013061545-07e4a09fb8e4 h1:eA9wi6ZzpIRobvXkn/S2Lyw1hr2pc71zxzOPl7Xjs4w=
github.com/jeremywohl/flatten/v2 v2.0.0-20211013061545-07e4a09fb8e4/go.mod h1:s9g9Dfls+aEgucKXKW+i8MRZuLXT2MrD/WjYpMnWfOw=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
@@ -650,8 +647,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubevela/pkg v1.9.3-0.20241203070234-2cf98778c0a9 h1:VgW3WgcQ5jZcWUvKULfnV7w8vfp86yGp6Es4NFJpiCg=
github.com/kubevela/pkg v1.9.3-0.20241203070234-2cf98778c0a9/go.mod h1:mb14wKSzUVKsSupXEjnci2vCd8DTkN4mBYdz9wvS7Vk=
github.com/kubevela/workflow v0.6.1-0.20241210074645-d8a85b26c862 h1:EaXO5m/4ewOBa1CAHqFt9RqN/+oh566YKKpQJ6a1MBU=
github.com/kubevela/workflow v0.6.1-0.20241210074645-d8a85b26c862/go.mod h1:nJIoAw1SHthfLhJqFFKX2dwwoDy6vF2DZrBdlAJNSXU=
github.com/kubevela/workflow v0.6.2 h1:zmsjQStemSSAJVACsf9c39WTIJqdn1YQlb5jltOfSwU=
github.com/kubevela/workflow v0.6.2/go.mod h1:nJIoAw1SHthfLhJqFFKX2dwwoDy6vF2DZrBdlAJNSXU=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
@@ -683,8 +680,6 @@ github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY
github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -761,8 +756,6 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -803,8 +796,8 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY=
github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
@@ -815,8 +808,8 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ
github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
@@ -841,8 +834,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -909,8 +902,8 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0=
github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -919,8 +912,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
@@ -932,8 +925,8 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -980,8 +973,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
@@ -1000,8 +993,6 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/xanzy/go-gitlab v0.91.1 h1:gnV57IPGYywWer32oXKBcdmc8dVxeKl3AauV8Bu17rw=
github.com/xanzy/go-gitlab v0.91.1/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -1030,6 +1021,8 @@ github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.13.0 h1:It5dfKTTZHe9aeppbNOda3mN7Ag7sg6QkBNm6TkyFa0=
github.com/zclconf/go-cty v1.13.0/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
gitlab.com/gitlab-org/api/client-go v0.127.0 h1:8xnxcNKGF2gDazEoMs+hOZfOspSSw8D0vAoWhQk9U+U=
gitlab.com/gitlab-org/api/client-go v0.127.0/go.mod h1:bYC6fPORKSmtuPRyD9Z2rtbAjE7UeNatu2VWHRf4/LE=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
@@ -1159,16 +1152,14 @@ golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1189,8 +1180,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1238,11 +1229,10 @@ golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1254,8 +1244,8 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1268,8 +1258,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1341,8 +1331,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1352,11 +1342,10 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -1366,18 +1355,17 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1408,8 +1396,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1501,8 +1489,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=

View File

@@ -18,7 +18,6 @@ package main
import (
"fmt"
"io"
"io/fs"
"log"
"os"
@@ -69,23 +68,23 @@ func GenMarkdownTreeForIndex(cmd *cobra.Command, dir string) error {
}
defer f.Close()
if _, err = io.WriteString(f, "---\ntitle: CLI Commands\n---\n\n\n"); err != nil {
if _, err = f.WriteString("---\ntitle: CLI Commands\n---\n\n\n"); err != nil {
return err
}
for _, tp := range []string{types.TypeStart, types.TypeApp, types.TypeCD, types.TypeExtension, types.TypeSystem} {
// write header of type
_, err = io.WriteString(f, "## "+tp+"\n\n")
_, err = f.WriteString("## " + tp + "\n\n")
if err != nil {
return err
}
str := PrintCLIByTag(cmd, cmd.Commands(), tp)
// write header of type
_, err = io.WriteString(f, str)
_, err = f.WriteString(str)
if err != nil {
return err
}
}
_, err = io.WriteString(f, "###### Auto generated by [script in KubeVela](https://github.com/kubevela/kubevela/tree/master/hack/docgen).")
_, err = f.WriteString("###### Auto generated by [script in KubeVela](https://github.com/kubevela/kubevela/tree/master/hack/docgen).")
if err != nil {
return err
}

View File

@@ -1,7 +1,7 @@
LOCALBIN ?= $(shell pwd)/bin
$(LOCALBIN):
mkdir -p $(LOCALBIN)
GOLANGCILINT_VERSION ?= 1.54.2
GOLANGCILINT_VERSION ?= 1.60.1
GLOBAL_GOLANGCILINT := $(shell which golangci-lint)
GOBIN_GOLANGCILINT:= $(shell which $(GOBIN)/golangci-lint)
ENVTEST_K8S_VERSION = 1.29.0
@@ -31,7 +31,7 @@ ifeq (, $(shell which staticcheck))
@{ \
set -e ;\
echo 'installing honnef.co/go/tools/cmd/staticcheck ' ;\
go install honnef.co/go/tools/cmd/staticcheck@v0.4.7 ;\
go install honnef.co/go/tools/cmd/staticcheck@v0.5.1 ;\
}
STATICCHECK=$(GOBIN)/staticcheck
else

View File

@@ -24,13 +24,15 @@ e2e-setup-core-wo-auth:
--namespace vela-system \
--set image.pullPolicy=IfNotPresent \
--set image.repository=vela-core-test \
--set applicationRevisionLimit=5 \
--set applicationRevisionLimit=5 \
--set controllerArgs.reSyncPeriod=1m \
--set optimize.disableComponentRevision=false \
--set image.tag=$(GIT_COMMIT) \
--set multicluster.clusterGateway.image.repository=ghcr.io/oam-dev/cluster-gateway \
--set admissionWebhooks.patch.image.repository=ghcr.io/oam-dev/kube-webhook-certgen/kube-webhook-certgen \
--set multicluster.clusterGateway.image.repository=ghcr.io/oam-dev/cluster-gateway \
--set admissionWebhooks.patch.image.repository=ghcr.io/oam-dev/kube-webhook-certgen/kube-webhook-certgen \
--set featureGates.enableCueValidation=true \
--wait kubevela ./charts/vela-core \
--debug
--debug
.PHONY: e2e-setup-core-w-auth
e2e-setup-core-w-auth:
@@ -109,4 +111,4 @@ end-e2e-core-shards: end-e2e-core
.PHONY: end-e2e
end-e2e:
sh ./hack/e2e/end_e2e.sh
sh ./hack/e2e/end_e2e.sh

View File

@@ -38,7 +38,7 @@ import (
"github.com/google/go-github/v32/github"
"github.com/imdario/mergo"
"github.com/pkg/errors"
"github.com/xanzy/go-gitlab"
gitlab "gitlab.com/gitlab-org/api/client-go"
"go.uber.org/multierr"
"golang.org/x/oauth2"
"helm.sh/helm/v3/pkg/chart/loader"
@@ -1368,7 +1368,7 @@ func getDependencyArgs(ctx context.Context, k8sClient client.Client, depName str
_, depErr := FetchAddonRelatedApp(ctx, k8sClient, depName)
if depErr != nil {
if !apierrors.IsNotFound(depErr) {
return nil, err
return nil, depErr
}
depArgs := map[string]interface{}{}
if addonClusters != nil {
@@ -1626,8 +1626,8 @@ func (h *Installer) renderNotes(addon *InstallPackage) (string, error) {
}
notesFile := contextFile + "\n" + addon.Notes.Data
val := cuecontext.New().CompileString(notesFile)
if val.Err() != nil {
return "", errors.Wrap(err, "build values for NOTES.cue")
if valErr := val.Err(); valErr != nil {
return "", errors.Wrap(valErr, "build values for NOTES.cue")
}
notes := val.LookupPath(cue.ParsePath(KeyWordNotes))
if !notes.Exists() {

View File

@@ -378,7 +378,8 @@ func TestGetAddonStatus(t *testing.T) {
})
cli := test.MockClient{
MockGet: getFunc,
MockGet: getFunc,
MockList: listFunc,
}
cases := []struct {
@@ -410,6 +411,10 @@ func TestGetAddonStatus(t *testing.T) {
}
}
func listFunc(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
return nil
}
func TestGetAddonVersionMeetSystemRequirement(t *testing.T) {
server := httptest.NewServer(helmHandler)
defer server.Close()

View File

@@ -123,6 +123,14 @@ func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli cli
// GetAddonStatus is general func for cli and apiServer get addon status
func GetAddonStatus(ctx context.Context, cli client.Client, name string) (Status, error) {
var addonStatus Status
joinedClusters, err := multicluster.NewClusterClient(cli).List(ctx)
if err != nil {
return addonStatus, errors.Wrap(err, "failed to list registered clusters")
}
var joinedClusterMap = make(map[string]bool)
for _, joinedCluster := range joinedClusters.Items {
joinedClusterMap[joinedCluster.Name] = true
}
app, err := FetchAddonRelatedApp(ctx, cli, name)
if err != nil {
@@ -143,8 +151,12 @@ func GetAddonStatus(ctx context.Context, cli client.Client, name string) (Status
r.Cluster = multicluster.ClusterLocalName
}
// TODO(wonderflow): we should collect all the necessary information as observability, currently we only collect cluster name
clusters[r.Cluster] = make(map[string]interface{})
// If cluster is not registered in KubeVela then skip it.
if joinedClusterMap[r.Cluster] {
clusters[r.Cluster] = make(map[string]interface{})
}
}
addonStatus.Clusters = clusters
if app.Status.Workflow != nil && app.Status.Workflow.Suspend {

View File

@@ -158,7 +158,7 @@ func (p *PushCmd) Push(ctx context.Context) error {
}
_, _ = fmt.Fprintf(os.Stderr, "Pushing %s to %s... ",
color.New(color.Bold).Sprintf(filepath.Base(chartPackagePath)),
color.New(color.Bold).Sprintf("%s", filepath.Base(chartPackagePath)),
formatRepoNameAndURL(p.RepoName, repo.Config.URL),
)
@@ -294,7 +294,7 @@ func formatRepoNameAndURL(name, url string) string {
}
return fmt.Sprintf("%s(%s)",
color.New(color.Bold).Sprintf(name),
color.New(color.Bold).Sprintf("%s", name),
color.BlueString(url),
)
}

View File

@@ -19,7 +19,7 @@ package addon
import (
"encoding/base64"
"github.com/xanzy/go-gitlab"
gitlab "gitlab.com/gitlab-org/api/client-go"
"github.com/oam-dev/kubevela/pkg/utils"
)

View File

@@ -26,7 +26,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/xanzy/go-gitlab"
gitlab "gitlab.com/gitlab-org/api/client-go"
"github.com/oam-dev/kubevela/pkg/utils"
)

View File

@@ -24,7 +24,7 @@ import (
"github.com/go-resty/resty/v2"
"github.com/pkg/errors"
"github.com/xanzy/go-gitlab"
gitlab "gitlab.com/gitlab-org/api/client-go"
"github.com/oam-dev/kubevela/pkg/utils"
)

View File

@@ -37,6 +37,7 @@ import (
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/oam"
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
)
// NewLiveDiffOption creates a live-diff option
@@ -118,9 +119,11 @@ func (l *LiveDiffOption) RenderlessDiff(ctx context.Context, base, comparor Live
switch {
case obj.Application != nil:
app = obj.Application.DeepCopy()
ctx = context.WithValue(ctx, oamutil.AppDefinitionNamespace, app.Namespace)
af, err = l.Parser.GenerateAppFileFromApp(ctx, obj.Application)
case obj.ApplicationRevision != nil:
app = obj.ApplicationRevision.Spec.Application.DeepCopy()
ctx = context.WithValue(ctx, oamutil.AppDefinitionNamespace, app.Namespace)
af, err = l.Parser.GenerateAppFileFromRevision(obj.ApplicationRevision)
default:
err = errors.Errorf("either application or application revision should be set for LiveDiffObject")

View File

@@ -109,9 +109,15 @@ func (d *Option) ValidateApp(ctx context.Context, filename string) error {
if err != nil {
return err
}
if len(app.GetNamespace()) == 0 {
namespace := oamutil.GetDefinitionNamespaceWithCtx(ctx)
if namespace != "" {
app.SetNamespace(namespace)
} else if len(app.GetNamespace()) == 0 {
app.SetNamespace(corev1.NamespaceDefault)
}
app2 := app.DeepCopy()
err = d.Client.Get(ctx, client.ObjectKey{Namespace: app.GetNamespace(), Name: app.GetName()}, app2)

View File

@@ -52,11 +52,11 @@ import (
)
// TemplateLoaderFn load template of a capability definition
type TemplateLoaderFn func(context.Context, client.Client, string, types.CapType) (*Template, error)
type TemplateLoaderFn func(context.Context, client.Client, string, types.CapType, map[string]string) (*Template, error)
// LoadTemplate load template of a capability definition
func (fn TemplateLoaderFn) LoadTemplate(ctx context.Context, c client.Client, capName string, capType types.CapType) (*Template, error) {
return fn(ctx, c, capName, capType)
func (fn TemplateLoaderFn) LoadTemplate(ctx context.Context, c client.Client, capName string, capType types.CapType, annotations map[string]string) (*Template, error) {
return fn(ctx, c, capName, capType, annotations)
}
// Parser is an application parser
@@ -104,7 +104,7 @@ func (p *Parser) GenerateAppFileFromApp(ctx context.Context, app *v1beta1.Applic
for idx := range app.Spec.Policies {
if app.Spec.Policies[idx].Name == "" {
app.Spec.Policies[idx].Name = fmt.Sprintf("%s:auto-gen:%d", app.Spec.Policies[idx].Type, idx)
app.Spec.Policies[idx].Name = fmt.Sprintf("%s-auto-gen-%d", app.Spec.Policies[idx].Type, idx)
}
}
@@ -253,7 +253,8 @@ func (p *Parser) parseWorkflowStepsForLegacyRevision(ctx context.Context, af *Ap
continue
}
def := &v1beta1.WorkflowStepDefinition{}
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type); err != nil {
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type, af.app.Annotations); err != nil {
return errors.Wrapf(err, "failed to get workflow step definition %s", workflowStep.Type)
}
af.RelatedWorkflowStepDefinitions[workflowStep.Type] = def
@@ -383,7 +384,7 @@ func (p *Parser) parsePolicies(ctx context.Context, af *Appfile) (err error) {
af.RelatedTraitDefinitions[def.Name] = def
}
default:
w, err := p.makeComponent(ctx, policy.Name, policy.Type, types.TypePolicy, policy.Properties)
w, err := p.makeComponent(ctx, policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.app.Annotations)
if err != nil {
return err
}
@@ -471,15 +472,15 @@ func (p *Parser) fetchAndSetWorkflowStepDefinition(ctx context.Context, af *Appf
return nil
}
def := &v1beta1.WorkflowStepDefinition{}
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStepType); err != nil {
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStepType, af.AppAnnotations); err != nil {
return errors.Wrapf(err, "failed to get workflow step definition %s", workflowStepType)
}
af.RelatedWorkflowStepDefinitions[workflowStepType] = def
return nil
}
func (p *Parser) makeComponent(ctx context.Context, name, typ string, capType types.CapType, props *runtime.RawExtension) (*Component, error) {
templ, err := p.tmplLoader.LoadTemplate(ctx, p.client, typ, capType)
func (p *Parser) makeComponent(ctx context.Context, name, typ string, capType types.CapType, props *runtime.RawExtension, annotations map[string]string) (*Component, error) {
templ, err := p.tmplLoader.LoadTemplate(ctx, p.client, typ, capType, annotations)
if err != nil {
return nil, errors.WithMessagef(err, "fetch component/policy type of %s", name)
}
@@ -519,7 +520,7 @@ func (p *Parser) convertTemplate2Component(name, typ string, props *runtime.RawE
func (p *Parser) parseComponents(ctx context.Context, af *Appfile) error {
var comps []*Component
for _, c := range af.app.Spec.Components {
comp, err := p.parseComponent(ctx, c)
comp, err := p.parseComponent(ctx, c, af.app.Annotations)
if err != nil {
return err
}
@@ -568,25 +569,25 @@ func setComponentDefinitionsFromRevision(af *Appfile) {
// parseComponent resolve an ApplicationComponent and generate a Component
// containing ALL information required by an Appfile.
func (p *Parser) parseComponent(ctx context.Context, comp common.ApplicationComponent) (*Component, error) {
workload, err := p.makeComponent(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
func (p *Parser) parseComponent(ctx context.Context, comp common.ApplicationComponent, annotations map[string]string) (*Component, error) {
workload, err := p.makeComponent(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, annotations)
if err != nil {
return nil, err
}
if err = p.parseTraits(ctx, workload, comp); err != nil {
if err = p.parseTraits(ctx, workload, comp, annotations); err != nil {
return nil, err
}
return workload, nil
}
func (p *Parser) parseTraits(ctx context.Context, workload *Component, comp common.ApplicationComponent) error {
func (p *Parser) parseTraits(ctx context.Context, workload *Component, comp common.ApplicationComponent, annotations map[string]string) error {
for _, traitValue := range comp.Traits {
properties, err := util.RawExtension2Map(traitValue.Properties)
if err != nil {
return errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
}
trait, err := p.parseTrait(ctx, traitValue.Type, properties)
trait, err := p.parseTrait(ctx, traitValue.Type, properties, annotations)
if err != nil {
return errors.WithMessagef(err, "component(%s) parse trait(%s)", comp.Name, traitValue.Type)
}
@@ -649,7 +650,7 @@ func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRe
func (p *Parser) ParseComponentFromRevisionAndClient(ctx context.Context, c common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Component, error) {
comp, err := p.makeComponentFromRevision(c.Name, c.Type, types.TypeComponentDefinition, c.Properties, appRev)
if IsNotFoundInAppRevision(err) {
comp, err = p.makeComponent(ctx, c.Name, c.Type, types.TypeComponentDefinition, c.Properties)
comp, err = p.makeComponent(ctx, c.Name, c.Type, types.TypeComponentDefinition, c.Properties, appRev.Annotations)
}
if err != nil {
return nil, err
@@ -662,7 +663,7 @@ func (p *Parser) ParseComponentFromRevisionAndClient(ctx context.Context, c comm
}
trait, err := p.parseTraitFromRevision(traitValue.Type, properties, appRev)
if IsNotFoundInAppRevision(err) {
trait, err = p.parseTrait(ctx, traitValue.Type, properties)
trait, err = p.parseTrait(ctx, traitValue.Type, properties, appRev.Annotations)
}
if err != nil {
return nil, errors.WithMessagef(err, "component(%s) parse trait(%s)", c.Name, traitValue.Type)
@@ -674,8 +675,8 @@ func (p *Parser) ParseComponentFromRevisionAndClient(ctx context.Context, c comm
return comp, nil
}
func (p *Parser) parseTrait(ctx context.Context, name string, properties map[string]interface{}) (*Trait, error) {
templ, err := p.tmplLoader.LoadTemplate(ctx, p.client, name, types.TypeTrait)
func (p *Parser) parseTrait(ctx context.Context, name string, properties map[string]interface{}, annotations map[string]string) (*Trait, error) {
templ, err := p.tmplLoader.LoadTemplate(ctx, p.client, name, types.TypeTrait, annotations)
if kerrors.IsNotFound(err) {
return nil, errors.Errorf("trait definition of %s not found", name)
}

View File

@@ -559,7 +559,7 @@ func TestParser_parseTraits(t *testing.T) {
},
},
},
mockTemplateLoaderFn: func(context.Context, client.Client, string, types.CapType) (*Template, error) {
mockTemplateLoaderFn: func(context.Context, client.Client, string, types.CapType, map[string]string) (*Template, error) {
return nil, fmt.Errorf("unsupported key not found")
},
wantErr: assert.Error,
@@ -580,7 +580,7 @@ func TestParser_parseTraits(t *testing.T) {
workload: &Component{},
},
wantErr: assert.NoError,
mockTemplateLoaderFn: func(ctx context.Context, reader client.Client, s string, capType types.CapType) (*Template, error) {
mockTemplateLoaderFn: func(ctx context.Context, reader client.Client, s string, capType types.CapType, annotations map[string]string) (*Template, error) {
return &Template{
TemplateStr: "template",
CapabilityCategory: "network",
@@ -598,7 +598,8 @@ func TestParser_parseTraits(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p.tmplLoader = tt.mockTemplateLoaderFn
err := p.parseTraits(context.Background(), tt.args.workload, tt.args.comp)
annotations := make(map[string]string)
err := p.parseTraits(context.Background(), tt.args.workload, tt.args.comp, annotations)
tt.wantErr(t, err, fmt.Sprintf("parseTraits(%v, %v)", tt.args.workload, tt.args.comp))
if tt.validateFunc != nil {
assert.True(t, tt.validateFunc(tt.args.workload))

View File

@@ -66,13 +66,13 @@ type Template struct {
// LoadTemplate gets the capability definition from cluster and resolve it.
// It returns a helper struct, Template, which will be used for further
// processing.
func LoadTemplate(ctx context.Context, cli client.Client, capName string, capType types.CapType) (*Template, error) {
func LoadTemplate(ctx context.Context, cli client.Client, capName string, capType types.CapType, annotations map[string]string) (*Template, error) {
ctx = multicluster.WithCluster(ctx, multicluster.Local)
// Application Controller only loads template from ComponentDefinition and TraitDefinition
switch capType {
case types.TypeComponentDefinition, types.TypeWorkload:
cd := new(v1beta1.ComponentDefinition)
err := oamutil.GetCapabilityDefinition(ctx, cli, cd, capName)
err := oamutil.GetCapabilityDefinition(ctx, cli, cd, capName, annotations)
if err != nil {
if kerrors.IsNotFound(err) {
wd := new(v1beta1.WorkloadDefinition)
@@ -108,7 +108,7 @@ func LoadTemplate(ctx context.Context, cli client.Client, capName string, capTyp
case types.TypeTrait:
td := new(v1beta1.TraitDefinition)
err := oamutil.GetCapabilityDefinition(ctx, cli, td, capName)
err := oamutil.GetCapabilityDefinition(ctx, cli, td, capName, annotations)
if err != nil {
return nil, errors.WithMessagef(err, "load template from trait definition [%s] ", capName)
}
@@ -119,7 +119,7 @@ func LoadTemplate(ctx context.Context, cli client.Client, capName string, capTyp
return tmpl, nil
case types.TypePolicy:
d := new(v1beta1.PolicyDefinition)
err := oamutil.GetCapabilityDefinition(ctx, cli, d, capName)
err := oamutil.GetCapabilityDefinition(ctx, cli, d, capName, annotations)
if err != nil {
return nil, errors.WithMessagef(err, "load template from policy definition [%s] ", capName)
}
@@ -130,7 +130,7 @@ func LoadTemplate(ctx context.Context, cli client.Client, capName string, capTyp
return tmpl, nil
case types.TypeWorkflowStep:
d := new(v1beta1.WorkflowStepDefinition)
err := oamutil.GetCapabilityDefinition(ctx, cli, d, capName)
err := oamutil.GetCapabilityDefinition(ctx, cli, d, capName, annotations)
if err != nil {
return nil, errors.WithMessagef(err, "load template from workflow step definition [%s] ", capName)
}
@@ -252,7 +252,7 @@ func verifyRevisionName(capName string, capType types.CapType, apprev *v1beta1.A
// LoadTemplate, but load template from provided ones before loading from
// cluster through LoadTemplate
func DryRunTemplateLoader(defs []*unstructured.Unstructured) TemplateLoaderFn {
return func(ctx context.Context, r client.Client, capName string, capType types.CapType) (*Template, error) {
return func(ctx context.Context, r client.Client, capName string, capType types.CapType, annotations map[string]string) (*Template, error) {
// retrieve provided cap definitions
for _, def := range defs {
if def.GetKind() == v1beta1.ComponentDefinitionKind &&
@@ -282,7 +282,7 @@ func DryRunTemplateLoader(defs []*unstructured.Unstructured) TemplateLoaderFn {
}
// not found in provided cap definitions
// then try to retrieve from cluster
tmpl, err := LoadTemplate(ctx, r, capName, capType)
tmpl, err := LoadTemplate(ctx, r, capName, capType, annotations)
if err != nil {
return nil, errors.WithMessagef(err, "cannot load template %q from cluster and provided ones", capName)
}

View File

@@ -111,8 +111,8 @@ spec:
return nil
},
}
temp, err := LoadTemplate(context.TODO(), &tclient, "worker", types.TypeComponentDefinition)
var annotations = make(map[string]string)
temp, err := LoadTemplate(context.TODO(), &tclient, "worker", types.TypeComponentDefinition, annotations)
if err != nil {
t.Error(err)
@@ -219,8 +219,8 @@ spec:
return nil
},
}
temp, err := LoadTemplate(context.TODO(), &tclient, "ingress", types.TypeTrait)
var annotations = make(map[string]string)
temp, err := LoadTemplate(context.TODO(), &tclient, "ingress", types.TypeTrait, annotations)
if err != nil {
t.Error(err)
@@ -362,8 +362,9 @@ spec:
TraitDefinition: traitDef,
}
var annotations = make(map[string]string)
dryRunLoadTemplate := DryRunTemplateLoader([]*unstructured.Unstructured{unstrctCompDef, unstrctTraitDef})
compTmpl, err := dryRunLoadTemplate(nil, nil, "myworker", types.TypeComponentDefinition)
compTmpl, err := dryRunLoadTemplate(nil, nil, "myworker", types.TypeComponentDefinition, annotations)
if err != nil {
t.Error("failed load template of component defintion", err)
}
@@ -371,7 +372,7 @@ spec:
t.Fatal("failed load template of component defintion", diff)
}
traitTmpl, err := dryRunLoadTemplate(nil, nil, "myingress", types.TypeTrait)
traitTmpl, err := dryRunLoadTemplate(nil, nil, "myingress", types.TypeTrait, annotations)
if err != nil {
t.Error("failed load template of component defintion", err)
}

View File

@@ -17,7 +17,17 @@ limitations under the License.
package appfile
import (
"encoding/json"
"fmt"
"strings"
"cuelang.org/go/cue"
"github.com/jeremywohl/flatten/v2"
"github.com/kubevela/pkg/cue/cuex"
"github.com/kubevela/workflow/pkg/cue/model/value"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"github.com/oam-dev/kubevela/pkg/features"
"github.com/pkg/errors"
@@ -36,11 +46,20 @@ func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
if wl.CapabilityCategory != types.CUECategory || wl.Type == v1alpha1.RefObjectsComponentType {
continue
}
ctxData := GenerateContextDataFromAppFile(a, wl.Name)
if utilfeature.DefaultMutableFeatureGate.Enabled(features.EnableCueValidation) {
err := p.ValidateComponentParams(ctxData, wl, a)
if err != nil {
return err
}
}
pCtx, err := newValidationProcessContext(wl, ctxData)
if err != nil {
return errors.WithMessagef(err, "cannot create the validation process context of app=%s in namespace=%s", a.Name, a.Namespace)
}
for _, tr := range wl.Traits {
if tr.CapabilityCategory != types.CUECategory {
continue
@@ -53,6 +72,225 @@ func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
return nil
}
// ValidateComponentParams performs CUElevel validation for a Components
// parameters and emits helpful, contextrich errors.
//
// Flow
// 1. Assemble a synthetic CUE document (template + params + app context).
// 2. Compile it; if compilation fails, return the compiler error.
// 3. When the EnableCueValidation gate is on, ensure *all* nonoptional,
// nondefaulted parameters are provided—either in the Component.Params
// block or as workflowstep inputs.
// 4. Run cue.Value.Validate to enforce usersupplied values against
// template constraints.
func (p *Parser) ValidateComponentParams(ctxData velaprocess.ContextData, wl *Component, app *Appfile) error {
// ---------------------------------------------------------------------
// 1. Build synthetic CUE source
// ---------------------------------------------------------------------
ctx := velaprocess.NewContext(ctxData)
baseCtx, err := ctx.BaseContextFile()
if err != nil {
return errors.WithStack(err)
}
paramSnippet, err := cueParamBlock(wl.Params)
if err != nil {
return errors.WithMessagef(err, "component %q: invalid params", wl.Name)
}
cueSrc := strings.Join([]string{
renderTemplate(wl.FullTemplate.TemplateStr),
paramSnippet,
baseCtx,
}, "\n")
val, err := cuex.DefaultCompiler.Get().CompileString(ctx.GetCtx(), cueSrc)
if err != nil {
return errors.WithMessagef(err, "component %q: CUE compile error", wl.Name)
}
// ---------------------------------------------------------------------
// 2. Strict requiredfield enforcement (featuregated)
// ---------------------------------------------------------------------
if err := enforceRequiredParams(val, wl.Params, app); err != nil {
return errors.WithMessagef(err, "component %q", wl.Name)
}
// ---------------------------------------------------------------------
// 3. Validate concrete values
// ---------------------------------------------------------------------
paramVal := val.LookupPath(value.FieldPath(velaprocess.ParameterFieldName))
if err := paramVal.Validate(cue.Concrete(false)); err != nil {
return errors.WithMessagef(err, "component %q: parameter constraint violation", wl.Name)
}
return nil
}
// cueParamBlock marshals the Params map into a `parameter:` block suitable
// for inclusion in a CUE document.
func cueParamBlock(params map[string]any) (string, error) {
if len(params) == 0 {
return velaprocess.ParameterFieldName + ": {}", nil
}
b, err := json.Marshal(params)
if err != nil {
return "", err
}
return fmt.Sprintf("%s: %s", velaprocess.ParameterFieldName, string(b)), nil
}
// enforceRequiredParams checks that every required field declared in the
// templates `parameter:` stanza is satisfied either directly (Params) or
// indirectly (workflowstep inputs). It returns an error describing any
// missing keys.
func enforceRequiredParams(root cue.Value, params map[string]any, app *Appfile) error {
requiredParams, err := requiredFields(root.LookupPath(value.FieldPath(velaprocess.ParameterFieldName)))
if err != nil {
return err
}
// filter out params that are initialized directly
requiredParams, err = filterMissing(requiredParams, params)
if err != nil {
return err
}
// if there are still required params not initialized
if len(requiredParams) > 0 {
// collect params that are initialized in workflow steps
wfInitParams := make(map[string]bool)
for _, step := range app.WorkflowSteps {
for _, in := range step.Inputs {
wfInitParams[in.ParameterKey] = true
}
}
for _, p := range app.Policies {
if p.Type != "override" {
continue
}
var spec overrideSpec
if err := json.Unmarshal(p.Properties.Raw, &spec); err != nil {
return fmt.Errorf("override policy %q: parse properties: %w", p.Name, err)
}
for _, c := range spec.Components {
if len(c.Properties) == 0 {
continue
}
flat, err := flatten.Flatten(c.Properties, "", flatten.DotStyle)
if err != nil {
return fmt.Errorf("override policy %q: flatten properties: %w", p.Name, err)
}
for k := range flat {
wfInitParams[k] = true // idempotent set-style insert
}
}
}
// collect required params that were not initialized even in workflow steps
var missingParams []string
for _, key := range requiredParams {
if !wfInitParams[key] {
missingParams = append(missingParams, key)
}
}
if len(missingParams) > 0 {
return fmt.Errorf("missing parameters: %v", strings.Join(missingParams, ","))
}
}
return nil
}
type overrideSpec struct {
Components []struct {
Properties map[string]any `json:"properties"`
} `json:"components"`
}
// requiredFields returns the list of "parameter" fields that must be supplied
// by the caller. Nested struct leaves are returned as dot-separated paths.
//
// Rules:
// - A field with a trailing '?' is optional -> ignore
// - A field that has a default (*value | …) is optional -> ignore
// - Everything else is required.
// - Traverses arbitrarily deep into structs.
func requiredFields(v cue.Value) ([]string, error) {
var out []string
err := collect("", v, &out)
return out, err
}
func collect(prefix string, v cue.Value, out *[]string) error {
// Only structs can contain nested required fields.
if v.Kind() != cue.StructKind {
return nil
}
it, err := v.Fields(
cue.Optional(false),
cue.Definitions(false),
cue.Hidden(false),
)
if err != nil {
return err
}
for it.Next() {
// Skip fields that provide a default (*").
if _, hasDef := it.Value().Default(); hasDef {
continue
}
label := it.Selector().Unquoted()
path := label
if prefix != "" {
path = prefix + "." + label
}
// Recurse if the value itself is a struct; otherwise record the leaf.
if it.Value().Kind() == cue.StructKind {
if err := collect(path, it.Value(), out); err != nil {
return err
}
} else {
*out = append(*out, path)
}
}
return nil
}
// filterMissing removes every key that is already present in the provided map.
//
// It reuses the original slices backing array to avoid allocations.
func filterMissing(keys []string, provided map[string]any) ([]string, error) {
flattenProvided, err := flatten.Flatten(provided, "", flatten.DotStyle)
if err != nil {
return nil, err
}
out := keys[:0]
for _, k := range keys {
if _, ok := flattenProvided[k]; !ok {
out = append(out, k)
}
}
return out, nil
}
// renderTemplate appends the placeholders expected by KubeVelas template
// compiler so that the generated snippet is always syntactically complete.
func renderTemplate(tmpl string) string {
return tmpl + `
context: _
parameter: _
`
}
func newValidationProcessContext(c *Component, ctxData velaprocess.ContextData) (process.Context, error) {
baseHooks := []process.BaseHook{
// add more hook funcs here to validate CUE base

View File

@@ -151,3 +151,114 @@ var _ = Describe("Test validate CUE schematic Appfile", func() {
}),
)
})
var _ = Describe("Test ValidateComponentParams", func() {
type ParamTestCase struct {
name string
template string
params map[string]interface{}
wantErr string
}
DescribeTable("ValidateComponentParams cases", func(tc ParamTestCase) {
wl := &Component{
Name: tc.name,
Type: "worker",
FullTemplate: &Template{TemplateStr: tc.template},
Params: tc.params,
}
app := &Appfile{
Name: "myapp",
Namespace: "test-ns",
}
ctxData := GenerateContextDataFromAppFile(app, wl.Name)
parser := &Parser{}
err := parser.ValidateComponentParams(ctxData, wl, app)
if tc.wantErr == "" {
Expect(err).To(BeNil())
} else {
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring(tc.wantErr))
}
},
Entry("valid params and template", ParamTestCase{
name: "valid",
template: `
parameter: {
replicas: int | *1
}
output: {
apiVersion: "apps/v1"
kind: "Deployment"
}
`,
params: map[string]interface{}{
"replicas": 2,
},
wantErr: "",
}),
Entry("invalid CUE in template", ParamTestCase{
name: "invalid-cue",
template: `
parameter: {
replicas: int | *1
}
output: {
apiVersion: "apps/v1"
kind: "Deployment"
invalidField: {
}
`,
params: map[string]interface{}{
"replicas": 2,
},
wantErr: "CUE compile error",
}),
Entry("missing required parameter", ParamTestCase{
name: "missing-required",
template: `
parameter: {
replicas: int
}
output: {
apiVersion: "apps/v1"
kind: "Deployment"
}
`,
params: map[string]interface{}{},
wantErr: "component \"missing-required\": missing parameters: replicas",
}),
Entry("parameter constraint violation", ParamTestCase{
name: "constraint-violation",
template: `
parameter: {
replicas: int & >0
}
output: {
apiVersion: "apps/v1"
kind: "Deployment"
}
`,
params: map[string]interface{}{
"replicas": -1,
},
wantErr: "parameter constraint violation",
}),
Entry("invalid parameter block", ParamTestCase{
name: "invalid-param-block",
template: `
parameter: {
replicas: int | *1
}
output: {
apiVersion: "apps/v1"
kind: "Deployment"
}
`,
params: map[string]interface{}{
"replicas": "not-an-int",
},
wantErr: "parameter constraint violation",
}),
)
})

View File

@@ -58,17 +58,17 @@ var _ = Describe("Test dispatch stage", func() {
},
},
}
stage, err := getTraitDispatchStage(k8sClient, "kruise-rollout", &appRev)
var annotations = make(map[string]string)
stage, err := getTraitDispatchStage(k8sClient, "kruise-rollout", &appRev, annotations)
Expect(err).Should(BeNil())
Expect(stage).Should(BeEquivalentTo(PreDispatch))
stage, err = getTraitDispatchStage(k8sClient, "gateway", &appRev)
stage, err = getTraitDispatchStage(k8sClient, "gateway", &appRev, annotations)
Expect(err).Should(BeNil())
Expect(stage).Should(BeEquivalentTo(PostDispatch))
stage, err = getTraitDispatchStage(k8sClient, "hpa", &appRev)
stage, err = getTraitDispatchStage(k8sClient, "hpa", &appRev, annotations)
Expect(err).Should(BeNil())
Expect(stage).Should(BeEquivalentTo(DefaultDispatch))
stage, err = getTraitDispatchStage(k8sClient, "not-exist", &appRev)
stage, err = getTraitDispatchStage(k8sClient, "not-exist", &appRev, annotations)
Expect(err).ShouldNot(BeNil())
Expect(stage).Should(BeEquivalentTo(DefaultDispatch))
})

View File

@@ -112,7 +112,7 @@ type manifestDispatcher struct {
healthCheck func(ctx context.Context, c *appfile.Component, appRev *v1beta1.ApplicationRevision) (bool, error)
}
func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, readyWorkload *unstructured.Unstructured, readyTraits []*unstructured.Unstructured, overrideNamespace string) ([]*manifestDispatcher, error) {
func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, readyWorkload *unstructured.Unstructured, readyTraits []*unstructured.Unstructured, overrideNamespace string, annotations map[string]string) ([]*manifestDispatcher, error) {
dispatcherGenerator := func(options DispatchOptions) *manifestDispatcher {
assembleManifestFn := func(skipApplyWorkload bool) (bool, []*unstructured.Unstructured) {
manifests := options.Traits
@@ -138,7 +138,13 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
}
dispatcher.run = func(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error) {
skipWorkload, dispatchManifests := assembleManifestFn(comp.SkipApplyWorkload)
if isHealth, err := dispatcher.healthCheck(ctx, comp, appRev); !isHealth || err != nil {
var isAutoUpdateEnabled bool
if annotations[oam.AnnotationAutoUpdate] == "true" {
isAutoUpdateEnabled = true
}
if isHealth, err := dispatcher.healthCheck(ctx, comp, appRev); !isHealth || err != nil || (!comp.SkipApplyWorkload && isAutoUpdateEnabled) {
if err := h.Dispatch(ctx, h.Client, clusterName, common.WorkflowResourceCreator, dispatchManifests...); err != nil {
return false, errors.WithMessage(err, "Dispatch")
}
@@ -179,7 +185,7 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
traitType = splitName
}
}
stageType, err = getTraitDispatchStage(h.Client, traitType, appRev)
stageType, err = getTraitDispatchStage(h.Client, traitType, appRev, annotations)
if err != nil {
return nil, err
}
@@ -210,11 +216,11 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
return manifestDispatchers, nil
}
func getTraitDispatchStage(client client.Client, traitType string, appRev *v1beta1.ApplicationRevision) (StageType, error) {
func getTraitDispatchStage(client client.Client, traitType string, appRev *v1beta1.ApplicationRevision, annotations map[string]string) (StageType, error) {
trait, ok := appRev.Spec.TraitDefinitions[traitType]
if !ok {
trait = &v1beta1.TraitDefinition{}
err := oamutil.GetCapabilityDefinition(context.Background(), client, trait, traitType)
err := oamutil.GetCapabilityDefinition(context.Background(), client, trait, traitType, annotations)
if err != nil {
return DefaultDispatch, err
}

View File

@@ -372,7 +372,7 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, af *appfile.A
isHealth := true
if utilfeature.DefaultMutableFeatureGate.Enabled(features.MultiStageComponentApply) {
manifestDispatchers, err := h.generateDispatcher(appRev, readyWorkload, readyTraits, overrideNamespace)
manifestDispatchers, err := h.generateDispatcher(appRev, readyWorkload, readyTraits, overrideNamespace, af.AppAnnotations)
if err != nil {
return nil, nil, false, errors.WithMessage(err, "generateDispatcher")
}

View File

@@ -194,6 +194,18 @@ var _ = Describe("Test DefinitionRevision created by ComponentDefinition", func(
Expect(defRev1.Spec.RevisionHash).Should(Equal(defRev2.Spec.RevisionHash))
})
It("Test ComponentDefinition with name specified in spec.version, Should create definitaion with specified name", func() {
cd := cdWithNoTemplate.DeepCopy()
cd.Name = "test-cd-with-custom-version"
cd.Spec.Version = "1.3.0"
cd.Spec.Schematic.CUE.Template = fmt.Sprintf(cdTemplate, "test-defrev")
defRev, _, err := coredef.GenerateDefinitionRevision(ctx, r.Client, cd)
Expect(err).Should(BeNil())
Expect(defRev.Name).Should(Equal("test-cd-with-custom-version-v1.3.0"))
})
It("Test only update ComponentDefinition Labels, Shouldn't create new revision", func() {
cd := cdWithNoTemplate.DeepCopy()
cdName := "test-cd"
@@ -258,6 +270,29 @@ var _ = Describe("Test DefinitionRevision created by ComponentDefinition", func(
By("check the DefinitionRevision's RevisionNum")
Expect(cdRev.Spec.Revision).Should(Equal(int64(1)))
})
It("Test specified DefinitionRevision name in spec.version", func() {
cdName := "test-specified-defrev1-name"
req := reconcile.Request{NamespacedName: client.ObjectKey{Name: cdName, Namespace: namespace}}
cd := cdWithNoTemplate.DeepCopy()
cd.Name = cdName
cd.Spec.Schematic.CUE.Template = fmt.Sprintf(cdTemplate, "test")
cd.Spec.Version = "1.1.3"
By("create componentDefinition")
Expect(k8sClient.Create(ctx, cd)).Should(SatisfyAll(BeNil()))
testutil.ReconcileRetry(&r, req)
By("check whether DefinitionRevision is created")
cdRevName := fmt.Sprintf("%s-v1.1.3", cdName)
var cdRev v1beta1.DefinitionRevision
Eventually(func() error {
return k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: cdRevName}, &cdRev)
}, 10*time.Second, time.Second).Should(BeNil())
By("check the DefinitionRevision's RevisionNum")
Expect(cdRev.Spec.Revision).Should(Equal(int64(1)))
})
})
Context("Test ComponentDefinition Controller clean up", func() {
@@ -381,7 +416,7 @@ var _ = Describe("Test DefinitionRevision created by ComponentDefinition", func(
}, time.Second*30, time.Microsecond*300).Should(BeNil())
})
It("Test clean up definitionRevision contains definitionRevision with custom name", func() {
It("Test clean up definitionRevision contains definitionRevision with custom name using annotation", func() {
var revKey client.ObjectKey
var defRev v1beta1.DefinitionRevision
revisionNames := []string{"1.3.1", "", "1.3.3", "", "prod"}

View File

@@ -32,6 +32,7 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
coredef "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/core"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/testutil"
"github.com/oam-dev/kubevela/pkg/oam/util"
@@ -128,6 +129,17 @@ var _ = Describe("Test DefinitionRevision created by PolicyDefinition", func() {
newRevKey := client.ObjectKey{Namespace: namespace, Name: newDefRevName}
Expect(k8sClient.Get(ctx, newRevKey, &defRev)).Should(HaveOccurred())
})
It("Test Policy Definition with name specified in spec.version, Should create definitaion with specified name", func() {
def := defWithNoTemplate.DeepCopy()
def.Name = "test-policy-def-custom-version"
def.Spec.Version = "1.3.0"
def.Spec.Schematic.CUE.Template = fmt.Sprintf(defTemplate, "test-defrev")
defRev, _, err := coredef.GenerateDefinitionRevision(ctx, r.Client, def)
Expect(err).Should(BeNil())
Expect(defRev.Name).Should(Equal("test-policy-def-custom-version-v1.3.0"))
})
})
Context("Test PolicyDefinition Controller clean up", func() {

View File

@@ -22,10 +22,12 @@ import (
"sort"
"strings"
"github.com/Masterminds/semver"
"github.com/crossplane/crossplane-runtime/pkg/event"
"github.com/pkg/errors"
apiequality "k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
@@ -44,12 +46,20 @@ import (
// GenerateDefinitionRevision will generate a definition revision the generated revision
// will be compare with the last revision to see if there's any difference.
func GenerateDefinitionRevision(ctx context.Context, cli client.Client, def runtime.Object) (*v1beta1.DefinitionRevision, bool, error) {
isNamedRev, defRevNamespacedName, err := isNamedRevision(def)
isSpecVersion, defRevNamespacedName, err := isSpecVersionRevision(def)
if err != nil {
return nil, false, err
}
if isSpecVersion {
return generateDefinitionRevision(ctx, cli, def, defRevNamespacedName)
}
isNamedRev, defRevNamespacedName, err := isNameAnnotationRevision(def)
if err != nil {
return nil, false, err
}
if isNamedRev {
return generateNamedDefinitionRevision(ctx, cli, def, defRevNamespacedName)
return generateDefinitionRevision(ctx, cli, def, defRevNamespacedName)
}
defRev, lastRevision, err := GatherRevisionInfo(def)
@@ -68,7 +78,9 @@ func GenerateDefinitionRevision(ctx context.Context, cli client.Client, def runt
return defRev, isNewRev, nil
}
func isNamedRevision(def runtime.Object) (bool, types.NamespacedName, error) {
// isNameAnnotationRevision is for Definition Version specified in the
// Definition's "definitionrevision.oam.dev/name" annotation.
func isNameAnnotationRevision(def runtime.Object) (bool, types.NamespacedName, error) {
defMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(def)
if err != nil {
return false, types.NamespacedName{}, err
@@ -86,7 +98,42 @@ func isNamedRevision(def runtime.Object) (bool, types.NamespacedName, error) {
return true, types.NamespacedName{Name: defRevName, Namespace: defNs}, nil
}
func generateNamedDefinitionRevision(ctx context.Context, cli client.Client, def runtime.Object, defRevNamespacedName types.NamespacedName) (*v1beta1.DefinitionRevision, bool, error) {
// isSpecVersionRevision is for Definition Version specified in the Definition spec.Version
func isSpecVersionRevision(def runtime.Object) (bool, types.NamespacedName, error) {
var definitionVersion, definitionNamespace, definitionName string
switch definition := def.(type) {
case *v1beta1.ComponentDefinition:
definitionVersion = definition.Spec.Version
definitionNamespace = definition.Namespace
definitionName = definition.Name
case *v1beta1.TraitDefinition:
definitionVersion = definition.Spec.Version
definitionNamespace = definition.Namespace
definitionName = definition.Name
case *v1beta1.PolicyDefinition:
definitionVersion = definition.Spec.Version
definitionNamespace = definition.Namespace
definitionName = definition.Name
case *v1beta1.WorkflowStepDefinition:
definitionVersion = definition.Spec.Version
definitionNamespace = definition.Namespace
definitionName = definition.Name
}
if definitionVersion == "" {
return false, types.NamespacedName{}, nil
}
semVersion, err := semver.NewVersion(definitionVersion)
if err != nil {
return false, types.NamespacedName{}, err
}
definitionRevisionName := ConstructDefinitionRevisionName(definitionName, semVersion.String())
return true, types.NamespacedName{Name: definitionRevisionName, Namespace: definitionNamespace}, nil
}
func generateDefinitionRevision(ctx context.Context, cli client.Client, def runtime.Object, defRevNamespacedName types.NamespacedName) (*v1beta1.DefinitionRevision, bool, error) {
oldDefRev := new(v1beta1.DefinitionRevision)
// definitionRevision is immutable, if the requested definitionRevision already exists, return directly.
@@ -118,21 +165,48 @@ func GatherRevisionInfo(def runtime.Object) (*v1beta1.DefinitionRevision, *commo
defRev.Spec.DefinitionType = common.ComponentType
defRev.Spec.ComponentDefinition = *copiedCompDef
LastRevision = copiedCompDef.Status.LatestRevision
defRev.ObjectMeta.OwnerReferences = []metav1.OwnerReference{{
APIVersion: copiedCompDef.APIVersion,
Kind: copiedCompDef.Kind,
Name: copiedCompDef.Name,
UID: copiedCompDef.UID,
}}
case *v1beta1.TraitDefinition:
copiedTraitDef := definition.DeepCopy()
defRev.Spec.DefinitionType = common.TraitType
defRev.Spec.TraitDefinition = *copiedTraitDef
LastRevision = copiedTraitDef.Status.LatestRevision
defRev.ObjectMeta.OwnerReferences = []metav1.OwnerReference{{
APIVersion: copiedTraitDef.APIVersion,
Kind: copiedTraitDef.Kind,
Name: copiedTraitDef.Name,
UID: copiedTraitDef.UID,
}}
case *v1beta1.PolicyDefinition:
defCopy := definition.DeepCopy()
defRev.Spec.DefinitionType = common.PolicyType
defRev.Spec.PolicyDefinition = *defCopy
LastRevision = defCopy.Status.LatestRevision
defRev.ObjectMeta.OwnerReferences = []metav1.OwnerReference{{
APIVersion: defCopy.APIVersion,
Kind: defCopy.Kind,
Name: defCopy.Name,
UID: defCopy.UID,
}}
case *v1beta1.WorkflowStepDefinition:
defCopy := definition.DeepCopy()
defRev.Spec.DefinitionType = common.WorkflowStepType
defRev.Spec.WorkflowStepDefinition = *defCopy
LastRevision = defCopy.Status.LatestRevision
defRev.ObjectMeta.OwnerReferences = []metav1.OwnerReference{{
APIVersion: defCopy.APIVersion,
Kind: defCopy.Kind,
Name: defCopy.Name,
UID: defCopy.UID,
}}
default:
return nil, nil, fmt.Errorf("unsupported type %v", definition)
}
@@ -230,24 +304,27 @@ func DeepEqualDefRevision(old, new *v1beta1.DefinitionRevision) bool {
return true
}
func getDefNextRevision(defRev *v1beta1.DefinitionRevision, lastRevision *common.Revision) (string, int64) {
func getDefNextRevision(definitionRevision *v1beta1.DefinitionRevision, lastRevision *common.Revision) (string, int64) {
var nextRevision int64 = 1
var definitionRevisionName string
if lastRevision != nil {
nextRevision = lastRevision.Revision + 1
}
var name string
switch defRev.Spec.DefinitionType {
switch definitionRevision.Spec.DefinitionType {
case common.ComponentType:
name = defRev.Spec.ComponentDefinition.Name
name = definitionRevision.Spec.ComponentDefinition.Name
case common.TraitType:
name = defRev.Spec.TraitDefinition.Name
name = definitionRevision.Spec.TraitDefinition.Name
case common.PolicyType:
name = defRev.Spec.PolicyDefinition.Name
name = definitionRevision.Spec.PolicyDefinition.Name
case common.WorkflowStepType:
name = defRev.Spec.WorkflowStepDefinition.Name
name = definitionRevision.Spec.WorkflowStepDefinition.Name
}
defRevName := strings.Join([]string{name, fmt.Sprintf("v%d", nextRevision)}, "-")
return defRevName, nextRevision
definitionRevisionName = strings.Join([]string{name, fmt.Sprintf("v%v", nextRevision)}, "-")
return definitionRevisionName, nextRevision
}
// ConstructDefinitionRevisionName construct the name of DefinitionRevision.

View File

@@ -32,6 +32,7 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
coredef "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/core"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/testutil"
"github.com/oam-dev/kubevela/pkg/oam/util"
@@ -128,6 +129,17 @@ var _ = Describe("Test DefinitionRevision created by TraitDefinition", func() {
newRevKey := client.ObjectKey{Namespace: namespace, Name: newDefRevName}
Expect(k8sClient.Get(ctx, newRevKey, &defRev)).Should(HaveOccurred())
})
It("Test Trait Definition with name specified in spec.version, Should create definitaion with specified name", func() {
td := tdWithNoTemplate.DeepCopy()
td.Name = "test-trait-def-custom-version"
td.Spec.Version = "1.3.0"
td.Spec.Schematic.CUE.Template = fmt.Sprintf(tdTemplate, fmt.Sprintf("test-v%d", 1))
defRev, _, err := coredef.GenerateDefinitionRevision(ctx, r.Client, td)
Expect(err).Should(BeNil())
Expect(defRev.Name).Should(Equal("test-trait-def-custom-version-v1.3.0"))
})
})
Context("Test TraitDefinition Controller clean up", func() {

View File

@@ -32,6 +32,7 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
coredef "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/core"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/testutil"
"github.com/oam-dev/kubevela/pkg/oam/util"
@@ -128,6 +129,16 @@ var _ = Describe("Test DefinitionRevision created by WorkflowStepDefinition", fu
newRevKey := client.ObjectKey{Namespace: namespace, Name: newDefRevName}
Expect(k8sClient.Get(ctx, newRevKey, &defRev)).Should(HaveOccurred())
})
It("Test WorkflowStep Definition with name specified in spec.version, Should create definitaion with specified name", func() {
def := defWithNoTemplate.DeepCopy()
def.Name = "test-workflow-def-custom-version"
def.Spec.Version = "1.3.0"
def.Spec.Schematic.CUE.Template = fmt.Sprintf(defTemplate, fmt.Sprintf("test-v%d", 1))
defRev, _, err := coredef.GenerateDefinitionRevision(ctx, r.Client, def)
Expect(err).Should(BeNil())
Expect(defRev.Name).Should(Equal("test-workflow-def-custom-version-v1.3.0"))
})
})
Context("Test WorkflowStepDefinition Controller clean up", func() {

View File

@@ -0,0 +1,351 @@
/*
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 cuex_test
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/kubevela/pkg/cue/cuex"
corev1 "k8s.io/api/core/v1"
"github.com/kubevela/pkg/util/singleton"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/cue/definition"
"github.com/oam-dev/kubevela/pkg/cue/process"
)
var testCtx = struct {
K8sClient client.Client
ReturnVal string
CueXTestPackage string
Namespace string
CueXPath string
ExternalFnName string
InputParamName string
OutputParamName string
}{
ReturnVal: "external",
CueXTestPackage: "cuex-test-package",
Namespace: "default",
CueXPath: "cuex/ext",
ExternalFnName: "external",
InputParamName: "input",
OutputParamName: "output",
}
func TestMain(m *testing.M) {
testEnv := &envtest.Environment{
CRDDirectoryPaths: []string{
filepath.Join("..", "..", "..", "charts", "vela-core", "crds"),
},
}
var err error
cfg, err := testEnv.Start()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to start envtest: %v\n", err)
os.Exit(1)
}
if cfg == nil {
fmt.Fprintf(os.Stderr, "envtest config is nil")
os.Exit(1)
}
testCtx.K8sClient, err = createK8sClient(cfg)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create k8s Client: %v\n", err)
os.Exit(1)
}
mockServer := createMockServer()
defer mockServer.Close()
singleton.KubeConfig.Set(cfg)
if err = createTestPackage(mockServer.URL); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Setup failed: %v\n", err)
os.Exit(1)
}
defer func() {
if err = deleteTestPackage(); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Teardown failed: %v\n", err)
os.Exit(1)
}
}()
code := m.Run()
singleton.KubeConfig.Reload()
if err := testEnv.Stop(); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed to stop envtest: %v\n", err)
os.Exit(1)
}
os.Exit(code)
}
func TestWorkloadCompiler(t *testing.T) {
testCases := map[string]struct {
cuexEnabled bool
workloadTemplate string
params map[string]interface{}
expectedObj runtime.Object
expectedAdditionalObjs map[string]runtime.Object
hasCompileErr bool
errorString string
}{
"cuex disabled with no external packages": {
cuexEnabled: false,
workloadTemplate: getWorkloadTemplate(false),
params: make(map[string]interface{}),
expectedObj: getExpectedObj(false),
expectedAdditionalObjs: make(map[string]runtime.Object),
hasCompileErr: false,
errorString: "",
},
"cuex enabled with no external packages": {
cuexEnabled: true,
workloadTemplate: getWorkloadTemplate(false),
params: make(map[string]interface{}),
expectedObj: getExpectedObj(false),
expectedAdditionalObjs: make(map[string]runtime.Object),
hasCompileErr: false,
errorString: "",
},
"cuex disabled with external packages": {
cuexEnabled: false,
workloadTemplate: getWorkloadTemplate(true),
params: make(map[string]interface{}),
expectedObj: getExpectedObj(true),
expectedAdditionalObjs: make(map[string]runtime.Object),
hasCompileErr: true,
errorString: "builtin package \"cuex/ext\" undefined",
},
"cuex enabled with external packages": {
cuexEnabled: true,
workloadTemplate: getWorkloadTemplate(true),
params: make(map[string]interface{}),
expectedObj: getExpectedObj(true),
expectedAdditionalObjs: make(map[string]runtime.Object),
hasCompileErr: false,
},
}
for _, tc := range testCases {
cuex.EnableExternalPackageForDefaultCompiler = tc.cuexEnabled
cuex.DefaultCompiler.Reload()
ctx := process.NewContext(process.ContextData{
AppName: "test-app",
CompName: "test-component",
Namespace: testCtx.Namespace,
AppRevisionName: "test-app-v1",
ClusterVersion: types.ClusterVersion{Minor: "19+"},
})
wt := definition.NewWorkloadAbstractEngine("test-workload")
err := wt.Complete(ctx, tc.workloadTemplate, tc.params)
assert.Equal(t, tc.hasCompileErr, err != nil)
if tc.hasCompileErr {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), tc.errorString)
} else {
output, _ := ctx.Output()
assert.Nil(t, err)
assert.NotNil(t, output)
outputObj, _ := output.Unstructured()
assert.Equal(t, tc.expectedObj, outputObj)
}
}
}
func createMockServer() *httptest.Server {
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/"+testCtx.ExternalFnName {
http.Error(w, fmt.Sprintf("unexpected path: %s, expected: /%s", r.URL.Path, testCtx.ExternalFnName), http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(fmt.Sprintf("{\"%s\": \"%s\"}", testCtx.OutputParamName, testCtx.ReturnVal)))
if err != nil {
return
}
}))
return mockServer
}
func createTestPackage(url string) error {
ctx := context.Background()
packageObj := &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "cue.oam.dev/v1alpha1",
"kind": "Package",
"metadata": map[string]interface{}{
"name": testCtx.CueXTestPackage,
"namespace": testCtx.Namespace,
},
"spec": map[string]interface{}{
"path": testCtx.CueXPath,
"provider": map[string]interface{}{
"endpoint": url,
"protocol": "http",
},
"templates": map[string]interface{}{
"ext/cue": strings.TrimSpace(fmt.Sprintf(`
package ext
#ExternalFunction: {
#do: "%s",
#provider: "%s",
$params: {
%s: string
},
$returns: {
%s: string
}
}
`, testCtx.ExternalFnName, testCtx.CueXTestPackage, testCtx.InputParamName, testCtx.OutputParamName)),
},
},
},
}
err := testCtx.K8sClient.Create(ctx, packageObj)
err = wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
err = testCtx.K8sClient.Get(ctx, client.ObjectKey{
Name: testCtx.CueXTestPackage,
Namespace: testCtx.Namespace,
}, packageObj)
if err != nil {
return false, nil
}
return true, nil
})
if err != nil {
return fmt.Errorf("failed to create test package: %w", err)
}
return nil
}
func deleteTestPackage() error {
ctx := context.Background()
testPkg := &unstructured.Unstructured{}
testPkg.SetGroupVersionKind(schema.GroupVersionKind{
Group: "cue.oam.dev",
Version: "v1alpha1",
Kind: "Package",
})
testPkg.SetName(testCtx.CueXTestPackage)
testPkg.SetNamespace(testCtx.Namespace)
err := testCtx.K8sClient.Delete(ctx, testPkg)
if err != nil {
return fmt.Errorf("failed to delete test package: %w", err)
}
err = wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
err := testCtx.K8sClient.Get(ctx, client.ObjectKey{
Name: testCtx.CueXTestPackage,
Namespace: testCtx.Namespace,
}, testPkg)
if err != nil {
if k8serrors.IsNotFound(err) {
return true, nil
}
return false, err
}
return false, nil
})
if err != nil {
return fmt.Errorf("failed to delete test package: %w", err)
}
return nil
}
func getWorkloadTemplate(includeExt bool) string {
tmpl := ""
name := "test-deployment"
if includeExt {
name = "test-deployment-\\(external.$returns.output)"
tmpl = tmpl + strings.TrimSpace(fmt.Sprintf(`
import (
"%s"
)
external: ext.#ExternalFunction & {
$params: {
%s: "external"
}
}
`, testCtx.CueXPath, testCtx.InputParamName)) + "\n"
}
tmpl = tmpl + strings.TrimSpace(fmt.Sprintf(`
output: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: "%s"
spec: replicas: 1
}
`, name))
return tmpl
}
func getExpectedObj(includeExt bool) *unstructured.Unstructured {
name := "test-deployment"
if includeExt {
name = fmt.Sprintf("test-deployment-%s", testCtx.ReturnVal)
}
return &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": name},
"spec": map[string]interface{}{"replicas": int64(1)},
}}
}
func createK8sClient(config *rest.Config) (client.Client, error) {
scheme := runtime.NewScheme()
if err := corev1.AddToScheme(scheme); err != nil {
return nil, fmt.Errorf("failed to add corev1 to scheme: %w", err)
}
return client.New(config, client.Options{Scheme: scheme})
}

View File

@@ -22,6 +22,8 @@ import (
"fmt"
"strings"
"github.com/kubevela/pkg/cue/cuex"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"github.com/kubevela/pkg/multicluster"
@@ -39,10 +41,6 @@ import (
"github.com/oam-dev/kubevela/pkg/cue/task"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"github.com/oam-dev/kubevela/pkg/features"
)
const (
@@ -111,10 +109,14 @@ func (wd *workloadDef) Complete(ctx process.Context, abstractTemplate string, pa
return err
}
val := cuecontext.New().CompileString(strings.Join([]string{
val, err := cuex.DefaultCompiler.Get().CompileString(ctx.GetCtx(), strings.Join([]string{
renderTemplate(abstractTemplate), paramFile, c,
}, "\n"))
if err != nil {
return errors.WithMessagef(err, "failed to compile workload %s after merge parameter and context", wd.name)
}
if err := val.Validate(); err != nil {
return errors.WithMessagef(err, "invalid cue template of workload %s after merge parameter and context", wd.name)
}
@@ -127,14 +129,6 @@ func (wd *workloadDef) Complete(ctx process.Context, abstractTemplate string, pa
return err
}
// Strict Cue required field parameter validation
if utilfeature.DefaultMutableFeatureGate.Enabled(features.EnableCueValidation) {
paramCue := val.LookupPath(value.FieldPath(velaprocess.ParameterFieldName))
if err := paramCue.Validate(cue.Concrete(true)); err != nil {
return errors.WithMessagef(err, "parameter error for %s", wd.name)
}
}
// we will support outputs for workload composition, and it will become trait in AppConfig.
outputs := val.LookupPath(value.FieldPath(OutputsFieldName))
if !outputs.Exists() {
@@ -318,10 +312,16 @@ func (td *traitDef) Complete(ctx process.Context, abstractTemplate string, param
}
buff += c
val := cuecontext.New().CompileString(buff)
val, err := cuex.DefaultCompiler.Get().CompileString(ctx.GetCtx(), buff)
if err != nil {
return errors.WithMessagef(err, "failed to compile trait %s after merge parameter and context", td.name)
}
if err := val.Validate(); err != nil {
return errors.WithMessagef(err, "invalid template of trait %s after merge with parameter and context", td.name)
}
processing := val.LookupPath(value.FieldPath("processing"))
if processing.Exists() {
if val, err = task.Process(val); err != nil {
@@ -386,7 +386,7 @@ func parseErrors(errs cue.Value) error {
if it, e := errs.List(); e == nil {
for it.Next() {
if s, err := it.Value().String(); err == nil && s != "" {
return errors.Errorf(s)
return errors.Errorf("%s", s)
}
}
}

View File

@@ -28,11 +28,6 @@ import (
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/cue/process"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"github.com/oam-dev/kubevela/pkg/features"
)
func TestWorkloadTemplateComplete(t *testing.T) {
@@ -1570,271 +1565,3 @@ parameter: {
assert.Contains(t, err.Error(), v.err)
}
}
func TestWorkloadParamsValidations(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(&testing.T{}, utilfeature.DefaultFeatureGate, features.EnableCueValidation, true)()
testCases := map[string]struct {
workloadTemplate string
params map[string]interface{}
expectObj runtime.Object
expAssObjs map[string]runtime.Object
category types.CapabilityCategory
hasCompileErr bool
errorString string
}{
"Missing Required Param that is used in template": {
workloadTemplate: `
output:{
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: context.name
spec: {
replicas: parameter.replicas
host: parameter.requiredParam
}
}
parameter: {
replicas: *1 | int
type: string
requiredParam!: string
}
`,
params: map[string]interface{}{
"replicas": 2,
"type": "ClusterIP",
},
expectObj: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": "test"},
"spec": map[string]interface{}{"replicas": int64(2)},
}},
hasCompileErr: true,
errorString: "parameter error for testWorkload: parameter.requiredParam: field is required but not present",
},
// Missing Required Param that is not used in template
"Missing Required Param that is not used in template": {
workloadTemplate: `
output:{
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: context.name
spec: {
replicas: parameter.replicas
}
}
parameter: {
replicas: *1 | int
type: string
requiredParam!: string
}
`,
params: map[string]interface{}{
"replicas": 2,
"type": "ClusterIP",
},
expectObj: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": "test"},
"spec": map[string]interface{}{"replicas": int64(2)},
}},
hasCompileErr: true,
errorString: "parameter error for testWorkload: parameter.requiredParam: field is required but not present",
},
//required param that is nested
"required param that is nested": {
workloadTemplate: `
output:{
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: context.name
spec: {
replicas: parameter.replicas
}
}
parameter: {
replicas: *1 | int
type: string
host: requiredParam!: string
}
`,
params: map[string]interface{}{
"replicas": 2,
"type": "ClusterIP",
"host": map[string]string{},
},
expectObj: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": "test"},
"spec": map[string]interface{}{"replicas": int64(2)},
}},
hasCompileErr: true,
errorString: "parameter error for testWorkload: parameter.host.requiredParam: field is required but not present",
},
//required params that are provided
"required params that are provided": {
workloadTemplate: `
output:{
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: context.name
spec: {
replicas: parameter.replicas
host: parameter.host.requiredParam
}
}
parameter: {
replicas: *1 | int
type: string
host: requiredParam!: string
param1!: string
}
`,
params: map[string]interface{}{
"replicas": 2,
"type": "ClusterIP",
"host": map[string]interface{}{"requiredParam": "example.com"},
"param1": "newparam",
},
expectObj: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": "test"},
"spec": map[string]interface{}{"replicas": int64(2), "host": "example.com"},
}},
hasCompileErr: false,
errorString: "",
},
//optional and regular param with default value should not give error
"optional and regular param with default value should not give error": {
workloadTemplate: `
output:{
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: context.name
spec: {
replicas: parameter.replicas
}
}
parameter: {
replicas: *1 | int
type: string
requiredParam!: string
optionalParam?: string
regularParam: string | *""
}
`,
params: map[string]interface{}{
"replicas": 2,
"type": "ClusterIP",
"requiredParam": "example.com",
},
expectObj: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": "test"},
"spec": map[string]interface{}{"replicas": int64(2)},
}},
hasCompileErr: false,
errorString: "",
},
// regular param should give error
"regular param should give error": {
workloadTemplate: `
output:{
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: context.name
spec: {
replicas: parameter.replicas
}
}
parameter: {
replicas: *1 | int
type: string
requiredParam!: string
regularParam: string
}
`,
params: map[string]interface{}{
"replicas": 2,
"type": "ClusterIP",
"requiredParam": "example.com",
},
expectObj: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": "test"},
"spec": map[string]interface{}{"replicas": int64(2)},
}},
hasCompileErr: true,
errorString: "parameter error for testWorkload: parameter.regularParam: incomplete value string",
},
// multiple errors
"multiple errors": {
workloadTemplate: `
output:{
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: context.name
spec: {
replicas: parameter.replicas
}
}
parameter: {
replicas: *1 | int
type: string
requiredParam!: string
regularParam: string
}
`,
params: map[string]interface{}{
"replicas": 2,
"type": "ClusterIP",
},
expectObj: &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{"name": "test"},
"spec": map[string]interface{}{"replicas": int64(2)},
}},
hasCompileErr: true,
errorString: "parameter error for testWorkload: parameter.requiredParam: field is required but not present (and 1 more errors)",
},
}
for _, v := range testCases {
ctx := process.NewContext(process.ContextData{
AppName: "myapp",
CompName: "test",
Namespace: "default",
AppRevisionName: "myapp-v1",
ClusterVersion: types.ClusterVersion{Minor: "19+"},
})
wt := NewWorkloadAbstractEngine("testWorkload")
err := wt.Complete(ctx, v.workloadTemplate, v.params)
hasError := err != nil
assert.Equal(t, v.hasCompileErr, hasError)
if v.hasCompileErr {
if err != nil {
assert.Equal(t, err.Error(), v.errorString)
}
continue
}
base, assists := ctx.Output()
assert.Equal(t, len(v.expAssObjs), len(assists))
assert.NotNil(t, base)
baseObj, err := base.Unstructured()
assert.Equal(t, nil, err)
assert.Equal(t, v.expectObj, baseObj)
for _, ss := range assists {
assert.Equal(t, AuxiliaryWorkload, ss.Type)
got, err := ss.Ins.Unstructured()
assert.NoError(t, err)
assert.Equal(t, got, v.expAssObjs[ss.Name])
}
}
}

View File

@@ -251,7 +251,7 @@ func (m *GoModuleModifier) addSubGoMod() error {
"--rm",
"-v", m.apiDir+":/api",
"-w", "/api",
"golang:1.22-alpine3.18",
"golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1",
"go", "get", fmt.Sprintf("%s@%s", m.Package, m.LangArgs.Get(mainModuleVersionKey)),
))
}
@@ -261,7 +261,7 @@ func (m *GoModuleModifier) addSubGoMod() error {
"-v", m.apiDir+":/api",
"-w", "/api",
"--env", "GOPROXY="+m.LangArgs.Get(goProxyKey),
"golang:1.22-alpine3.18",
"golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1",
"go", "mod", "tidy",
))
for _, cmd := range cmds {
@@ -293,7 +293,7 @@ func (m *GoModuleModifier) tidyMainMod() error {
"--rm",
"-v", outDir+":/api",
"-w", "/api",
"golang:1.22-alpine3.18",
"golang:1.23.8-alpine@sha256:b7486658b87d34ecf95125e5b97e8dfe86c21f712aa36fc0c702e5dc41dc63e1",
"go", "mod", "tidy",
)
if m.Verbose {

View File

@@ -19,7 +19,10 @@ package multicluster
import (
"bytes"
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
"time"
@@ -41,6 +44,7 @@ import (
ocmclusterv1 "open-cluster-management.io/api/cluster/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/utils"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
)
@@ -125,10 +129,20 @@ func (clusterConfig *KubeClusterConfig) createOrUpdateClusterSecret(ctx context.
data["ca.crt"] = clusterConfig.Cluster.CertificateAuthorityData
}
}
if len(clusterConfig.AuthInfo.Token) > 0 {
switch {
case len(clusterConfig.AuthInfo.Token) > 0:
credentialType = clusterv1alpha1.CredentialTypeServiceAccountToken
data["token"] = []byte(clusterConfig.AuthInfo.Token)
} else {
case clusterConfig.AuthInfo.Exec != nil:
token, err := getTokenFromExec(clusterConfig.AuthInfo.Exec)
if err != nil {
return err
}
credentialType = clusterv1alpha1.CredentialTypeServiceAccountToken
data["token"] = []byte(token)
default:
credentialType = clusterv1alpha1.CredentialTypeX509Certificate
data["tls.crt"] = clusterConfig.AuthInfo.ClientCertificateData
data["tls.key"] = clusterConfig.AuthInfo.ClientKeyData
@@ -473,6 +487,9 @@ func (op DetachClusterManagedClusterKubeConfigPathOption) ApplyToArgs(args *Deta
// DetachCluster detach cluster by name, if cluster is using by application, it will return error
func DetachCluster(ctx context.Context, cli client.Client, clusterName string, options ...DetachClusterOption) error {
if err := removeClusterFromResourceTrackers(ctx, cli, clusterName); err != nil {
return fmt.Errorf("error in removing cluster references from resourcetrackers: %w", err)
}
args := newDetachClusterArgs(options...)
if clusterName == ClusterLocalName {
return ErrReservedLocalClusterName
@@ -598,3 +615,78 @@ func getMutableClusterSecret(ctx context.Context, c client.Client, clusterName s
}
return clusterSecret, nil
}
// removeClusterFromResourceTrackers removes cluster references from all resource trackers.
func removeClusterFromResourceTrackers(ctx context.Context, cli client.Client, clusterName string) error {
rts := v1beta1.ResourceTrackerList{}
if err := cli.List(ctx, &rts); err != nil {
return fmt.Errorf("unable to list resourcetrackers due to error: %w", err)
}
for i := range rts.Items {
managedResources := rts.Items[i].Spec.ManagedResources
var result []v1beta1.ManagedResource
for _, mr := range managedResources {
if mr.ClusterObjectReference.Cluster != clusterName {
result = append(result, mr)
}
}
if len(rts.Items[i].Spec.ManagedResources) != len(result) {
rts.Items[i].Spec.ManagedResources = result
if err := cli.Update(ctx, &rts.Items[i]); err != nil {
return fmt.Errorf("error in updating resourcetracker %s: %w", rts.Items[i].Name, err)
}
}
}
return nil
}
func getTokenFromExec(execConfig *clientcmdapi.ExecConfig) (string, error) {
// #nosec G204 -- This is intentionally running an exec command with user-provided input
// The execConfig comes from the kubeconfig which should be trusted in this context
cmdPath := execConfig.Command
if strings.Contains(cmdPath, "..") {
return "", fmt.Errorf("command path must not contain '..'")
}
if strings.ContainsAny(cmdPath, "$;&|<>\"'\\") {
return "", fmt.Errorf("command must not contain shell metacharacters")
}
for _, arg := range execConfig.Args {
if strings.ContainsAny(arg, "$;&|<>\\") {
return "", fmt.Errorf("arguments must not contain shell metacharacters")
}
}
cmd := exec.Command(cmdPath, execConfig.Args...) // #nosec G204
env := os.Environ()
for _, e := range execConfig.Env {
if strings.ContainsAny(e.Name, "=$;\n") || strings.ContainsAny(e.Value, "\n") {
return "", fmt.Errorf("environment variable names and values must not contain control characters")
}
env = append(env, fmt.Sprintf("%s=%s", e.Name, e.Value))
}
cmd.Env = env
output, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("failed to execute auth command: %w", err)
}
var execCredential struct {
Status struct {
Token string `json:"token"`
} `json:"status"`
}
if err := json.Unmarshal(output, &execCredential); err != nil {
return "", fmt.Errorf("failed to parse exec command output: %w", err)
}
if execCredential.Status.Token == "" {
return "", fmt.Errorf("token not found in exec command output")
}
return execCredential.Status.Token, nil
}

View File

@@ -22,6 +22,7 @@ import (
"fmt"
"hash"
"hash/fnv"
"sort"
"strconv"
"strings"
@@ -39,6 +40,8 @@ import (
"k8s.io/apimachinery/pkg/util/validation"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/Masterminds/semver"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
@@ -122,6 +125,14 @@ const (
XDefinitionNamespace
)
// DefinitionKindToNameLabel records DefinitionRevision types and labels to search its name
var DefinitionKindToNameLabel = map[common.DefinitionType]string{
common.ComponentType: oam.LabelComponentDefinitionName,
common.TraitType: oam.LabelTraitDefinitionName,
common.PolicyType: oam.LabelPolicyDefinitionName,
common.WorkflowStepType: oam.LabelWorkflowStepDefinitionName,
}
// A ConditionedObject is an Object type with condition field
type ConditionedObject interface {
client.Object
@@ -192,6 +203,7 @@ func GetDefinition(ctx context.Context, cli client.Reader, definition client.Obj
}
return err
}
return nil
}
@@ -213,12 +225,17 @@ func GetDefinitionFromNamespace(ctx context.Context, cli client.Reader, definiti
// GetCapabilityDefinition can get different versions of ComponentDefinition/TraitDefinition
func GetCapabilityDefinition(ctx context.Context, cli client.Reader, definition client.Object,
definitionName string) error {
isLatestRevision, defRev, err := fetchDefinitionRev(ctx, cli, definitionName)
definitionName string, annotations map[string]string) error {
definitionType, err := getDefinitionType(definition)
if err != nil {
return err
}
isLatestRevision, defRev, err := fetchDefinitionRevision(ctx, cli, definitionName, definitionType, annotations)
if err != nil {
return err
}
if isLatestRevision {
return GetDefinition(ctx, cli, definition, definitionName)
}
switch def := definition.(type) {
@@ -235,7 +252,24 @@ func GetCapabilityDefinition(ctx context.Context, cli client.Reader, definition
return nil
}
func fetchDefinitionRev(ctx context.Context, cli client.Reader, definitionName string) (bool, *v1beta1.DefinitionRevision, error) {
func getDefinitionType(definition client.Object) (common.DefinitionType, error) {
var definitionType common.DefinitionType
switch definition.(type) {
case *v1beta1.ComponentDefinition:
definitionType = common.ComponentType
case *v1beta1.TraitDefinition:
definitionType = common.TraitType
case *v1beta1.PolicyDefinition:
definitionType = common.PolicyType
case *v1beta1.WorkflowStepDefinition:
definitionType = common.WorkflowStepType
default:
return definitionType, fmt.Errorf("invalid definition type for %v", definition.GetName())
}
return definitionType, nil
}
func fetchDefinitionRevision(ctx context.Context, cli client.Reader, definitionName string, definitionType common.DefinitionType, annotations map[string]string) (bool, *v1beta1.DefinitionRevision, error) {
// if the component's type doesn't contain '@' means user want to use the latest Definition.
if !strings.Contains(definitionName, "@") {
return true, nil, nil
@@ -245,13 +279,93 @@ func fetchDefinitionRev(ctx context.Context, cli client.Reader, definitionName s
if err != nil {
return false, nil, err
}
defName := strings.Split(definitionName, "@")[0]
autoUpdate, ok := annotations[oam.AnnotationAutoUpdate]
if ok && autoUpdate == "true" {
latestRevisionName, err := GetLatestDefinitionRevisionName(ctx, cli.(client.Client), defName, defRevName, definitionType)
if err != nil {
return false, nil, err
}
defRevName = latestRevisionName
}
defRev := new(v1beta1.DefinitionRevision)
if err := GetDefinition(ctx, cli, defRev, defRevName); err != nil {
return false, nil, err
}
return false, defRev, nil
}
// GetLatestDefinitionRevisionName returns the latest definition revision name in specified version range.
func GetLatestDefinitionRevisionName(ctx context.Context, cli client.Client, definitionName, revisionName string, definitionType common.DefinitionType) (string, error) {
for _, ns := range []string{GetDefinitionNamespaceWithCtx(ctx), oam.SystemDefinitionNamespace} {
revisionListForDefinition, err := fetchAllRevisionsForDefinitionName(ctx, cli, ns, definitionName, definitionType)
if err != nil {
return "", err
}
matchedDefinitionRevision, err := getMatchingDefinitionRevision(revisionName, definitionName, revisionListForDefinition, definitionType)
if err == nil && matchedDefinitionRevision != "" {
return matchedDefinitionRevision, nil
}
}
return "", fmt.Errorf("error finding definition revision for Name: %v, Type: %v", definitionName, definitionType)
}
func fetchAllRevisionsForDefinitionName(ctx context.Context, cli client.Client, ns, definitionName string, definitionType common.DefinitionType) (*v1beta1.DefinitionRevisionList, error) {
var listOptions []client.ListOption
listOptions = append(listOptions, client.InNamespace(ns),
client.MatchingLabels{
DefinitionKindToNameLabel[definitionType]: definitionName,
})
revisionList := v1beta1.DefinitionRevisionList{}
revisionList.SetGroupVersionKind(schema.GroupVersionKind{
Group: v1beta1.Group,
Version: v1beta1.Version,
Kind: v1beta1.DefinitionRevisionKind,
})
err := cli.List(ctx, &revisionList, listOptions...)
return &revisionList, err
}
func getMatchingDefinitionRevision(exactRevisionName, definitionName string, revisionList *v1beta1.DefinitionRevisionList, definitionType common.DefinitionType) (string, error) {
var definitionVersions []*semver.Version
revisionPrefix := exactRevisionName + "."
orignalVersions := make(map[string]string)
for _, revision := range revisionList.Items {
if definitionType != "" && definitionType != revision.Spec.DefinitionType {
continue
}
if revision.Name == exactRevisionName {
return exactRevisionName, nil
}
// Only get the revisions that the user expects
if strings.HasPrefix(revision.Name, revisionPrefix) {
version := strings.Split(revision.Name, definitionName+"-")[1]
v, err := semver.NewVersion(version)
orignalVersions[v.String()] = version
if err != nil {
return "", err
}
definitionVersions = append(definitionVersions, v)
}
}
if len(definitionVersions) == 0 {
return "", nil
}
sort.Sort(semver.Collection(definitionVersions))
latestVersion := definitionVersions[len(definitionVersions)-1]
return definitionName + "-" + orignalVersions[latestVersion.String()], nil
}
// ConvertDefinitionRevName can help convert definition type defined in Application to DefinitionRevision Name
// e.g., worker@v1.3.1 will be convert to worker-v1.3.1
func ConvertDefinitionRevName(definitionName string) (string, error) {

View File

@@ -980,3 +980,339 @@ func TestXDefinitionNamespaceInCtx(t *testing.T) {
assert.Equal(t, tc.expectedNamespace, ns)
}
}
func TestGetLatestDefinitionRevisionName(t *testing.T) {
componetListCli := test.MockClient{MockList: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
defRevisionList := getComponentDefRevisionList()
defRevisionList.DeepCopyInto(list.(*v1beta1.DefinitionRevisionList))
return nil
}}
traitListCli := test.MockClient{MockList: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
defRevisionList := getTraitDefRevisionList()
defRevisionList.DeepCopyInto(list.(*v1beta1.DefinitionRevisionList))
return nil
}}
testcases := []struct {
name string
inputRevisionName string
definitionName string
definitionType string
expectedDefRevisionName string
revisionList *v1beta1.DefinitionRevisionList
client client.Client
err error
}{
{
name: "Complete Component version name specified",
inputRevisionName: "configmap-component-v1.3.0",
definitionName: "configmap-component",
definitionType: "Component",
expectedDefRevisionName: "configmap-component-v1.3.0",
client: &componetListCli,
err: nil,
}, {
name: "Partial Component version name specified",
inputRevisionName: "configmap-component-v1.2",
definitionName: "configmap-component",
definitionType: "Component",
expectedDefRevisionName: "configmap-component-v1.2.4",
client: &componetListCli,
err: nil,
}, {
name: "Component version not present",
inputRevisionName: "configmap-component-v1.6",
definitionName: "configmap-component",
definitionType: "Component",
expectedDefRevisionName: "",
client: &componetListCli,
err: fmt.Errorf("error finding definition revision for Name: configmap-component, Type: Component"),
}, {
name: "Complete Trait version name specified",
inputRevisionName: "scaler-trait-v1.3.0",
definitionName: "scaler-trait",
definitionType: "Trait",
expectedDefRevisionName: "scaler-trait-v1.3.0",
client: &traitListCli,
err: nil,
},
{
name: "Partial Trait version name specified",
inputRevisionName: "scaler-trait-v1.2",
definitionName: "scaler-trait",
definitionType: "Trait",
expectedDefRevisionName: "scaler-trait-v1.2.4",
client: &traitListCli,
err: nil,
}, {
name: "Trait version name not present",
inputRevisionName: "scaler-trait-v1.5",
definitionName: "scaler-trait",
definitionType: "Trait",
expectedDefRevisionName: "",
client: &traitListCli,
err: fmt.Errorf("error finding definition revision for Name: scaler-trait, Type: Trait"),
},
}
ctx := context.Background()
for _, tc := range testcases {
defRevisionName, err := util.GetLatestDefinitionRevisionName(ctx, tc.client, tc.definitionName, tc.inputRevisionName, common.DefinitionType(tc.definitionType))
assert.Equal(t, defRevisionName, tc.expectedDefRevisionName)
assert.Equal(t, err, tc.err)
}
}
func TestGetCapabilityDefinitionComponentAutoUpdateEnabled(t *testing.T) {
cli := test.MockClient{MockList: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
defRevisionList := getComponentDefRevisionList()
defRevisionList.DeepCopyInto(list.(*v1beta1.DefinitionRevisionList))
return nil
}, MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
componentDefinitionRevision.DeepCopyInto(obj.(*v1beta1.DefinitionRevision))
return nil
}}
annotations := make(map[string]string)
annotations[oam.AnnotationAutoUpdate] = "true"
definitionName := "configmap-component@v1"
ctx := context.Background()
definition := new(v1beta1.ComponentDefinition)
err := util.GetCapabilityDefinition(ctx, &cli, definition, definitionName, annotations)
assert.Equal(t, err, nil)
assert.Equal(t, definition.Spec.Version, "1.0.0")
}
func TestGetCapabilityDefinitionOfTraitAutoUpdateEnabled(t *testing.T) {
cli := test.MockClient{MockList: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
defRevisionList := getTraitDefRevisionList()
defRevisionList.DeepCopyInto(list.(*v1beta1.DefinitionRevisionList))
return nil
}, MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
traitDefinitionRevision.DeepCopyInto(obj.(*v1beta1.DefinitionRevision))
return nil
}}
annotations := make(map[string]string)
annotations[oam.AnnotationAutoUpdate] = "true"
definitionName := "scaler-trait@v1"
ctx := context.Background()
definition := new(v1beta1.TraitDefinition)
err := util.GetCapabilityDefinition(ctx, &cli, definition, definitionName, annotations)
assert.Equal(t, err, nil)
assert.Equal(t, definition.Spec.Version, "1.0.0")
}
func TestGetCapabilityDefinitionComponentAutoUpdateDisabled(t *testing.T) {
cli := test.MockClient{MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
componentDefinitionRevision.Spec.ComponentDefinition.DeepCopyInto(obj.(*v1beta1.ComponentDefinition))
return nil
}}
annotations := make(map[string]string)
annotations[oam.AnnotationAutoUpdate] = "false"
definitionName := "configmap-component"
ctx := context.Background()
definition := new(v1beta1.ComponentDefinition)
err := util.GetCapabilityDefinition(ctx, &cli, definition, definitionName, annotations)
assert.Equal(t, err, nil)
assert.Equal(t, definition.Spec.Version, "1.0.0")
}
func TestGetCapabilityDefinitionPolicyAutoUpdateDisabled(t *testing.T) {
cli := test.MockClient{MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
policydefinition := &v1beta1.PolicyDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: "mock-policy-definition",
Namespace: "vela-system",
},
}
policydefinition.DeepCopyInto(obj.(*v1beta1.PolicyDefinition))
return nil
}}
annotations := make(map[string]string)
annotations[oam.AnnotationAutoUpdate] = "false"
definitionName := "mock-policy-definition"
ctx := context.Background()
definition := new(v1beta1.PolicyDefinition)
err := util.GetCapabilityDefinition(ctx, &cli, definition, definitionName, annotations)
assert.Equal(t, err, nil)
}
func TestGetCapabilityDefinitionWorkflowStepAutoUpdateDisabled(t *testing.T) {
cli := test.MockClient{MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
workflowStepDefinition := &v1beta1.WorkflowStepDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: "mock-workflow-definition",
Namespace: "vela-system",
},
}
workflowStepDefinition.DeepCopyInto(obj.(*v1beta1.WorkflowStepDefinition))
return nil
}}
annotations := make(map[string]string)
annotations[oam.AnnotationAutoUpdate] = "false"
definitionName := "mock-workflow-definition"
ctx := context.Background()
definition := new(v1beta1.WorkflowStepDefinition)
err := util.GetCapabilityDefinition(ctx, &cli, definition, definitionName, annotations)
assert.Equal(t, err, nil)
}
func TestGetCapabilityDefinitionInvalidDefinition(t *testing.T) {
cli := test.MockClient{MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
workflowStepDefinition := &v1beta1.WorkloadDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: "mock-workload-definition",
Namespace: "vela-system",
},
}
workflowStepDefinition.DeepCopyInto(obj.(*v1beta1.WorkloadDefinition))
return nil
}}
annotations := make(map[string]string)
annotations[oam.AnnotationAutoUpdate] = "false"
definitionName := "mock-workload-definition"
ctx := context.Background()
definition := new(v1beta1.WorkloadDefinition)
definition.ObjectMeta.Name = "mock-workload-definition"
err := util.GetCapabilityDefinition(ctx, &cli, definition, definitionName, annotations)
assert.Equal(t, err.Error(), "invalid definition type for mock-workload-definition")
}
func TestGetCapabilityDefinitionOfTraitAutoUpdateDisabled(t *testing.T) {
cli := test.MockClient{MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
o := new(v1beta1.TraitDefinition)
*o = traitDefinitionRevision.Spec.TraitDefinition
return nil
}}
annotations := make(map[string]string)
annotations[oam.AnnotationAutoUpdate] = "false"
definitionName := "scaler-trait"
ctx := context.Background()
definition := new(v1beta1.TraitDefinition)
err := util.GetCapabilityDefinition(ctx, &cli, definition, definitionName, annotations)
assert.Equal(t, err, nil)
}
func getComponentDefRevisionList() v1beta1.DefinitionRevisionList {
compDefRevision1 := componentDefinitionRevision.DeepCopy()
compDefRevision1.Spec.ComponentDefinition.Spec.Version = "1.2.0"
compDefRevision1.Name = "configmap-component-v1.2.0"
compDefRevision2 := componentDefinitionRevision.DeepCopy()
compDefRevision2.Spec.ComponentDefinition.Spec.Version = "1.2.4"
compDefRevision2.Name = "configmap-component-v1.2.4"
compDefRevision3 := componentDefinitionRevision.DeepCopy()
compDefRevision3.Spec.ComponentDefinition.Spec.Version = "1.3.0"
compDefRevision3.Name = "configmap-component-v1.3.0"
compRevisionList := v1beta1.DefinitionRevisionList{
TypeMeta: metav1.TypeMeta{
Kind: "DefinitionRevision",
APIVersion: "core.oam.dev/v1beta1",
},
Items: []v1beta1.DefinitionRevision{
*compDefRevision1, *compDefRevision2, *compDefRevision3,
},
}
return compRevisionList
}
func getTraitDefRevisionList() v1beta1.DefinitionRevisionList {
traitDefRevision1 := traitDefinitionRevision.DeepCopy()
traitDefRevision1.Spec.TraitDefinition.Spec.Version = "1.2.0"
traitDefRevision1.Name = "scaler-trait-v1.2.0"
traitDefRevision2 := traitDefinitionRevision.DeepCopy()
traitDefRevision2.Spec.TraitDefinition.Spec.Version = "1.2.4"
traitDefRevision2.Name = "scaler-trait-v1.2.4"
traitDefRevision3 := traitDefinitionRevision.DeepCopy()
traitDefRevision3.Spec.TraitDefinition.Spec.Version = "1.3.0"
traitDefRevision3.Name = "scaler-trait-v1.3.0"
traitRevisionList := v1beta1.DefinitionRevisionList{
TypeMeta: metav1.TypeMeta{
Kind: "DefinitionRevision",
APIVersion: "core.oam.dev/v1beta1",
},
Items: []v1beta1.DefinitionRevision{
*traitDefRevision1, *traitDefRevision2, *traitDefRevision3,
},
}
return traitRevisionList
}
var traitDefinitionRevision = v1beta1.DefinitionRevision{
TypeMeta: metav1.TypeMeta{
Kind: "DefinitionRevision",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "scaler-trait",
Labels: map[string]string{
"trait.oam.dev/name": "scaler-trait",
},
},
Spec: v1beta1.DefinitionRevisionSpec{
Revision: 1,
RevisionHash: "5ceecfbe58dde83a",
DefinitionType: "Trait",
TraitDefinition: v1beta1.TraitDefinition{
TypeMeta: metav1.TypeMeta{
Kind: "TraitDefinition",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "scaler-trait",
},
Spec: v1beta1.TraitDefinitionSpec{
Version: "1.0.0",
Schematic: &common.Schematic{
CUE: &common.CUE{
Template: "",
},
},
},
},
},
}
// debug unit tests
var componentDefinitionRevision = v1beta1.DefinitionRevision{
TypeMeta: metav1.TypeMeta{
Kind: "DefinitionRevision",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap-component",
Labels: map[string]string{
"componentdefinition.oam.dev/name": "configmap-component",
},
},
Spec: v1beta1.DefinitionRevisionSpec{
Revision: 1,
RevisionHash: "5ceecfbe58dde83a",
DefinitionType: "Component",
ComponentDefinition: v1beta1.ComponentDefinition{
TypeMeta: metav1.TypeMeta{
Kind: "ComponentDefinition",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap-component",
},
Spec: v1beta1.ComponentDefinitionSpec{
Version: "1.0.0",
Schematic: &common.Schematic{
CUE: &common.CUE{
Template: "",
},
},
},
},
},
}

View File

@@ -398,18 +398,23 @@ func DeleteManagedResourceInApplication(ctx context.Context, cli client.Client,
}
util.RemoveAnnotations(obj, []string{oam.AnnotationAppSharedBy})
}
if mr.SkipGC || hasOrphanFinalizer(app) {
var opts []client.DeleteOption
var isOrphan bool
if garbageCollectPolicy, _ := policy.ParsePolicy[v1alpha1.GarbageCollectPolicySpec](app); garbageCollectPolicy != nil {
isOrphan, opts = garbageCollectPolicy.FindDeleteOption(obj)
}
if mr.SkipGC || hasOrphanFinalizer(app) || isOrphan {
if labels := obj.GetLabels(); labels != nil {
delete(labels, oam.LabelAppName)
delete(labels, oam.LabelAppNamespace)
obj.SetLabels(labels)
}
return errors.Wrapf(cli.Update(_ctx, obj), "failed to remove owner labels for resource while skipping gc")
}
var opts []client.DeleteOption
if garbageCollectPolicy, _ := policy.ParsePolicy[v1alpha1.GarbageCollectPolicySpec](app); garbageCollectPolicy != nil {
opts = garbageCollectPolicy.FindDeleteOption(obj)
return errors.Wrapf(cli.Update(_ctx, obj), "skipping deletion for resource")
}
if err := cli.Delete(_ctx, obj, opts...); err != nil && !kerrors.IsNotFound(err) {
return errors.Wrapf(err, "failed to delete resource %s", mr.ResourceKey())
}

View File

@@ -80,7 +80,7 @@ func LoadDataFromPath(ctx context.Context, path string, pathFilter func(string)
}
bs, e := os.ReadFile(filepath.Clean(path))
if e != nil {
return nil, fmt.Errorf("failed to read file %s: %w", path, err)
return nil, fmt.Errorf("failed to read file %s: %w", path, e)
}
return []FileData{{Path: path, Data: bs}}, nil
}

View File

@@ -35,7 +35,6 @@ import (
"github.com/kubevela/pkg/cue/cuex"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
"github.com/kubevela/workflow/pkg/cue/model/sets"
"github.com/kubevela/workflow/pkg/cue/model/value"
providertypes "github.com/kubevela/workflow/pkg/providers/types"
@@ -128,20 +127,9 @@ func ValidateView(ctx context.Context, viewStr string) error {
// Make sure `status` or `export` field exists
vStatus := val.LookupPath(cue.ParsePath(DefaultExportValue))
errStatus := vStatus.Err()
vExport := val.LookupPath(cue.ParsePath(KeyWordExport))
errExport := vExport.Err()
if errStatus != nil && errExport != nil {
return errors.Errorf("no `status` or `export` field found in view: %v, %v", errStatus, errExport)
}
if errStatus == nil {
_, errStatus = sets.ToString(vStatus)
}
if errExport == nil {
_, errExport = sets.ToString(vExport)
}
if errStatus != nil && errExport != nil {
return errors.Errorf("connot get string from` status` or `export`: %v, %v", errStatus, errExport)
if !vStatus.Exists() && !vExport.Exists() {
return errors.Errorf("no `status` or `export` field found in view")
}
return nil

View File

@@ -25,6 +25,7 @@ import (
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/componentdefinition"
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/policydefinition"
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/traitdefinition"
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/workflowstepdefinition"
)
// Register will be called in main and register all validation handlers
@@ -35,6 +36,7 @@ func Register(mgr manager.Manager, args controller.Args) {
componentdefinition.RegisterValidatingHandler(mgr)
traitdefinition.RegisterValidatingHandler(mgr, args)
policydefinition.RegisterValidatingHandler(mgr)
workflowstepdefinition.RegisterValidatingHandler(mgr)
server := mgr.GetWebhookServer()
server.Register("/convert", conversion.NewWebhookHandler(mgr.GetScheme()))
}

View File

@@ -66,6 +66,10 @@ func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) a
if err := h.Decoder.Decode(req, app); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}
if req.Namespace != "" {
app.Namespace = req.Namespace
}
ctx = util.SetNamespaceInCtx(ctx, app.Namespace)
switch req.Operation {
case admissionv1.Create:

View File

@@ -207,4 +207,52 @@ var _ = Describe("Test Application Validator", func() {
resp := handler.Handle(ctx, req)
Expect(resp.Allowed).Should(BeFalse())
})
It("Test Application with PublishVersion and Autoupdate annotations", func() {
req := admission.Request{
AdmissionRequest: admissionv1.AdmissionRequest{
Operation: admissionv1.Create,
Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
Object: runtime.RawExtension{
Raw: []byte(`
{"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-timeout","namespace":"default","annotations":{"app.oam.dev/publishVersion":"v1.0.0","app.oam.dev/autoUpdate":"true"}},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"suspend","timeout":"1s"}]}}}
`),
},
},
}
resp := handler.Handle(ctx, req)
Expect(resp.Allowed).Should(BeFalse())
})
It("Test Application Publishversion Annotation", func() {
req := admission.Request{
AdmissionRequest: admissionv1.AdmissionRequest{
Operation: admissionv1.Create,
Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
Object: runtime.RawExtension{
Raw: []byte(`
{"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-timeout","namespace":"default","annotations":{"app.oam.dev/publishVersion":"v1.0.0"}},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"suspend","timeout":"1s"}]}}}
`),
},
},
}
resp := handler.Handle(ctx, req)
Expect(resp.Allowed).Should(BeTrue())
})
It("Test Application Autoupdate Annotation", func() {
req := admission.Request{
AdmissionRequest: admissionv1.AdmissionRequest{
Operation: admissionv1.Create,
Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
Object: runtime.RawExtension{
Raw: []byte(`
{"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-timeout","namespace":"default","annotations":{"app.oam.dev/autoUpdate":"true"}},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"suspend","timeout":"1s"}]}}}
`),
},
},
}
resp := handler.Handle(ctx, req)
Expect(resp.Allowed).Should(BeTrue())
})
})

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