Compare commits

..

30 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
79 changed files with 3390 additions and 630 deletions

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:

View File

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

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@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0
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@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@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@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- name: Setup QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
with:
driver-opts: image=moby/buildkit:master
- uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
name: Build & Pushing vela-core for Dockerhub, GHCR
- name: Build & Push Vela Core for Dockerhub, GHCR
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: .
file: Dockerfile
labels: |-
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
platforms: linux/amd64,linux/arm64
@@ -61,16 +90,55 @@ jobs:
GITVERSION=git-${{ steps.vars.outputs.git_revision }}
VERSION=${{ steps.get_version.outputs.VERSION }}
GOPROXY=https://proxy.golang.org
tags: |-
tags: |
docker.io/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
- uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
name: Build & Pushing CLI for Dockerhub, GHCR
- name: Get Vela Core Image Digest
id: meta-vela-core
run: |
GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/oamdev/vela-core
DOCKER_IMAGE=docker.io/oamdev/vela-core
TAG=${{ steps.get_version.outputs.VERSION }}
DIGEST=$(crane digest $GHCR_IMAGE:$TAG)
echo "image=$GHCR_IMAGE" >> $GITHUB_OUTPUT
echo "dockerhub_image=$DOCKER_IMAGE" >> $GITHUB_OUTPUT
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
- name: Generate SBOM for Vela Core Image
id: generate_vela_core_sbom
uses: anchore/sbom-action@v0.17.0
with:
image: ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
registry-username: ${{ github.actor }}
registry-password: ${{ secrets.GITHUB_TOKEN }}
format: spdx-json
artifact-name: sbom-vela-core.spdx.json
output-file: ${{ github.workspace }}/sbom-vela-core.spdx.json
- name: Sign Vela Core Image and Attest SBOM
env:
COSIGN_EXPERIMENTAL: 'true'
run: |
echo "signing vela core images..."
cosign sign --yes ghcr.io/${{ github.repository_owner }}/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
cosign sign --yes docker.io/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
echo "attesting SBOM against the vela core image..."
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-core.spdx.json --type spdx \
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-core.spdx.json --type spdx \
docker.io/oamdev/vela-core@${{ steps.meta-vela-core.outputs.digest }}
- name: Build & Push Vela CLI for Dockerhub, GHCR
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: .
file: Dockerfile.cli
labels: |-
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
platforms: linux/amd64,linux/arm64
@@ -79,6 +147,100 @@ jobs:
GITVERSION=git-${{ steps.vars.outputs.git_revision }}
VERSION=${{ steps.get_version.outputs.VERSION }}
GOPROXY=https://proxy.golang.org
tags: |-
tags: |
docker.io/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
- name: Get Vela CLI Image Digest
id: meta-vela-cli
run: |
GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli
DOCKER_IMAGE=docker.io/oamdev/vela-cli
TAG=${{ steps.get_version.outputs.VERSION }}
DIGEST=$(crane digest $GHCR_IMAGE:$TAG)
echo "image=$GHCR_IMAGE" >> $GITHUB_OUTPUT
echo "dockerhub_image=$DOCKER_IMAGE" >> $GITHUB_OUTPUT
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
- name: Generate SBOM for Vela CLI Image
id: generate_sbom
uses: anchore/sbom-action@v0.17.0
with:
image: ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli:${{ steps.get_version.outputs.VERSION }}
registry-username: ${{ github.actor }}
registry-password: ${{ secrets.GITHUB_TOKEN }}
format: spdx-json
artifact-name: sbom-vela-cli.spdx.json
output-file: ${{ github.workspace }}/sbom-vela-cli.spdx.json
- name: Sign Vela CLI Image and Attest SBOM
env:
COSIGN_EXPERIMENTAL: 'true'
run: |
echo "signing vela CLI images..."
cosign sign --yes ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
cosign sign --yes docker.io/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
echo "attesting SBOM against the vela cli image..."
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-cli.spdx.json --type spdx \
ghcr.io/${{ github.repository_owner }}/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
cosign attest --yes --predicate ${{ github.workspace }}/sbom-vela-cli.spdx.json --type spdx \
docker.io/oamdev/vela-cli@${{ steps.meta-vela-cli.outputs.digest }}
- name: Publish SBOMs as release artifacts
uses: anchore/sbom-action/publish-sbom@v0.17.0
provenance-ghcr:
name: Generate and Push Provenance to GCHR
needs: publish-vela-images
if: startsWith(github.ref, 'refs/tags/')
strategy:
matrix:
include:
- name: 'Vela Core Image'
image: ${{ needs.publish-vela-images.outputs.vela_core_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_core_digest }}
- name: 'Vela CLI Image'
image: ${{ needs.publish-vela-images.outputs.vela_cli_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_cli_digest }}
permissions:
id-token: write
contents: write
actions: read
packages: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 # has to be sem var
with:
image: ${{ matrix.image }}
digest: ${{ matrix.digest }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
provenance-dockerhub:
name: Generate and Push Provenance to DockerHub
needs: publish-vela-images
if: startsWith(github.ref, 'refs/tags/')
strategy:
matrix:
include:
- name: 'Vela Core Image'
image: ${{ needs.publish-vela-images.outputs.vela_core_dockerhub_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_core_digest }}
- name: 'Vela CLI Image'
image: ${{ needs.publish-vela-images.outputs.vela_cli_dockerhub_image }}
digest: ${{ needs.publish-vela-images.outputs.vela_cli_digest }}
permissions:
id-token: write
contents: write
packages: write
actions: read
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: ${{ matrix.image }}
digest: ${{ matrix.digest }}
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
@@ -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

@@ -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

@@ -190,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

@@ -39,8 +39,9 @@ spec:
parameter: {
// +usage=Specify the AppArmor profile for the pod
appArmorProfile?: {
type: "RuntimeDefault" | "Unconfined" | "Localhost"
localhostProfile: string
type: "RuntimeDefault" | "Unconfined" | "Localhost"
// +usage: localhostProfile is required when type is 'Localhost'
localhostProfile?: string
}
fsGroup?: int
runAsGroup?: int
@@ -50,8 +51,9 @@ spec:
runAsNonRoot: *true | bool
// +usage=Specify the seccomp profile for the pod
seccompProfile?: {
type: "RuntimeDefault" | "Unconfined" | "Localhost"
localhostProfile: string
type: "RuntimeDefault" | "Unconfined" | "Localhost"
// +usage: localhostProfile is required when type is 'Localhost'
localhostProfile?: string
}
}

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

@@ -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

@@ -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

@@ -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

@@ -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())

81
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/oam-dev/kubevela
go 1.22.0
go 1.23.8
require (
cuelang.org/go v0.9.2
@@ -21,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.13.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
@@ -37,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.20250226022524-23468c911a01
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
@@ -64,16 +65,16 @@ require (
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.32.0
golang.org/x/mod v0.19.0
golang.org/x/oauth2 v0.20.0
golang.org/x/sync v0.10.0
golang.org/x/term v0.28.0
golang.org/x/text v0.21.0
golang.org/x/tools v0.23.0
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
@@ -109,10 +110,10 @@ require (
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.1 // 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 v1.1.3 // 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
@@ -126,23 +127,24 @@ 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.14 // 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
github.com/coreos/go-semver v0.3.1 // indirect
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.3.6 // indirect
github.com/distribution/reference v0.5.0 // 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
@@ -151,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
@@ -160,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.6.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
@@ -172,7 +174,7 @@ require (
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
@@ -191,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
@@ -227,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
@@ -235,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.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/skeema/knownhosts v1.3.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
@@ -261,27 +262,27 @@ require (
go.etcd.io/etcd/api/v3 v3.5.10 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect
go.etcd.io/etcd/client/v3 v3.5.10 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.opentelemetry.io/otel/sdk v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
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-20240719175910-8a7402abbf56 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/time v0.5.0 // 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.34.1 // 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
@@ -306,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

173
go.sum
View File

@@ -53,8 +53,8 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.12.2 h1:AcXy+yfRvrx20g9v7qYaJv5Rh+8GaHOS6b8G6Wx/nKs=
github.com/Microsoft/hcsshim v0.12.2/go.mod h1:RZV12pcHCXQ42XnlQ3pz6FZfmrC1C+R4gaOHhRNML1g=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -63,8 +63,8 @@ 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 v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk=
github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
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=
@@ -154,8 +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.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=
@@ -174,14 +174,16 @@ 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.14 h1:H/XLzbnGuenZEGK+v0RkwTdv2u1QFAruMe5N0GNPJwA=
github.com/containerd/containerd v1.7.14/go.mod h1:YMC9Qt5yzNqXx/fO4j/5yYVIHXSRrlB3H7sxkUTvspg=
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/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
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=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -209,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.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
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=
@@ -220,14 +222,14 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc=
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v24.0.9+incompatible h1:OxbimnP/z+qVjDLpq9wbeFU3Nc30XhSe+LkwYQisD50=
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=
@@ -236,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=
@@ -245,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 v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ=
github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
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=
@@ -291,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,12 +330,12 @@ github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8b
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.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA=
github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE=
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.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
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=
@@ -353,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=
@@ -417,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=
@@ -470,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=
@@ -533,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=
@@ -587,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=
@@ -644,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.20250226022524-23468c911a01 h1:E2QTiakMlz7ICp/p9os0NZs4BTDq4rKtfzdTOMuBFM8=
github.com/kubevela/workflow v0.6.1-0.20250226022524-23468c911a01/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=
@@ -735,6 +738,8 @@ github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
@@ -751,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=
@@ -831,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=
@@ -899,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=
@@ -922,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.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
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=
@@ -990,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=
@@ -1020,10 +1021,12 @@ 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.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8=
go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k=
@@ -1060,8 +1063,8 @@ go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUz
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 h1:RsQi0qJ2imFfCvZabqzM9cNXBG8k6gXMv1A0cXRmH6A=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0/go.mod h1:vsh3ySueQCiKPxFLvjWC4Z135gIa34TQ/NSqkDTZYUM=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
@@ -1070,8 +1073,8 @@ go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzox
go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU=
go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw=
@@ -1084,22 +1087,22 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S2
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I=
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A=
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI=
go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk=
go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM=
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
@@ -1150,8 +1153,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
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.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
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=
@@ -1177,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.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.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=
@@ -1228,8 +1231,8 @@ 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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
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=
@@ -1241,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=
@@ -1255,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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.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=
@@ -1328,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.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.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=
@@ -1341,8 +1344,8 @@ 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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
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=
@@ -1354,15 +1357,15 @@ 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.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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
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=
@@ -1393,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.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
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=
@@ -1486,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.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/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

@@ -30,6 +30,7 @@ e2e-setup-core-wo-auth:
--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 featureGates.enableCueValidation=true \
--wait kubevela ./charts/vela-core \
--debug

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"
@@ -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

@@ -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)
}
}

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

@@ -27,6 +27,7 @@ import (
"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"
@@ -164,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)
}

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

@@ -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

@@ -49,13 +49,6 @@ const (
QLProviderName = "ql"
)
var (
// EnableExternalPackageForDefaultCompiler .
EnableExternalPackageForDefaultCompiler = true
// EnableExternalPackageWatchForDefaultCompiler .
EnableExternalPackageWatchForDefaultCompiler = false
)
// compiler is the workflow default compiler
var compiler = singleton.NewSingletonE[*cuex.Compiler](func() (*cuex.Compiler, error) {
return cuex.NewCompilerWithInternalPackages(
@@ -84,12 +77,12 @@ var compiler = singleton.NewSingletonE[*cuex.Compiler](func() (*cuex.Compiler, e
// DefaultCompiler compiler for cuex to compile
var DefaultCompiler = singleton.NewSingleton[*cuex.Compiler](func() *cuex.Compiler {
c := compiler.Get()
if EnableExternalPackageForDefaultCompiler {
if cuex.EnableExternalPackageForDefaultCompiler {
if err := c.LoadExternalPackages(context.Background()); err != nil {
klog.Errorf("failed to load external packages for cuex default compiler: %v", err.Error())
}
}
if EnableExternalPackageWatchForDefaultCompiler {
if cuex.EnableExternalPackageWatchForDefaultCompiler {
go c.ListenExternalPackages(nil)
}
return c

View File

@@ -297,7 +297,7 @@ func CollectLogsInPod(ctx context.Context, params *LogParams) (*LogResult, error
}
}
if errMsg != "" {
klog.Warningf(errMsg)
klog.Warningf("%s", errMsg)
defaultOutputs["err"] = errMsg
}
return &LogResult{Outputs: defaultOutputs}, nil

View File

@@ -303,7 +303,7 @@ func CollectLogsInPod(ctx context.Context, params *LogParams) (*LogReturns, erro
}
}
if errMsg != "" {
klog.Warningf(errMsg)
klog.Warningf("%s", errMsg)
defaultOutputs["err"] = errMsg
}
return &LogReturns{Returns: LogReturnVars{Outputs: defaultOutputs}}, nil

View File

@@ -179,7 +179,7 @@ func NewAddonEnableCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.Com
if !file.IsDir() {
return fmt.Errorf("%s is not addon dir", addonOrDir)
}
ioStream.Infof(color.New(color.FgYellow).Sprintf("enabling addon by local dir: %s \n", addonOrDir))
ioStream.Infof("%s", color.New(color.FgYellow).Sprintf("enabling addon by local dir: %s \n", addonOrDir))
// args[0] is a local path install with local dir, use base dir name as addonName
abs, err := filepath.Abs(addonOrDir)
if err != nil {
@@ -300,7 +300,7 @@ non-empty new arg
if !file.IsDir() {
return fmt.Errorf("%s is not addon dir", addonOrDir)
}
ioStream.Infof(color.New(color.FgYellow).Sprintf("enabling addon by local dir: %s \n", addonOrDir))
ioStream.Infof("%s", color.New(color.FgYellow).Sprintf("enabling addon by local dir: %s \n", addonOrDir))
// args[0] is a local path install with local dir
abs, err := filepath.Abs(addonOrDir)
if err != nil {

View File

@@ -18,9 +18,11 @@ package cli
import (
"context"
"encoding/json"
"fmt"
"sort"
"strings"
"time"
"github.com/crossplane/crossplane-runtime/pkg/meta"
"github.com/fatih/color"
@@ -37,9 +39,17 @@ import (
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
apitypes "k8s.io/apimachinery/pkg/types"
"github.com/oam-dev/kubevela/apis/types"
velacmd "github.com/oam-dev/kubevela/pkg/cmd"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/utils/common"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
)
@@ -213,11 +223,17 @@ func NewClusterJoinCommand(c *common.Args, ioStreams cmdutil.IOStreams) *cobra.C
if err != nil {
return err
}
cmd.Printf("Successfully add cluster %s, endpoint: %s.\n", clusterName, clusterConfig.Cluster.Server)
if len(labels) > 0 {
return addClusterLabels(cmd, c, clusterName, labels)
if err := addClusterLabels(cmd, c, clusterName, labels); err != nil {
return fmt.Errorf("error in adding cluster labels: %w", err)
}
}
if err := updateAppsWithTopologyPolicy(ctx, cmd, client); err != nil {
return fmt.Errorf("error in updating apps with topology policy: %w", err)
}
cmd.Printf("Successfully add cluster %s, endpoint: %s.\n", clusterName, clusterConfig.Cluster.Server)
return nil
},
}
@@ -232,6 +248,97 @@ func NewClusterJoinCommand(c *common.Args, ioStreams cmdutil.IOStreams) *cobra.C
return cmd
}
// updateAppsWithTopologyPolicy iterates through all Application resources in the cluster,
// and updates those that have a cluster-level label selector defined in topology policy.
// For each matching application, it sets or updates publish version annotation.
func updateAppsWithTopologyPolicy(ctx context.Context, cmd *cobra.Command, k8sClient client.Client) error {
var continueToken string
const pageSize = 100 // Adjust based on performance needs
for {
// List every Application once, update only those with a cluster label selector.
applicationList := &v1beta1.ApplicationList{}
listOpts := &client.ListOptions{
Limit: pageSize,
Continue: continueToken,
}
if err := k8sClient.List(ctx, applicationList, listOpts); err != nil {
return fmt.Errorf("failed to list applications: %w", err)
}
for i := range applicationList.Items { // index-based to avoid copies
app := &applicationList.Items[i]
matched, err := hasClusterLabelSelector(app.Spec.Policies)
if err != nil {
return fmt.Errorf("failed to check clusterlabelselector for application %s in namespace %s: %w", app.Name, app.Namespace, err)
}
if !matched {
continue
}
// Retry loop for conflict handling
const maxRetries = 5
for attempt := 0; attempt < maxRetries; attempt++ {
// Refresh the object to get the latest resourceVersion (only after 1st attempt)
if attempt > 0 {
key := apitypes.NamespacedName{Namespace: app.Namespace, Name: app.Name}
if err := k8sClient.Get(ctx, key, app); err != nil {
return fmt.Errorf("failed to refetch app %s in namespace %s: %w", app.Name, app.Namespace, err)
}
}
// Update logic
oam.SetPublishVersion(app, util.GenerateVersion("clusterjoin"))
if err := k8sClient.Update(ctx, app); err != nil {
if apierrors.IsConflict(err) {
// Retry if there's a conflict
if attempt == maxRetries-1 {
return fmt.Errorf("conflict error updating app %s in namespace %s after %d retries: %w", app.Name, app.Namespace, maxRetries, err)
}
cmd.Printf("Conflict updating app %s in namespace %s, retrying (%d/%d)...\n", app.Name, app.Namespace, attempt+1, maxRetries)
time.Sleep(500 * time.Millisecond)
continue
}
// Non-conflict error, return it
return fmt.Errorf("error updating app %s in namespace %s: %w", app.Name, app.Namespace, err)
}
if attempt > 0 {
cmd.Printf("Successfully updated app %s in namespace %s after %d retries.\n", app.Name, app.Namespace, attempt)
}
// Successful update
break
}
}
continueToken = applicationList.Continue
if continueToken == "" {
break // No more pages
}
}
return nil
}
// hasClusterLabelSelector returns true when at least one topology policy
// has an explicit clusterLabelSelector.
func hasClusterLabelSelector(policies []v1beta1.AppPolicy) (bool, error) {
for _, p := range policies {
if p.Type != "topology" || p.Properties == nil || len(p.Properties.Raw) == 0 {
continue
}
var tp v1alpha1.Placement
if err := json.Unmarshal(p.Properties.Raw, &tp); err != nil {
return false, fmt.Errorf("error in unmarshalling policy %v: %w", p, err)
}
if tp.ClusterLabelSelector != nil {
return true, nil
}
}
return false, nil
}
// NewClusterRenameCommand create command to help user rename cluster
func NewClusterRenameCommand(c *common.Args) *cobra.Command {
cmd := &cobra.Command{

View File

@@ -0,0 +1,189 @@
/*
Copyright 2022 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cli
import (
"context"
"fmt"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/oam"
)
var (
appWithoutTopologyPolicyYaml = `
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-without-policies
namespace: vela-system
spec:
components:
- name: nginx-basic
type: webservice
properties:
image: nginx
`
appWithTopologyClustersYaml = `
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: basic-topology
namespace: default
spec:
components:
- name: nginx-basic
type: webservice
properties:
image: nginx
policies:
- name: topology-hangzhou-clusters
type: topology
properties:
clusters: ["hangzhou-1", "hangzhou-2"]
`
appWithTopologyClusterLabelSelectorYaml = `
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: region-selector
namespace: vela-system
spec:
components:
- name: nginx-basic
type: webservice
properties:
image: nginx
policies:
- name: topology-hangzhou-clusters
type: topology
properties:
clusterLabelSelector:
region: hangzhou
`
appWithEmptyTopologyClusterLabelSelectorYaml = `
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: empty-cluster-selector
namespace: default
spec:
components:
- name: nginx-basic
type: webservice
properties:
image: nginx
policies:
- name: topology-hangzhou-clusters
type: topology
properties:
clusterLabelSelector: {}
`
)
var _ = Describe("Test updateAppsWithTopologyPolicy", func() {
var _ = When("app does not have topology policy", func() {
It("app should not have publish version annotation set", func() {
err := createApplication(appWithoutTopologyPolicyYaml)
Expect(err).Should(BeNil())
cmd := &cobra.Command{}
err = updateAppsWithTopologyPolicy(context.Background(), cmd, k8sClient)
Expect(err).Should(BeNil())
matched, err := hasPublishVersionAnnotation("app-without-policies", "vela-system")
Expect(err).Should(BeNil())
Expect(matched).Should(BeFalse())
})
})
var _ = When("app has topology policy without clusterLabelSelector", func() {
It("app should not have publish version annotation set", func() {
err := createApplication(appWithTopologyClustersYaml)
Expect(err).Should(BeNil())
cmd := &cobra.Command{}
err = updateAppsWithTopologyPolicy(context.Background(), cmd, k8sClient)
Expect(err).Should(BeNil())
matched, err := hasPublishVersionAnnotation("basic-topology", "default")
Expect(err).Should(BeNil())
Expect(matched).Should(BeFalse())
})
})
var _ = When("app has topology policy with clusterLabelSelector", func() {
It("app should have publish version annotation set", func() {
err := createApplication(appWithTopologyClusterLabelSelectorYaml)
Expect(err).Should(BeNil())
cmd := &cobra.Command{}
err = updateAppsWithTopologyPolicy(context.Background(), cmd, k8sClient)
Expect(err).Should(BeNil())
matched, err := hasPublishVersionAnnotation("region-selector", "vela-system")
Expect(err).Should(BeNil())
Expect(matched).Should(BeTrue())
})
})
var _ = When("app has topology policy with empty clusterLabelSelector", func() {
It("app should have publish version annotation set", func() {
err := createApplication(appWithEmptyTopologyClusterLabelSelectorYaml)
Expect(err).Should(BeNil())
cmd := &cobra.Command{}
err = updateAppsWithTopologyPolicy(context.Background(), cmd, k8sClient)
Expect(err).Should(BeNil())
matched, err := hasPublishVersionAnnotation("empty-cluster-selector", "default")
Expect(err).Should(BeNil())
Expect(matched).Should(BeTrue())
})
})
})
func createApplication(appYaml string) error {
app := v1beta1.Application{}
if err := yaml.Unmarshal([]byte(appYaml), &app); err != nil {
return fmt.Errorf("unmarshal error for yaml %s: %w", appYaml, err)
}
if err := k8sClient.Create(context.Background(), &app); err != nil {
return fmt.Errorf("error in creating app %s in namespace %s: %w", app.Name, app.Namespace, err)
}
return nil
}
func hasPublishVersionAnnotation(name, namespace string) (bool, error) {
app := &v1beta1.Application{}
if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, app); err != nil {
return false, fmt.Errorf("error in getting application %s in namespace %s: %w", name, namespace, err)
}
annotations := app.GetAnnotations()
if annotations != nil && annotations[oam.AnnotationPublishVersion] != "" {
return true, nil
}
return false, nil
}

View File

@@ -101,9 +101,9 @@ func DefinitionCommandGroup(c common.Args, order string, ioStreams util.IOStream
}
func getPrompt(cmd *cobra.Command, reader *bufio.Reader, description string, prompt string, validate func(string) error) (string, error) {
cmd.Printf(description)
cmd.Printf("%s", description)
for {
cmd.Printf(prompt)
cmd.Printf("%s", prompt)
resp, err := reader.ReadString('\n')
resp = strings.TrimSpace(resp)
if err != nil {
@@ -133,12 +133,14 @@ func buildTemplateFromYAML(templateYAML string, def *pkgdef.Definition) error {
process.OutputsFieldName: map[string]interface{}{},
process.ParameterFieldName: map[string]interface{}{},
}
kind := def.GetKind()
for index, yamlString := range yamlStrings {
var yamlObject map[string]interface{}
if err = yaml.Unmarshal([]byte(yamlString), &yamlObject); err != nil {
return errors.Wrapf(err, "failed to unmarshal template yaml file")
}
if index == 0 {
if index == 0 && kind != v1beta1.TraitDefinitionKind {
templateObject[process.OutputFieldName] = yamlObject
} else {
name, _, _ := unstructured.NestedString(yamlObject, "metadata", "name")
@@ -1140,7 +1142,7 @@ func NewDefinitionGenAPICommand(c common.Args) *cobra.Command {
}
}
cmd.Flags().StringSliceVar(&languageArgs, "language-args", []string{},
fmt.Sprintf("language-specific arguments to pass to the go generator, available options: \n"+langArgsDescStr),
fmt.Sprintf("language-specific arguments to pass to the go generator, available options: \n%s", langArgsDescStr),
)
return cmd

View File

@@ -82,7 +82,7 @@ func NewInstallCommand(c common.Args, order string, ioStreams util.IOStreams) *c
Short: "Installs or Upgrades Kubevela control plane on a Kubernetes cluster.",
Long: "The Kubevela CLI allows installing Kubevela on any Kubernetes derivative to which your kube config is pointing to.",
Args: cobra.ExactArgs(0),
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(_ *cobra.Command, args []string) error {
// CheckRequirements
ioStreams.Info("Check Requirements ...")
restConfig, err := c.GetConfig()

View File

@@ -353,8 +353,8 @@ func loopCheckStatus(c client.Client, ioStreams cmdutil.IOStreams, appName strin
if comp.Namespace != "" {
nsStat = "Namespace: " + comp.Namespace
}
ioStreams.Infof(fmt.Sprintf(" - Name: %s %s\n", compName, envStat))
ioStreams.Infof(fmt.Sprintf(" Cluster: %s %s\n", comp.Cluster, nsStat))
ioStreams.Infof("%s", fmt.Sprintf(" - Name: %s %s\n", compName, envStat))
ioStreams.Infof("%s", fmt.Sprintf(" Cluster: %s %s\n", comp.Cluster, nsStat))
ioStreams.Infof(" Type: %s\n", getComponentType(remoteApp, compName))
healthColor := getHealthStatusColor(comp.Healthy)
healthInfo := strings.ReplaceAll(comp.Message, "\n", "\n\t") // format healthInfo output
@@ -385,7 +385,7 @@ func loopCheckStatus(c client.Client, ioStreams cmdutil.IOStreams, appName strin
if tr.Message != "" {
traitBase += ": " + tr.Message
}
ioStreams.Infof(traitBase)
ioStreams.Infof("%s", traitBase)
}
ioStreams.Info("")
}

View File

@@ -275,7 +275,7 @@ func GetServiceEndpoints(ctx context.Context, appName string, namespace string,
return nil, err
}
if response.Error != "" {
return nil, fmt.Errorf(response.Error)
return nil, fmt.Errorf("%s", response.Error)
}
return response.Endpoints, nil
}
@@ -305,7 +305,7 @@ func GetApplicationPods(ctx context.Context, appName string, namespace string, v
return nil, err
}
if response.Error != "" {
return nil, fmt.Errorf(response.Error)
return nil, fmt.Errorf("%s", response.Error)
}
return response.Pods, nil
}
@@ -334,7 +334,7 @@ func GetApplicationServices(ctx context.Context, appName string, namespace strin
return nil, err
}
if response.Error != "" {
return nil, fmt.Errorf(response.Error)
return nil, fmt.Errorf("%s", response.Error)
}
return response.Services, nil
}

View File

@@ -224,7 +224,7 @@ func (o *AppfileOptions) ApplyApp(app *corev1beta1.Application, scopes []oam.Obj
if err := o.apply(app, scopes); err != nil {
return err
}
o.IO.Infof(Info(app))
o.IO.Infof("%s", Info(app))
return nil
}
@@ -262,7 +262,7 @@ func ApplyApplication(app corev1beta1.Application, ioStream cmdutil.IOStreams, c
if err != nil {
return err
}
ioStream.Infof(Info(&app))
ioStream.Infof("%s", Info(&app))
return nil
}

View File

@@ -0,0 +1,40 @@
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: postgres
spec:
components:
- name: postgres
type: statefulset
properties:
cpu: "1"
exposeType: ClusterIP
# see https://hub.docker.com/_/postgres
image: docker.io/library/postgres:16.4
memory: 2Gi
ports:
- expose: true
port: 5432
protocol: TCP
env:
- name: POSTGRES_DB
value: mydb
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: kvsecretpwd123
traits:
- type: scaler
properties:
replicas: 1
- type: storage
properties:
pvc:
- name: "postgresdb-pvc"
storageClassName: local-path
resources:
requests:
storage: "2Gi"
mountPath: "/var/lib/postgresql/data"
```

View File

@@ -299,7 +299,7 @@ var _ = Describe("Test multicluster standalone scenario", func() {
revs, err := application.GetSortedAppRevisions(hubCtx, k8sClient, app.Name, namespace)
g.Expect(err).Should(Succeed())
g.Expect(len(revs)).Should(Equal(1))
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
}).WithTimeout(5 * time.Minute).WithPolling(2 * time.Second).Should(Succeed())
})
It("Test large application parallel apply and delete", func() {

View File

@@ -0,0 +1,230 @@
/*
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 controllers_test
import (
"context"
"encoding/json"
"fmt"
"time"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"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/pkg/oam/util"
)
var _ = Describe("Application required-parameter validation", Ordered, func() {
var (
ctx context.Context
nsName string
namespace corev1.Namespace
)
BeforeAll(func() {
ctx = context.Background()
nsName = randomNamespaceName("requiredparam-validation-test")
namespace = corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName}}
By("creating the test namespace")
Eventually(func() error {
return k8sClient.Create(ctx, &namespace)
}, 3*time.Second, 300*time.Millisecond).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
By("Apply the component definition")
Expect(k8sClient.Create(ctx, newConfigMapComponent(nsName))).To(Succeed())
})
AfterEach(func() {
By("Cleaning up resources after each test")
Expect(k8sClient.DeleteAllOf(ctx, &v1beta1.Application{}, client.InNamespace(nsName))).To(Succeed())
})
AfterAll(func() {
By("Cleaning up resources after all the test")
Expect(k8sClient.DeleteAllOf(ctx, &v1beta1.ComponentDefinition{}, client.InNamespace(nsName))).To(Succeed())
Expect(k8sClient.Delete(ctx, &namespace)).To(Succeed())
})
// -------------------------------------------------------------------------
// Scenario 1: missing parameter → expect failure
// -------------------------------------------------------------------------
It("fails when the required parameter is missing", func() {
app := appWithWorkflow.DeepCopy()
app.Name = "app-missing-param"
app.Namespace = nsName
err := k8sClient.Create(ctx, app)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(`component %q: missing parameters: secondkey.value2.value3.value5`, "configmap-component")))
})
// -------------------------------------------------------------------------
// Scenario 2: param provided via workflow → expect success
// -------------------------------------------------------------------------
It("succeeds when the parameter is provided in the workflow", func() {
app := appWithWorkflow.DeepCopy()
app.Name = "app-with-param-wf"
app.Namespace = nsName
// inject missing parameter
app.Spec.Workflow.Steps[0].Inputs = append(app.Spec.Workflow.Steps[0].Inputs,
workflowv1alpha1.InputItem{
ParameterKey: "secondkey.value2.value3.value5",
From: "dummy",
})
Expect(k8sClient.Create(ctx, app)).To(Succeed())
})
// -------------------------------------------------------------------------
// Scenario 3: param provided via policy → expect success
// -------------------------------------------------------------------------
It("succeeds when the parameter is provided in a policy", func() {
app := appWithPolicy.DeepCopy()
app.Name = "app-with-param-policy"
app.Namespace = nsName
Expect(k8sClient.Create(ctx, app)).To(Succeed())
})
})
/* -------------------------------------------------------------------------- */
/* Helpers */
/* -------------------------------------------------------------------------- */
func newConfigMapComponent(namespace string) *v1beta1.ComponentDefinition {
return &v1beta1.ComponentDefinition{
TypeMeta: metav1.TypeMeta{
Kind: "ComponentDefinition",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "configmap-component",
Namespace: namespace, // set it here
},
Spec: v1beta1.ComponentDefinitionSpec{
Schematic: &common.Schematic{
CUE: &common.CUE{Template: configMapOutputTemp},
},
},
}
}
var configMapOutputTemp = `
parameter: {
firstkey: string & !="" & !~".*-$"
secondkey: {
value1: string
value2: {
value3: {
value4: *"default-value-2" | string
value5: string
}
}
}
thirdkey?: string
}
output: {
apiVersion: "v1"
kind: "ConfigMap"
metadata: { name: context.name }
data: {
one: parameter.firstkey
two: parameter.secondkey.value2.value3.value5
three: parameter.secondkey.value1
four: parameter.thirdkey
}
}
`
var appWithWorkflow = v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "configmap-component",
Type: "configmap-component",
Properties: &runtime.RawExtension{Raw: []byte(`{
"secondkey": { "value2": { "value3": { "value4": "1" } } }
}`)},
}},
Workflow: &v1beta1.Workflow{
Steps: []workflowv1alpha1.WorkflowStep{{
WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{
Name: "apply",
Type: "apply-component",
Inputs: workflowv1alpha1.StepInputs{
{ParameterKey: "firstkey", From: "dummy1"},
{ParameterKey: "secondkey.value1", From: "dummy2"},
{ParameterKey: "thirdkey", From: "dummy3"},
},
Properties: util.Object2RawExtension(map[string]any{"component": "express-server"}),
},
}},
},
},
}
var appWithPolicy = v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "app-policy",
Type: "configmap-component",
Properties: &runtime.RawExtension{Raw: []byte(`{
"secondkey": { "value2": { "value3": { "value4": "1" } } }
}`)},
}},
Policies: []v1beta1.AppPolicy{{
Name: "override-configmap-data",
Type: "override",
Properties: &runtime.RawExtension{Raw: mustJSON(policyProperties)},
}},
},
}
var policyProperties = map[string]any{
"components": []any{map[string]any{
"name": "express-server",
"properties": map[string]any{
"firstkey": "nginx:1.20",
"secondkey": map[string]any{
"value1": "abc",
"value2": map[string]any{
"value3": map[string]any{
"value5": "1",
},
},
},
"thirdkey": "123",
},
}},
}
func mustJSON(v any) []byte {
out, err := json.Marshal(v)
if err != nil {
panic(err)
}
return out
}

View File

@@ -0,0 +1,610 @@
import (
"strconv"
"strings"
)
statefulset: {
type: "component"
annotations: {}
labels: {}
description: "Describes long-running, scalable, containerized services used to manage stateful application, like database."
attributes: {
workload: {
definition: {
apiVersion: "apps/v1"
kind: "StatefulSet"
}
type: "statefulsets.apps"
}
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
}
}
"""#
}
}
}
template: {
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
}
}

View File

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

View File

@@ -254,16 +254,32 @@ template: {
}
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
}
}
}
@@ -468,6 +484,11 @@ template: {
// +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

@@ -33,8 +33,9 @@ template: {
parameter: {
// +usage=Specify the AppArmor profile for the pod
appArmorProfile?: {
type: "RuntimeDefault" | "Unconfined" | "Localhost"
localhostProfile: string
type: "RuntimeDefault" | "Unconfined" | "Localhost"
// +usage: localhostProfile is required when type is 'Localhost'
localhostProfile?: string
}
fsGroup?: int
runAsGroup?: int
@@ -44,8 +45,9 @@ template: {
runAsNonRoot: *true | bool
// +usage=Specify the seccomp profile for the pod
seccompProfile?: {
type: "RuntimeDefault" | "Unconfined" | "Localhost"
localhostProfile: string
type: "RuntimeDefault" | "Unconfined" | "Localhost"
// +usage: localhostProfile is required when type is 'Localhost'
localhostProfile?: string
}
}
}

View File

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

View File

@@ -0,0 +1,40 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: postgres
spec:
components:
- name: postgres
type: statefulset
properties:
cpu: "1"
exposeType: ClusterIP
# see https://hub.docker.com/_/postgres
image: docker.io/library/postgres:16.4
memory: 2Gi
ports:
- expose: true
port: 5432
protocol: TCP
env:
- name: POSTGRES_DB
value: mydb
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: kvsecretpwd123
traits:
- type: scaler
properties:
replicas: 1
- type: storage
properties:
pvc:
- name: "postgresdb-pvc"
storageClassName: local-path
resources:
requests:
storage: "2Gi"
mountPath: "/var/lib/postgresql/data"

View File

@@ -0,0 +1,24 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: application-with-storage
spec:
components:
- name: busybox-runner2
type: webservice
properties:
image: busybox
cmd:
- sleep
- '1000'
traits:
- type: storage
properties:
pvc:
- name: "busybox-pvc2"
storageClassName: local-path
resources:
requests:
storage: "2Gi"
mountPath: "/tmp"