Compare commits

..

26 Commits

Author SHA1 Message Date
dependabot[bot]
9c57c09878 Chore: (deps): Bump goreleaser/goreleaser-action from 4.3.0 to 4.4.0 (#6267)
Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 4.3.0 to 4.4.0.
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](336e29918d...3fa32b8bb5)

---
updated-dependencies:
- dependency-name: goreleaser/goreleaser-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>
2023-08-15 11:52:59 +08:00
dependabot[bot]
cc1ac251ce Chore: (deps): Bump github.com/google/go-containerregistry (#6264)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.15.2 to 0.16.1.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.15.2...v0.16.1)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  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>
2023-08-15 11:52:24 +08:00
dependabot[bot]
18fb098fce Chore: (deps): Bump golang.org/x/text from 0.11.0 to 0.12.0 (#6262)
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.11.0...v0.12.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  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>
2023-08-15 11:51:51 +08:00
qiaozp
5a5721048c Refactor: organize appHandler, remove unused flags (#6254) 2023-08-11 12:50:22 +08:00
qiaozp
bab5bb2caf Refactor: capabilities and workload in appfile parsing (#6250) 2023-08-10 14:41:20 +08:00
dependabot[bot]
cce1859294 Chore: (deps): Bump github.com/go-git/go-git/v5 from 5.7.0 to 5.8.1 (#6239)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-08 17:11:03 +08:00
Daniel Higuero
72bb0798ef Fix: test timeout due to hardcoded goproxy (#6246)
Co-authored-by: JohnJan <wuzhongjian_yewu@cmss.chinamobile.com>
2023-08-08 09:43:41 +08:00
qiaozp
29aa2b9644 Fix: issue bot permission (#6245) 2023-08-07 17:10:50 +08:00
qiaozp
307d1db36d Chore: revert "Feat: apply-component supports namespace" (#6247) 2023-08-07 15:44:20 +08:00
qiaozp
00ae0c9494 Feat: support offline dryrun with deploy step (#6234) 2023-07-26 18:09:01 +08:00
JohnJan
f0357fdc8f Feat: apply-component supports namespace (#6228)
* Feat: apply-component supports namespace

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Feat: apply-component supports namespace

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

---------

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2023-07-25 10:31:18 +08:00
dependabot[bot]
ef8b0ac00f Chore: (deps): Bump github.com/mattn/go-runewidth from 0.0.14 to 0.0.15 (#6229)
Bumps [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth) from 0.0.14 to 0.0.15.
- [Commits](https://github.com/mattn/go-runewidth/compare/v0.0.14...v0.0.15)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-runewidth
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-24 17:23:38 +08:00
suwliang3
aaaf2bddac bug: The log printing error for the addon module (#6207)
Signed-off-by: suwanliang <suwanliang@cmss.chinamobile.com>
Co-authored-by: suwanliang <suwanliang@cmss.chinamobile.com>
2023-07-24 17:22:53 +08:00
dependabot[bot]
eeb6f08edf Chore: (deps): Bump golang.org/x/tools from 0.10.0 to 0.11.0 (#6217)
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.10.0 to 0.11.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  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>
2023-07-24 13:37:50 +08:00
JohnJan
b9f1cc97a9 Feat: add container-ports trait for hostPort and hostIP (#6187)
* Feat: add container-ports trait for hostPort and hostIP

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Feat: add container-ports trait for hostPort and hostIP

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Feat: add container-ports trait for hostPort and hostIP

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Feat: add container-ports trait for hostPort and hostIP

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

* Feat: add container-ports trait for hostPort and hostIP

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>

---------

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2023-07-11 18:44:05 +08:00
Jianbo Sun
2117554d53 Fix: add deploy as built-in step to avoid parse in offline mode (#6201) 2023-07-11 17:23:32 +08:00
dependabot[bot]
9edd6ebc30 Chore: (deps): Bump golang.org/x/oauth2 from 0.9.0 to 0.10.0 (#6195)
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.9.0 to 0.10.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.9.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  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>
2023-07-11 09:51:26 +08:00
dependabot[bot]
ccdfc409a8 Chore: (deps): Bump golang.org/x/term from 0.9.0 to 0.10.0 (#6197)
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.9.0 to 0.10.0.
- [Commits](https://github.com/golang/term/compare/v0.9.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/term
  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>
2023-07-10 22:43:09 +08:00
dependabot[bot]
449b3e0b49 Chore: (deps): Bump RyanSiu1995/kubebuilder-action (#6192)
Bumps [RyanSiu1995/kubebuilder-action](https://github.com/ryansiu1995/kubebuilder-action) from ed0e300b13152c2c2bfb104475665c7bf609332f to 7170cb0476187070ae04cbb6cee305e809de2693.
- [Release notes](https://github.com/ryansiu1995/kubebuilder-action/releases)
- [Commits](ed0e300b13...7170cb0476)

---
updated-dependencies:
- dependency-name: RyanSiu1995/kubebuilder-action
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 22:42:39 +08:00
dependabot[bot]
8be1fb29b4 Chore: (deps): Bump github.com/prometheus/client_golang (#6198)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.15.1 to 1.16.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.15.1...v1.16.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  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>
2023-07-10 19:33:45 +08:00
dependabot[bot]
b42e6cf1e6 Chore: (deps): Bump golang.org/x/text from 0.10.0 to 0.11.0 (#6196)
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.10.0 to 0.11.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  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>
2023-07-10 19:32:43 +08:00
dependabot[bot]
096afa227b Chore: (deps): Bump docker/setup-buildx-action from 2.8.0 to 2.9.0 (#6193)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2.8.0 to 2.9.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](16c0bc4a6e...2a1a44ac4a)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 19:32:16 +08:00
dependabot[bot]
57b74c3687 Chore: (deps): Bump actions/setup-node from 3.6.0 to 3.7.0 (#6194)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.6.0 to 3.7.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](64ed1c7eab...e33196f742)

---
updated-dependencies:
- dependency-name: actions/setup-node
  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>
2023-07-10 19:24:58 +08:00
dependabot[bot]
9203bbcdb8 Chore: (deps): Bump github.com/kubevela/workflow (#6177)
Bumps [github.com/kubevela/workflow](https://github.com/kubevela/workflow) from 0.5.1-0.20230412142834-be9e5a10baf0 to 0.6.0.
- [Release notes](https://github.com/kubevela/workflow/releases)
- [Commits](https://github.com/kubevela/workflow/commits/v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/kubevela/workflow
  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>
2023-07-06 16:48:47 +08:00
JohnJan
f3e920ab60 Refactor: parse workloads (#6185)
Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2023-07-05 09:49:34 +08:00
Tanjim Hossain
6893a2b776 fix arm64 build, rm --platform flags in Dockerfile (#6170)
explicitly specify alpine version



explicitly specify alpine version

Signed-off-by: Audacious Tux <tangimhossain1@gmail.com>
2023-07-04 15:39:58 +08:00
58 changed files with 969 additions and 889 deletions

View File

@@ -28,7 +28,7 @@ jobs:
with:
version: v3.4.0
- name: Setup node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8
with:
node-version: '14'
- name: Generate helm doc

View File

@@ -104,7 +104,7 @@ jobs:
go-version: ${{ env.GO_VERSION }}
- name: Setup node
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8
with:
node-version: '14'
@@ -176,7 +176,7 @@ jobs:
- name: Set up QEMU
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@16c0bc4a6e6ada2cfd8afd41d22d95379cf7c32a # v2.8.0
uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0
- name: Build Test for vela core
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
with:
@@ -196,7 +196,7 @@ jobs:
- name: Set up QEMU
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@16c0bc4a6e6ada2cfd8afd41d22d95379cf7c32a # v2.8.0
uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0
- name: Build Test for CLI
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
with:

View File

@@ -7,6 +7,7 @@ on:
permissions:
contents: read
issues: write
jobs:
bot:
@@ -22,7 +23,7 @@ jobs:
path: ./actions
ref: v0.4.2
- name: Setup Node.js
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8
with:
node-version: '14'
cache: 'npm'

View File

@@ -43,7 +43,7 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
- uses: docker/setup-buildx-action@16c0bc4a6e6ada2cfd8afd41d22d95379cf7c32a # v2.8.0
- uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0
with:
driver-opts: image=moby/buildkit:master

View File

@@ -33,7 +33,7 @@ jobs:
with:
go-version: 1.19
cache: true
- uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # v4.3.0
- uses: goreleaser/goreleaser-action@3fa32b8bb5620a2c1afe798654bbad59f9da4906 # v4.4.0
with:
distribution: goreleaser
version: 1.14.1

View File

@@ -71,7 +71,7 @@ jobs:
kind create cluster
- name: install Kubebuilder
uses: RyanSiu1995/kubebuilder-action@ed0e300b13152c2c2bfb104475665c7bf609332f
uses: RyanSiu1995/kubebuilder-action@7170cb0476187070ae04cbb6cee305e809de2693
with:
version: 3.9.1
kubebuilderOnly: false

View File

@@ -1,6 +1,6 @@
ARG BASE_IMAGE
# Build the manager binary
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-alpine@sha256:2381c1e5f8350a901597d633b2e517775eeac7a6682be39225a93b22cfd0f8bb as builder
FROM golang:1.19-alpine3.18 as builder
WORKDIR /workspace
# Copy the Go Modules manifests
@@ -34,7 +34,7 @@ RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} \
# You can replace distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
# Overwrite `BASE_IMAGE` by passing `--build-arg=BASE_IMAGE=gcr.io/distroless/static:nonroot`
FROM ${BASE_IMAGE:-alpine@sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501}
FROM ${BASE_IMAGE:-alpine:3.18}
# This is required by daemon connecting with cri
RUN apk add --no-cache ca-certificates bash expat

View File

@@ -32,22 +32,6 @@ type CRDInfo struct {
Kind string `json:"kind"`
}
// Chart defines all necessary information to install a whole chart
type Chart struct {
Repo string `json:"repo"`
URL string `json:"url"`
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
Version string `json:"version"`
Values map[string]interface{} `json:"values"`
}
// Installation defines the installation method for this Capability, currently only helm is supported
type Installation struct {
Helm Chart `json:"helm"`
// TODO(wonderflow) add raw yaml file support for install capability
}
// CapType defines the type of capability
type CapType string
@@ -107,7 +91,6 @@ type Capability struct {
CueTemplateURI string `json:"templateURI,omitempty"`
Parameters []Parameter `json:"parameters,omitempty"`
CrdName string `json:"crdName,omitempty"`
Center string `json:"center,omitempty"`
Status string `json:"status,omitempty"`
Description string `json:"description,omitempty"`
Example string `json:"example,omitempty"`
@@ -121,8 +104,7 @@ type Capability struct {
Namespace string `json:"namespace,omitempty"`
// Plugin Source
Source *Source `json:"source,omitempty"`
CrdInfo *CRDInfo `json:"crdInfo,omitempty"`
Source *Source `json:"source,omitempty"`
// Terraform
TerraformConfiguration string `json:"terraformConfiguration,omitempty"`

View File

@@ -0,0 +1,139 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/container-ports.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Expose on the host and bind the external port to host to enable web traffic for your component.
name: container-ports
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:
template: |
import (
"strconv"
"strings"
)
#PatchParams: {
// +usage=Specify the name of the target container, if not set, use the component name
containerName: *"" | string
// +usage=Specify ports you want customer traffic sent to
ports: *[] | [...{
// +usage=Number of port to expose on the pod's IP address
containerPort: int
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
protocol: *"TCP" | "UDP" | "SCTP"
// +usage=Number of port to expose on the host
hostPort?: int
// +usage=What host IP to bind the external port to.
hostIP?: string
}]
}
PatchContainer: {
_params: #PatchParams
name: _params.containerName
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
_baseContainer: *_|_ | {...}
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
}
if len(_matchContainers_) > 0 {
_baseContainer: _matchContainers_[0]
_basePorts: _baseContainer.ports
if _basePorts == _|_ {
// +patchStrategy=replace
ports: [ for port in _params.ports {
containerPort: port.containerPort
protocol: port.protocol
if port.hostPort != _|_ {
hostPort: port.hostPort
}
if port.hostIP != _|_ {
hostIP: port.hostIP
}
}]
}
if _basePorts != _|_ {
_basePortsMap: {for _basePort in _basePorts {(strings.ToLower(_basePort.protocol) + strconv.FormatInt(_basePort.containerPort, 10)): _basePort}}
_portsMap: {for port in _params.ports {(strings.ToLower(port.protocol) + strconv.FormatInt(port.containerPort, 10)): port}}
// +patchStrategy=replace
ports: [ for portVar in _basePorts {
containerPort: portVar.containerPort
protocol: portVar.protocol
_uniqueKey: strings.ToLower(portVar.protocol) + strconv.FormatInt(portVar.containerPort, 10)
if _portsMap[_uniqueKey] != _|_ {
if _portsMap[_uniqueKey].hostPort != _|_ {
hostPort: _portsMap[_uniqueKey].hostPort
}
if _portsMap[_uniqueKey].hostIP != _|_ {
hostIP: _portsMap[_uniqueKey].hostIP
}
}
if _portsMap[_uniqueKey] == _|_ {
if portVar.name != _|_ {
name: portVar.name
}
}
}] + [ for port in _params.ports if _basePortsMap[strings.ToLower(port.protocol)+strconv.FormatInt(port.containerPort, 10)] == _|_ {
if port.containerPort != _|_ {
containerPort: port.containerPort
}
if port.protocol != _|_ {
protocol: port.protocol
}
if port.hostPort != _|_ {
hostPort: port.hostPort
}
if port.hostIP != _|_ {
hostIP: port.hostIP
}
}]
}
}
}
patch: spec: template: spec: {
if parameter.containers == _|_ {
// +patchKey=name
containers: [{
PatchContainer & {_params: {
if parameter.containerName == "" {
containerName: context.name
}
if parameter.containerName != "" {
containerName: parameter.containerName
}
ports: parameter.ports
}}
}]
}
if parameter.containers != _|_ {
// +patchKey=name
containers: [ for c in parameter.containers {
if c.containerName == "" {
err: "container name must be set for containers"
}
if c.containerName != "" {
PatchContainer & {_params: c}
}
}]
}
}
parameter: *#PatchParams | close({
// +usage=Specify the container ports for multiple containers
containers: [...#PatchParams]
})
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]

View File

@@ -81,7 +81,6 @@ func NewCoreOptions() *CoreOptions {
DefRevisionLimit: 20,
AutoGenWorkloadDefinition: true,
ConcurrentReconciles: 4,
EnableCompatibility: false,
IgnoreAppWithoutControllerRequirement: false,
IgnoreDefinitionWithoutControllerRequirement: false,
},

View File

@@ -47,7 +47,7 @@ import (
"github.com/oam-dev/kubevela/pkg/auth"
"github.com/oam-dev/kubevela/pkg/cache"
commonconfig "github.com/oam-dev/kubevela/pkg/controller/common"
oamv1alpha2 "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1"
oamv1beta1 "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/application"
"github.com/oam-dev/kubevela/pkg/features"
"github.com/oam-dev/kubevela/pkg/monitor/watcher"
@@ -227,7 +227,7 @@ func prepareRun(ctx context.Context, mgr manager.Manager, s *options.CoreOptions
}
}
if err := oamv1alpha2.Setup(mgr, *s.ControllerArgs); err != nil {
if err := oamv1beta1.Setup(mgr, *s.ControllerArgs); err != nil {
klog.ErrorS(err, "Unable to setup the oam controller")
return err
}

39
go.mod
View File

@@ -24,12 +24,12 @@ require (
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.7.0
github.com/go-git/go-git/v5 v5.8.1
github.com/go-logr/logr v1.2.4
github.com/go-resty/resty/v2 v2.7.0
github.com/golang/mock v1.6.0
github.com/google/go-cmp v0.5.9
github.com/google/go-containerregistry v0.15.2
github.com/google/go-containerregistry v0.16.1
github.com/google/go-github/v32 v32.1.0
github.com/gosuri/uitable v0.0.4
github.com/hashicorp/go-version v1.6.0
@@ -37,10 +37,10 @@ require (
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
github.com/imdario/mergo v0.3.16
github.com/kubevela/pkg v1.8.1-0.20230522085329-7d5e1241a86d
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0
github.com/kubevela/workflow v0.6.0
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/magiconair/properties v1.8.7
github.com/mattn/go-runewidth v0.0.14
github.com/mattn/go-runewidth v0.0.15
github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/nacos-group/nacos-sdk-go/v2 v2.2.2
github.com/oam-dev/cluster-gateway v1.9.0-alpha.2
@@ -54,7 +54,7 @@ require (
github.com/openkruise/rollouts v0.3.0
github.com/pelletier/go-toml v1.9.5
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.15.1
github.com/prometheus/client_golang v1.16.0
github.com/prometheus/client_model v0.4.0
github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9
github.com/rogpeppe/go-internal v1.10.0
@@ -67,12 +67,12 @@ require (
github.com/xanzy/go-gitlab v0.86.0
github.com/xlab/treeprint v1.2.0
go.uber.org/multierr v1.11.0
golang.org/x/crypto v0.10.0
golang.org/x/oauth2 v0.9.0
golang.org/x/crypto v0.11.0
golang.org/x/oauth2 v0.10.0
golang.org/x/sync v0.3.0
golang.org/x/term v0.9.0
golang.org/x/text v0.10.0
golang.org/x/tools v0.10.0
golang.org/x/term v0.10.0
golang.org/x/text v0.12.0
golang.org/x/tools v0.11.0
gomodules.xyz/jsonpatch/v2 v2.3.0
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.11.2
@@ -98,6 +98,7 @@ require (
)
require (
dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/BurntSushi/toml v1.2.1 // indirect
@@ -109,7 +110,7 @@ require (
github.com/Masterminds/squirrel v1.5.3 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/alessio/shellescape v1.4.1 // indirect
@@ -131,9 +132,9 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/creack/pty v1.1.18 // indirect
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/docker/cli v23.0.5+incompatible // indirect
github.com/docker/cli v24.0.0+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v23.0.5+incompatible // indirect
github.com/docker/docker v24.0.0+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
@@ -233,7 +234,7 @@ require (
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
@@ -241,7 +242,7 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/skeema/knownhosts v1.1.1 // indirect
github.com/skeema/knownhosts v1.2.0 // 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
@@ -268,14 +269,14 @@ require (
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
gopkg.in/inf.v0 v0.9.1 // indirect

76
go.sum
View File

@@ -1,12 +1,14 @@
cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cuelang.org/go v0.5.0 h1:D6N0UgTGJCOxFKU8RU+qYvavKNsVc/+ZobmifStVJzU=
cuelang.org/go v0.5.0/go.mod h1:okjJBHFQFer+a41sAe2SaGm1glWS8oEb6CmJvn5Zdws=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0=
@@ -57,8 +59,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 v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek=
github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/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=
@@ -124,7 +126,7 @@ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx2
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
@@ -145,7 +147,6 @@ 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.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -304,8 +305,8 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmS
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
github.com/go-git/go-git/v5 v5.7.0 h1:t9AudWVLmqzlo+4bqdf7GY+46SUuRsx59SboFxkq2aE=
github.com/go-git/go-git/v5 v5.7.0/go.mod h1:coJHKEOk5kUClpsNlXrUvPrDxY3w3gjHvhcZd8Fodw8=
github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gorp/gorp/v3 v3.0.5/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
@@ -429,8 +430,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
@@ -599,8 +600,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.8.1-0.20230522085329-7d5e1241a86d h1:QMmTg33lUZEfTz94eYJKa6Nb7GDcEOmuXsXRt/dA5vk=
github.com/kubevela/pkg v1.8.1-0.20230522085329-7d5e1241a86d/go.mod h1:3ZWrl2+zb5ROdC2NJPPrL/4sun4M10wYfRP/9gF9WJE=
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0 h1:/ZPmjKpd/+fpCjJfNfUnE7jdESuCcZeP+fyTUAU9an0=
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0/go.mod h1:0GhIWFIPP+Zt31m4Aslx9mihoyNz3HrOvCV69ljMIBo=
github.com/kubevela/workflow v0.6.0 h1:fYXviOYD5zqHs3J61tNbM4HZ85EcZlPm7Fyz8Q5o9Fk=
github.com/kubevela/workflow v0.6.0/go.mod h1:sjLcYqKHKeCQ+w77gijoNILwIShJKnCU+e3q7ETtZGI=
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=
@@ -652,8 +653,9 @@ github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPn
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
@@ -824,8 +826,8 @@ github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -852,8 +854,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b h1:zd/2RNzIRkoGGMjE+YIsZ85CnDIz672JK2F3Zl4vux4=
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b/go.mod h1:KjY0wibdYKc4DYkerHSbguaf3JeIPGhNJBp2BNiFH78=
@@ -893,8 +895,8 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
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.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE=
github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
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=
@@ -1116,10 +1118,11 @@ golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
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=
@@ -1142,8 +1145,8 @@ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
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=
@@ -1195,8 +1198,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
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=
@@ -1208,8 +1211,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.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs=
golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw=
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
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=
@@ -1276,7 +1279,6 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1298,8 +1300,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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=
@@ -1311,8 +1313,8 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
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=
@@ -1324,8 +1326,8 @@ golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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=
@@ -1364,8 +1366,8 @@ golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E
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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
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=
@@ -1454,8 +1456,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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
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

@@ -42,7 +42,7 @@ var ComponentDefDirs = []string{"./vela-templates/definitions/internal/component
// CustomComponentHeaderEN .
var CustomComponentHeaderEN = `---
title: Built-in Component Type
title: Built-in ParsedComponents Type
---
This documentation will walk through all the built-in component types sorted alphabetically.

View File

@@ -161,7 +161,6 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
if addonVersion == nil {
return nil, errors.Errorf("specified version %s not exist", utils.Sanitize(version))
}
klog.V(5).Infof("Addon '%s' with version '%s' found from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
for _, chartURL := range addonVersion.URLs {
if !utils.IsValidURL(chartURL) {
chartURL, err = utils.JoinURL(i.url, chartURL)
@@ -186,7 +185,9 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
addonPkg.AvailableVersions = availableVersions
addonPkg.RegistryName = i.name
addonPkg.Meta.SystemRequirements = LoadSystemRequirements(addonVersion.Annotations)
klog.V(5).Infof("Addon '%s' with version '%s' loaded successfully from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
if addonPkg.Name != "" {
klog.V(5).Infof("Addon '%s' with version '%s' loaded successfully from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
}
return addonPkg, nil
}
return nil, ErrFetch

View File

@@ -74,8 +74,10 @@ const (
GitCredentialsSecretReferenceKey = "gitCredentialsSecretReference"
)
// Workload is component
type Workload struct {
// Component is an internal struct for component in application
// User-defined policies are parsed as a Component without any Traits because their purpose is dispatching some resources
// Internal policies are NOT parsed as a Component
type Component struct {
Name string
Type string
CapabilityCategory types.CapabilityCategory
@@ -89,39 +91,39 @@ type Workload struct {
}
// EvalContext eval workload template and set the result to context
func (wl *Workload) EvalContext(ctx process.Context) error {
return wl.engine.Complete(ctx, wl.FullTemplate.TemplateStr, wl.Params)
func (comp *Component) EvalContext(ctx process.Context) error {
return comp.engine.Complete(ctx, comp.FullTemplate.TemplateStr, comp.Params)
}
// GetTemplateContext get workload template context, it will be used to eval status and health
func (wl *Workload) GetTemplateContext(ctx process.Context, client client.Client, accessor util.NamespaceAccessor) (map[string]interface{}, error) {
func (comp *Component) GetTemplateContext(ctx process.Context, client client.Client, accessor util.NamespaceAccessor) (map[string]interface{}, error) {
// if the standard workload is managed by trait, just return empty context
if wl.SkipApplyWorkload {
if comp.SkipApplyWorkload {
return nil, nil
}
templateContext, err := wl.engine.GetTemplateContext(ctx, client, accessor)
templateContext, err := comp.engine.GetTemplateContext(ctx, client, accessor)
if templateContext != nil {
templateContext[velaprocess.ParameterFieldName] = wl.Params
templateContext[velaprocess.ParameterFieldName] = comp.Params
}
return templateContext, err
}
// EvalStatus eval workload status
func (wl *Workload) EvalStatus(templateContext map[string]interface{}) (string, error) {
func (comp *Component) EvalStatus(templateContext map[string]interface{}) (string, error) {
// if the standard workload is managed by trait always return empty message
if wl.SkipApplyWorkload {
if comp.SkipApplyWorkload {
return "", nil
}
return wl.engine.Status(templateContext, wl.FullTemplate.CustomStatus, wl.Params)
return comp.engine.Status(templateContext, comp.FullTemplate.CustomStatus, comp.Params)
}
// EvalHealth eval workload health check
func (wl *Workload) EvalHealth(templateContext map[string]interface{}) (bool, error) {
func (comp *Component) EvalHealth(templateContext map[string]interface{}) (bool, error) {
// if the health of template is not set or standard workload is managed by trait always return true
if wl.SkipApplyWorkload {
if comp.SkipApplyWorkload {
return true, nil
}
return wl.engine.HealthCheck(templateContext, wl.FullTemplate.Health, wl.Params)
return comp.engine.HealthCheck(templateContext, comp.FullTemplate.Health, comp.Params)
}
// Trait is ComponentTrait
@@ -168,9 +170,10 @@ func (trait *Trait) EvalHealth(templateContext map[string]interface{}) (bool, er
// Appfile describes application
type Appfile struct {
Name string
Namespace string
Workloads []*Workload
Name string
Namespace string
ParsedComponents []*Component
ParsedPolicies []*Component
AppRevision *v1beta1.ApplicationRevision
AppRevisionName string
@@ -183,19 +186,17 @@ type Appfile struct {
RelatedComponentDefinitions map[string]*v1beta1.ComponentDefinition
RelatedWorkflowStepDefinitions map[string]*v1beta1.WorkflowStepDefinition
Policies []v1beta1.AppPolicy
PolicyWorkloads []*Workload
Components []common.ApplicationComponent
Artifacts []*types.ComponentManifest
WorkflowSteps []workflowv1alpha1.WorkflowStep
WorkflowMode *workflowv1alpha1.WorkflowExecuteMode
Policies []v1beta1.AppPolicy
Components []common.ApplicationComponent
Artifacts []*types.ComponentManifest
WorkflowSteps []workflowv1alpha1.WorkflowStep
WorkflowMode *workflowv1alpha1.WorkflowExecuteMode
ExternalPolicies map[string]*v1alpha1.Policy
ExternalWorkflow *workflowv1alpha1.Workflow
ReferredObjects []*unstructured.Unstructured
parser *Parser
app *v1beta1.Application
app *v1beta1.Application
Debug bool
}
@@ -204,7 +205,7 @@ type Appfile struct {
// internal policies like apply-once, topology, will not render manifests
func (af *Appfile) GeneratePolicyManifests(ctx context.Context) ([]*unstructured.Unstructured, error) {
var manifests []*unstructured.Unstructured
for _, policy := range af.PolicyWorkloads {
for _, policy := range af.ParsedPolicies {
un, err := af.generatePolicyUnstructured(policy)
if err != nil {
return nil, err
@@ -214,7 +215,7 @@ func (af *Appfile) GeneratePolicyManifests(ctx context.Context) ([]*unstructured
return manifests, nil
}
func (af *Appfile) generatePolicyUnstructured(workload *Workload) ([]*unstructured.Unstructured, error) {
func (af *Appfile) generatePolicyUnstructured(workload *Component) ([]*unstructured.Unstructured, error) {
ctxData := GenerateContextDataFromAppFile(af, workload.Name)
uns, err := generatePolicyUnstructuredFromCUEModule(workload, af.Artifacts, ctxData)
if err != nil {
@@ -231,16 +232,16 @@ func (af *Appfile) generatePolicyUnstructured(workload *Workload) ([]*unstructur
return uns, nil
}
func generatePolicyUnstructuredFromCUEModule(wl *Workload, artifacts []*types.ComponentManifest, ctxData velaprocess.ContextData) ([]*unstructured.Unstructured, error) {
func generatePolicyUnstructuredFromCUEModule(comp *Component, artifacts []*types.ComponentManifest, ctxData velaprocess.ContextData) ([]*unstructured.Unstructured, error) {
pCtx := velaprocess.NewContext(ctxData)
pCtx.PushData(velaprocess.ContextDataArtifacts, prepareArtifactsData(artifacts))
if err := wl.EvalContext(pCtx); err != nil {
if err := comp.EvalContext(pCtx); err != nil {
return nil, errors.Wrapf(err, "evaluate base template app=%s in namespace=%s", ctxData.AppName, ctxData.Namespace)
}
base, auxs := pCtx.Output()
workload, err := base.Unstructured()
if err != nil {
return nil, errors.Wrapf(err, "evaluate base template policy=%s app=%s", wl.Name, ctxData.AppName)
return nil, errors.Wrapf(err, "evaluate base template policy=%s app=%s", comp.Name, ctxData.AppName)
}
commonLabels := definition.GetCommonLabels(definition.GetBaseContextLabels(pCtx))
util.AddLabels(workload, commonLabels)
@@ -249,7 +250,7 @@ func generatePolicyUnstructuredFromCUEModule(wl *Workload, artifacts []*types.Co
for _, assist := range auxs {
tr, err := assist.Ins.Unstructured()
if err != nil {
return nil, errors.Wrapf(err, "evaluate auxiliary=%s template for policy=%s app=%s", assist.Name, wl.Name, ctxData.AppName)
return nil, errors.Wrapf(err, "evaluate auxiliary=%s template for policy=%s app=%s", assist.Name, comp.Name, ctxData.AppName)
}
util.AddLabels(tr, commonLabels)
res = append(res, tr)
@@ -283,10 +284,10 @@ func prepareArtifactsData(comps []*types.ComponentManifest) map[string]interface
// GenerateComponentManifests converts an appFile to a slice of ComponentManifest
func (af *Appfile) GenerateComponentManifests() ([]*types.ComponentManifest, error) {
compManifests := make([]*types.ComponentManifest, len(af.Workloads))
af.Artifacts = make([]*types.ComponentManifest, len(af.Workloads))
for i, wl := range af.Workloads {
cm, err := af.GenerateComponentManifest(wl, nil)
compManifests := make([]*types.ComponentManifest, len(af.ParsedComponents))
af.Artifacts = make([]*types.ComponentManifest, len(af.ParsedComponents))
for i, comp := range af.ParsedComponents {
cm, err := af.GenerateComponentManifest(comp, nil)
if err != nil {
return nil, err
}
@@ -301,21 +302,21 @@ func (af *Appfile) GenerateComponentManifests() ([]*types.ComponentManifest, err
}
// GenerateComponentManifest generate only one ComponentManifest
func (af *Appfile) GenerateComponentManifest(wl *Workload, mutate func(*velaprocess.ContextData)) (*types.ComponentManifest, error) {
func (af *Appfile) GenerateComponentManifest(comp *Component, mutate func(*velaprocess.ContextData)) (*types.ComponentManifest, error) {
if af.Namespace == "" {
af.Namespace = corev1.NamespaceDefault
}
ctxData := GenerateContextDataFromAppFile(af, wl.Name)
ctxData := GenerateContextDataFromAppFile(af, comp.Name)
if mutate != nil {
mutate(&ctxData)
}
// generate context here to avoid nil pointer panic
wl.Ctx = NewBasicContext(ctxData, wl.Params)
switch wl.CapabilityCategory {
comp.Ctx = NewBasicContext(ctxData, comp.Params)
switch comp.CapabilityCategory {
case types.TerraformCategory:
return generateComponentFromTerraformModule(wl, af.Name, af.Namespace)
return generateComponentFromTerraformModule(comp, af.Name, af.Namespace)
default:
return generateComponentFromCUEModule(wl, ctxData)
return generateComponentFromCUEModule(comp, ctxData)
}
}
@@ -393,15 +394,15 @@ func (af *Appfile) setNamespace(obj *unstructured.Unstructured) {
}
}
func (af *Appfile) assembleWorkload(wl *unstructured.Unstructured, compName string, labels map[string]string) {
func (af *Appfile) assembleWorkload(comp *unstructured.Unstructured, compName string, labels map[string]string) {
// use component name as workload name if workload name is not specified
// don't override the name set in render phase if exist
if len(wl.GetName()) == 0 {
wl.SetName(compName)
if len(comp.GetName()) == 0 {
comp.SetName(compName)
}
af.setNamespace(wl)
af.setWorkloadLabels(wl, labels)
af.filterAndSetAnnotations(wl)
af.setNamespace(comp)
af.setWorkloadLabels(comp, labels)
af.filterAndSetAnnotations(comp)
}
/*
@@ -416,10 +417,10 @@ func (af *Appfile) assembleWorkload(wl *unstructured.Unstructured, compName stri
// Component Revision name was not added here (app.oam.dev/revision: mycomp-v2)
*/
func (af *Appfile) setWorkloadLabels(wl *unstructured.Unstructured, commonLabels map[string]string) {
func (af *Appfile) setWorkloadLabels(comp *unstructured.Unstructured, commonLabels map[string]string) {
// add more workload-specific labels here
util.AddLabels(wl, map[string]string{oam.LabelOAMResourceType: oam.ResourceTypeWorkload})
util.AddLabels(wl, commonLabels)
util.AddLabels(comp, map[string]string{oam.LabelOAMResourceType: oam.ResourceTypeWorkload})
util.AddLabels(comp, commonLabels)
}
func (af *Appfile) assembleTrait(trait *unstructured.Unstructured, compName string, labels map[string]string) {
@@ -491,14 +492,14 @@ func IsNotFoundInAppFile(err error) bool {
}
// PrepareProcessContext prepares a DSL process Context
func PrepareProcessContext(wl *Workload, ctxData velaprocess.ContextData) (process.Context, error) {
if wl.Ctx == nil {
wl.Ctx = NewBasicContext(ctxData, wl.Params)
func PrepareProcessContext(comp *Component, ctxData velaprocess.ContextData) (process.Context, error) {
if comp.Ctx == nil {
comp.Ctx = NewBasicContext(ctxData, comp.Params)
}
if err := wl.EvalContext(wl.Ctx); err != nil {
if err := comp.EvalContext(comp.Ctx); err != nil {
return nil, errors.Wrapf(err, "evaluate base template app=%s in namespace=%s", ctxData.AppName, ctxData.Namespace)
}
return wl.Ctx, nil
return comp.Ctx, nil
}
// NewBasicContext prepares a basic DSL process Context
@@ -510,27 +511,27 @@ func NewBasicContext(contextData velaprocess.ContextData, params map[string]inte
return pCtx
}
func generateComponentFromCUEModule(wl *Workload, ctxData velaprocess.ContextData) (*types.ComponentManifest, error) {
pCtx, err := PrepareProcessContext(wl, ctxData)
func generateComponentFromCUEModule(comp *Component, ctxData velaprocess.ContextData) (*types.ComponentManifest, error) {
pCtx, err := PrepareProcessContext(comp, ctxData)
if err != nil {
return nil, err
}
return baseGenerateComponent(pCtx, wl, ctxData.AppName, ctxData.Namespace)
return baseGenerateComponent(pCtx, comp, ctxData.AppName, ctxData.Namespace)
}
func generateComponentFromTerraformModule(wl *Workload, appName, ns string) (*types.ComponentManifest, error) {
return baseGenerateComponent(wl.Ctx, wl, appName, ns)
func generateComponentFromTerraformModule(comp *Component, appName, ns string) (*types.ComponentManifest, error) {
return baseGenerateComponent(comp.Ctx, comp, appName, ns)
}
func baseGenerateComponent(pCtx process.Context, wl *Workload, appName, ns string) (*types.ComponentManifest, error) {
func baseGenerateComponent(pCtx process.Context, comp *Component, appName, ns string) (*types.ComponentManifest, error) {
var err error
pCtx.PushData(velaprocess.ContextComponentType, wl.Type)
for _, tr := range wl.Traits {
pCtx.PushData(velaprocess.ContextComponentType, comp.Type)
for _, tr := range comp.Traits {
if err := tr.EvalContext(pCtx); err != nil {
return nil, errors.Wrapf(err, "evaluate template trait=%s app=%s", tr.Name, wl.Name)
return nil, errors.Wrapf(err, "evaluate template trait=%s app=%s", tr.Name, comp.Name)
}
}
if patcher := wl.Patch; patcher != nil {
if patcher := comp.Patch; patcher != nil {
workload, auxiliaries := pCtx.Output()
if p, err := patcher.LookupValue("workload"); err == nil {
if err := workload.Unify(p.CueValue()); err != nil {
@@ -545,43 +546,43 @@ func baseGenerateComponent(pCtx process.Context, wl *Workload, appName, ns strin
}
}
}
compManifest, err := evalWorkloadWithContext(pCtx, wl, ns, appName)
compManifest, err := evalWorkloadWithContext(pCtx, comp, ns, appName)
if err != nil {
return nil, err
}
compManifest.Name = wl.Name
compManifest.Name = comp.Name
compManifest.Namespace = ns
return compManifest, nil
}
// makeWorkloadWithContext evaluate the workload's template to unstructured resource.
func makeWorkloadWithContext(pCtx process.Context, wl *Workload, ns, appName string) (*unstructured.Unstructured, error) {
func makeWorkloadWithContext(pCtx process.Context, comp *Component, ns, appName string) (*unstructured.Unstructured, error) {
var (
workload *unstructured.Unstructured
err error
)
base, _ := pCtx.Output()
switch wl.CapabilityCategory {
switch comp.CapabilityCategory {
case types.TerraformCategory:
workload, err = generateTerraformConfigurationWorkload(wl, ns)
workload, err = generateTerraformConfigurationWorkload(comp, ns)
if err != nil {
return nil, errors.Wrapf(err, "failed to generate Terraform Configuration workload for workload %s", wl.Name)
return nil, errors.Wrapf(err, "failed to generate Terraform Configuration workload for workload %s", comp.Name)
}
default:
workload, err = base.Unstructured()
if err != nil {
return nil, errors.Wrapf(err, "evaluate base template component=%s app=%s", wl.Name, appName)
return nil, errors.Wrapf(err, "evaluate base template component=%s app=%s", comp.Name, appName)
}
}
commonLabels := definition.GetCommonLabels(definition.GetBaseContextLabels(pCtx))
util.AddLabels(workload, util.MergeMapOverrideWithDst(commonLabels, map[string]string{oam.WorkloadTypeLabel: wl.Type}))
util.AddLabels(workload, util.MergeMapOverrideWithDst(commonLabels, map[string]string{oam.WorkloadTypeLabel: comp.Type}))
return workload, nil
}
// evalWorkloadWithContext evaluate the workload's template to generate component manifest
func evalWorkloadWithContext(pCtx process.Context, wl *Workload, ns, appName string) (*types.ComponentManifest, error) {
func evalWorkloadWithContext(pCtx process.Context, comp *Component, ns, appName string) (*types.ComponentManifest, error) {
compManifest := &types.ComponentManifest{}
workload, err := makeWorkloadWithContext(pCtx, wl, ns, appName)
workload, err := makeWorkloadWithContext(pCtx, comp, ns, appName)
if err != nil {
return nil, err
}
@@ -593,7 +594,7 @@ func evalWorkloadWithContext(pCtx process.Context, wl *Workload, ns, appName str
for i, assist := range assists {
tr, err := assist.Ins.Unstructured()
if err != nil {
return nil, errors.Wrapf(err, "evaluate trait=%s template for component=%s app=%s", assist.Name, wl.Name, appName)
return nil, errors.Wrapf(err, "evaluate trait=%s template for component=%s app=%s", assist.Name, comp.Name, appName)
}
labels := util.MergeMapOverrideWithDst(commonLabels, map[string]string{oam.TraitTypeLabel: assist.Type})
if assist.Name != "" {
@@ -605,26 +606,26 @@ func evalWorkloadWithContext(pCtx process.Context, wl *Workload, ns, appName str
return compManifest, nil
}
func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructured.Unstructured, error) {
if wl.FullTemplate == nil || wl.FullTemplate.Terraform == nil || wl.FullTemplate.Terraform.Configuration == "" {
func generateTerraformConfigurationWorkload(comp *Component, ns string) (*unstructured.Unstructured, error) {
if comp.FullTemplate == nil || comp.FullTemplate.Terraform == nil || comp.FullTemplate.Terraform.Configuration == "" {
return nil, errors.New(errTerraformConfigurationIsNotSet)
}
params, err := json.Marshal(wl.Params)
params, err := json.Marshal(comp.Params)
if err != nil {
return nil, errors.Wrap(err, errFailToConvertTerraformComponentProperties)
}
if wl.FullTemplate.ComponentDefinition == nil || wl.FullTemplate.ComponentDefinition.Spec.Schematic == nil ||
wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform == nil {
if comp.FullTemplate.ComponentDefinition == nil || comp.FullTemplate.ComponentDefinition.Spec.Schematic == nil ||
comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform == nil {
return nil, errors.New(errTerraformComponentDefinition)
}
configuration := terraformapi.Configuration{
TypeMeta: metav1.TypeMeta{APIVersion: "terraform.core.oam.dev/v1beta2", Kind: "Configuration"},
ObjectMeta: metav1.ObjectMeta{
Name: wl.Name,
Name: comp.Name,
Namespace: ns,
Annotations: wl.FullTemplate.ComponentDefinition.Annotations,
Annotations: comp.FullTemplate.ComponentDefinition.Annotations,
},
}
// 1. parse the spec of configuration
@@ -635,26 +636,26 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
configuration.Spec = spec
if configuration.Spec.WriteConnectionSecretToReference == nil {
configuration.Spec.WriteConnectionSecretToReference = wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.WriteConnectionSecretToReference
configuration.Spec.WriteConnectionSecretToReference = comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.WriteConnectionSecretToReference
}
if configuration.Spec.WriteConnectionSecretToReference != nil && configuration.Spec.WriteConnectionSecretToReference.Namespace == "" {
configuration.Spec.WriteConnectionSecretToReference.Namespace = ns
}
if configuration.Spec.ProviderReference == nil {
configuration.Spec.ProviderReference = wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.ProviderReference
configuration.Spec.ProviderReference = comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.ProviderReference
}
if configuration.Spec.GitCredentialsSecretReference == nil {
configuration.Spec.GitCredentialsSecretReference = wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.GitCredentialsSecretReference
configuration.Spec.GitCredentialsSecretReference = comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.GitCredentialsSecretReference
}
switch wl.FullTemplate.Terraform.Type {
switch comp.FullTemplate.Terraform.Type {
case "hcl":
configuration.Spec.HCL = wl.FullTemplate.Terraform.Configuration
configuration.Spec.HCL = comp.FullTemplate.Terraform.Configuration
case "remote":
configuration.Spec.Remote = wl.FullTemplate.Terraform.Configuration
configuration.Spec.Path = wl.FullTemplate.Terraform.Path
configuration.Spec.Remote = comp.FullTemplate.Terraform.Configuration
configuration.Spec.Path = comp.FullTemplate.Terraform.Path
}
// 2. parse variable

View File

@@ -135,7 +135,7 @@ variable "password" {
`
)
wl := &Workload{
wl := &Component{
Name: "sample-db",
FullTemplate: &Template{
Terraform: &common.Terraform{
@@ -161,10 +161,10 @@ variable "password" {
}
af := &Appfile{
Workloads: []*Workload{wl},
Name: appName,
AppRevisionName: revision,
Namespace: ns,
ParsedComponents: []*Component{wl},
Name: appName,
AppRevisionName: revision,
Namespace: ns,
}
variable := map[string]interface{}{"account_name": "oamtest"}
@@ -319,13 +319,13 @@ var _ = Describe("Test evalWorkloadWithContext", func() {
err error
)
type appArgs struct {
wl *Workload
wl *Component
appName string
revision string
}
args := appArgs{
wl: &Workload{
wl: &Component{
Name: compName,
FullTemplate: &Template{
Terraform: &common.Terraform{
@@ -595,7 +595,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
}
}
wl := &Workload{
wl := &Component{
FullTemplate: template,
Name: name,
Params: tc.args.params,
@@ -730,7 +730,7 @@ if context.componentType == "stateless" {
publishVersion: context.publishVersion
}`,
}
wl := &Workload{Type: "stateful", Traits: []*Trait{tr}}
wl := &Component{Type: "stateful", Traits: []*Trait{tr}}
cm, err := baseGenerateComponent(pContext, wl, appName, ns)
assert.NoError(t, err)
assert.Equal(t, cm.Traits[0].Object["kind"], "StatefulSet")
@@ -751,7 +751,7 @@ var _ = Describe("Test use context.appLabels& context.appAnnotations in componen
"ak1": "av1",
"ak2": "av2",
},
Workloads: []*Workload{
ParsedComponents: []*Component{
{
Name: "comp1",
Type: "deployment",

View File

@@ -24,6 +24,7 @@ import (
"github.com/aryann/difflib"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
@@ -40,7 +41,7 @@ import (
)
// NewLiveDiffOption creates a live-diff option
func NewLiveDiffOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []oam.Object) *LiveDiffOption {
func NewLiveDiffOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []*unstructured.Unstructured) *LiveDiffOption {
parser := appfile.NewApplicationParser(c, pd)
return &LiveDiffOption{DryRun: NewDryRunOption(c, cfg, pd, as, false), Parser: parser}
}
@@ -136,7 +137,7 @@ func (l *LiveDiffOption) RenderlessDiff(ctx context.Context, base, comparor Live
m := &manifest{Name: app.Name, Kind: AppKind, Data: string(bs)}
if appfileError != nil {
m.Data += "Error: " + appfileError.Error() + "\n"
return m, nil //nolint
return m, nil // nolint
}
for _, policy := range af.ExternalPolicies {
if bs, err = marshalObject(policy); err == nil {

View File

@@ -56,7 +56,7 @@ type DryRun interface {
}
// NewDryRunOption creates a dry-run option
func NewDryRunOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []oam.Object, serverSideDryRun bool) *Option {
func NewDryRunOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []*unstructured.Unstructured, serverSideDryRun bool) *Option {
parser := appfile.NewDryRunApplicationParser(c, pd, as)
return &Option{c, pd, parser, parser.GenerateAppFileFromApp, cfg, as, serverSideDryRun}
}
@@ -74,7 +74,7 @@ type Option struct {
// Auxiliaries are capability definitions used to parse application.
// DryRun will use capabilities in Auxiliaries as higher priority than
// getting one from cluster.
Auxiliaries []oam.Object
Auxiliaries []*unstructured.Unstructured
// serverSideDryRun If set to true, means will dry run via the apiserver.
serverSideDryRun bool

View File

@@ -25,6 +25,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
@@ -46,7 +47,6 @@ import (
coreoam "github.com/oam-dev/kubevela/apis/core.oam.dev"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/oam"
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
)
@@ -113,7 +113,7 @@ var _ = BeforeSuite(func() {
wfsd.SetNamespace(types.DefaultKubeVelaNS)
Expect(k8sClient.Create(context.TODO(), &wfsd)).Should(BeNil())
dryrunOpt = NewDryRunOption(k8sClient, cfg, pd, []oam.Object{cdMyWorker, tdMyIngress}, false)
dryrunOpt = NewDryRunOption(k8sClient, cfg, pd, []*unstructured.Unstructured{cdMyWorker, tdMyIngress}, false)
diffOpt = &LiveDiffOption{DryRun: dryrunOpt, Parser: appfile.NewApplicationParser(k8sClient, pd)}
})

View File

@@ -77,7 +77,7 @@ func NewApplicationParser(cli client.Client, pd *packages.PackageDiscover) *Pars
}
// NewDryRunApplicationParser create an appfile parser for DryRun
func NewDryRunApplicationParser(cli client.Client, pd *packages.PackageDiscover, defs []oam.Object) *Parser {
func NewDryRunApplicationParser(cli client.Client, pd *packages.PackageDiscover, defs []*unstructured.Unstructured) *Parser {
return &Parser{
client: cli,
pd: pd,
@@ -105,8 +105,6 @@ func (p *Parser) GenerateAppFile(ctx context.Context, app *v1beta1.Application)
// GenerateAppFileFromApp converts an application to an Appfile
func (p *Parser) GenerateAppFileFromApp(ctx context.Context, app *v1beta1.Application) (*Appfile, error) {
ns := app.Namespace
appName := app.Name
for idx := range app.Spec.Policies {
if app.Spec.Policies[idx].Name == "" {
@@ -114,62 +112,32 @@ func (p *Parser) GenerateAppFileFromApp(ctx context.Context, app *v1beta1.Applic
}
}
appfile := p.newAppFile(appName, ns, app)
appFile := newAppFile(app)
if app.Status.LatestRevision != nil {
appfile.AppRevisionName = app.Status.LatestRevision.Name
appFile.AppRevisionName = app.Status.LatestRevision.Name
}
var wds []*Workload
for _, comp := range app.Spec.Components {
wd, err := p.parseWorkload(ctx, comp)
if err != nil {
return nil, err
}
wds = append(wds, wd)
}
appfile.Workloads = wds
appfile.Components = app.Spec.Components
var err error
if err = p.parseWorkflowSteps(ctx, appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseWorkflowSteps")
if err = p.parseComponents(ctx, appFile); err != nil {
return nil, errors.Wrap(err, "failed to parseComponents")
}
if err = p.parsePolicies(ctx, appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parsePolicies")
if err = p.parseWorkflowSteps(ctx, appFile); err != nil {
return nil, errors.Wrap(err, "failed to parseWorkflowSteps")
}
if err = p.parseReferredObjects(ctx, appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseReferredObjects")
if err = p.parsePolicies(ctx, appFile); err != nil {
return nil, errors.Wrap(err, "failed to parsePolicies")
}
if err = p.parseReferredObjects(ctx, appFile); err != nil {
return nil, errors.Wrap(err, "failed to parseReferredObjects")
}
for _, w := range wds {
if w == nil {
continue
}
if w.FullTemplate.ComponentDefinition != nil {
cd := w.FullTemplate.ComponentDefinition.DeepCopy()
cd.Status = v1beta1.ComponentDefinitionStatus{}
appfile.RelatedComponentDefinitions[w.FullTemplate.ComponentDefinition.Name] = cd
}
for _, t := range w.Traits {
if t == nil {
continue
}
if t.FullTemplate.TraitDefinition != nil {
td := t.FullTemplate.TraitDefinition.DeepCopy()
td.Status = v1beta1.TraitDefinitionStatus{}
appfile.RelatedTraitDefinitions[t.FullTemplate.TraitDefinition.Name] = td
}
}
}
return appfile, nil
return appFile, nil
}
func (p *Parser) newAppFile(appName, ns string, app *v1beta1.Application) *Appfile {
func newAppFile(app *v1beta1.Application) *Appfile {
file := &Appfile{
Name: appName,
Namespace: ns,
Name: app.Name,
Namespace: app.Namespace,
AppLabels: make(map[string]string),
AppAnnotations: make(map[string]string),
@@ -179,8 +147,7 @@ func (p *Parser) newAppFile(appName, ns string, app *v1beta1.Application) *Appfi
ExternalPolicies: make(map[string]*v1alpha1.Policy),
parser: p,
app: app,
app: app,
}
for k, v := range app.Annotations {
file.AppAnnotations[k] = v
@@ -246,10 +213,8 @@ func (p *Parser) GenerateAppFileFromRevision(appRev *v1beta1.ApplicationRevision
inheritLabelAndAnnotationFromAppRev(appRev)
app := appRev.Spec.Application.DeepCopy()
ns := app.Namespace
appName := app.Name
appfile := p.newAppFile(appName, ns, app)
ctx := context.Background()
appfile := newAppFile(appRev.Spec.Application.DeepCopy())
appfile.AppRevision = appRev
appfile.AppRevisionName = appRev.Name
appfile.AppRevisionHash = appRev.Labels[oam.LabelAppRevisionHash]
@@ -259,62 +224,52 @@ func (p *Parser) GenerateAppFileFromRevision(appRev *v1beta1.ApplicationRevision
}
appfile.ExternalWorkflow = appRev.Spec.Workflow
var wds []*Workload
for _, comp := range app.Spec.Components {
wd, err := p.ParseWorkloadFromRevision(comp, appRev)
if err != nil {
return nil, err
}
wds = append(wds, wd)
if err := p.parseComponentsFromRevision(appfile); err != nil {
return nil, errors.Wrap(err, "failed to parseComponentsFromRevision")
}
appfile.Workloads = wds
appfile.Components = app.Spec.Components
if err := p.parseWorkflowStepsFromRevision(context.Background(), appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseWorkflowStepsFromRevision")
if err := p.parseWorkflowStepsFromRevision(ctx, appfile); err != nil {
return nil, errors.Wrap(err, "failed to parseWorkflowStepsFromRevision")
}
if err := p.parsePoliciesFromRevision(context.Background(), appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parsePolicies")
if err := p.parsePoliciesFromRevision(ctx, appfile); err != nil {
return nil, errors.Wrap(err, "failed to parsePolicies")
}
if err := p.parseReferredObjectsFromRevision(appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseReferredObjects")
}
for k, v := range appRev.Spec.ComponentDefinitions {
appfile.RelatedComponentDefinitions[k] = v.DeepCopy()
}
for k, v := range appRev.Spec.TraitDefinitions {
appfile.RelatedTraitDefinitions[k] = v.DeepCopy()
}
for k, v := range appRev.Spec.WorkflowStepDefinitions {
appfile.RelatedWorkflowStepDefinitions[k] = v.DeepCopy()
return nil, errors.Wrap(err, "failed to parseReferredObjects")
}
// add compatible code for upgrading to v1.3 as the workflow steps were not recorded before v1.2
if len(appfile.RelatedWorkflowStepDefinitions) == 0 && len(appfile.WorkflowSteps) > 0 {
ctx := context.Background()
for _, workflowStep := range appfile.WorkflowSteps {
if step.IsBuiltinWorkflowStepType(workflowStep.Type) {
continue
}
if _, found := appfile.RelatedWorkflowStepDefinitions[workflowStep.Type]; found {
continue
}
def := &v1beta1.WorkflowStepDefinition{}
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type); err != nil {
return nil, errors.Wrapf(err, "failed to get workflow step definition %s", workflowStep.Type)
}
appfile.RelatedWorkflowStepDefinitions[workflowStep.Type] = def
}
appRev.Spec.WorkflowStepDefinitions = make(map[string]*v1beta1.WorkflowStepDefinition)
for name, def := range appfile.RelatedWorkflowStepDefinitions {
appRev.Spec.WorkflowStepDefinitions[name] = def
if err := p.parseWorkflowStepsForLegacyRevision(ctx, appfile); err != nil {
return nil, errors.Wrap(err, "failed to parseWorkflowStepsForLegacyRevision")
}
}
return appfile, nil
}
// parseWorkflowStepsForLegacyRevision compatible for upgrading to v1.3 as the workflow steps were not recorded before v1.2
func (p *Parser) parseWorkflowStepsForLegacyRevision(ctx context.Context, af *Appfile) error {
for _, workflowStep := range af.WorkflowSteps {
if step.IsBuiltinWorkflowStepType(workflowStep.Type) {
continue
}
if _, found := af.RelatedWorkflowStepDefinitions[workflowStep.Type]; found {
continue
}
def := &v1beta1.WorkflowStepDefinition{}
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type); err != nil {
return errors.Wrapf(err, "failed to get workflow step definition %s", workflowStep.Type)
}
af.RelatedWorkflowStepDefinitions[workflowStep.Type] = def
}
af.AppRevision.Spec.WorkflowStepDefinitions = make(map[string]*v1beta1.WorkflowStepDefinition)
for name, def := range af.RelatedWorkflowStepDefinitions {
af.AppRevision.Spec.WorkflowStepDefinitions[name] = def
}
return nil
}
func (p *Parser) parseReferredObjectsFromRevision(af *Appfile) error {
af.ReferredObjects = []*unstructured.Unstructured{}
for _, obj := range af.AppRevision.Spec.ReferredObjects {
@@ -389,11 +344,11 @@ func (p *Parser) parsePoliciesFromRevision(ctx context.Context, af *Appfile) (er
case v1alpha1.DebugPolicyType:
af.Debug = true
default:
w, err := p.makeWorkloadFromRevision(policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.AppRevision)
w, err := p.makeComponentFromRevision(policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.AppRevision)
if err != nil {
return err
}
af.PolicyWorkloads = append(af.PolicyWorkloads, w)
af.ParsedPolicies = append(af.ParsedPolicies, w)
}
}
return nil
@@ -432,11 +387,11 @@ func (p *Parser) parsePolicies(ctx context.Context, af *Appfile) (err error) {
af.RelatedTraitDefinitions[def.Name] = def
}
default:
w, err := p.makeWorkload(ctx, policy.Name, policy.Type, types.TypePolicy, policy.Properties)
w, err := p.makeComponent(ctx, policy.Name, policy.Type, types.TypePolicy, policy.Properties)
if err != nil {
return err
}
af.PolicyWorkloads = append(af.PolicyWorkloads, w)
af.ParsedPolicies = append(af.ParsedPolicies, w)
}
}
return nil
@@ -480,7 +435,14 @@ func (p *Parser) loadWorkflowToAppfile(ctx context.Context, af *Appfile) error {
}
func (p *Parser) parseWorkflowStepsFromRevision(ctx context.Context, af *Appfile) error {
return p.loadWorkflowToAppfile(ctx, af)
if err := p.loadWorkflowToAppfile(ctx, af); err != nil {
return err
}
// Definitions are already in AppRevision
for k, v := range af.AppRevision.Spec.WorkflowStepDefinitions {
af.RelatedWorkflowStepDefinitions[k] = v.DeepCopy()
}
return nil
}
func (p *Parser) parseWorkflowSteps(ctx context.Context, af *Appfile) error {
@@ -488,14 +450,14 @@ func (p *Parser) parseWorkflowSteps(ctx context.Context, af *Appfile) error {
return err
}
for _, workflowStep := range af.WorkflowSteps {
err := p.parseWorkflowStep(ctx, af, workflowStep.Type)
err := p.fetchAndSetWorkflowStepDefinition(ctx, af, workflowStep.Type)
if err != nil {
return err
}
if workflowStep.SubSteps != nil {
for _, workflowSubStep := range workflowStep.SubSteps {
err := p.parseWorkflowStep(ctx, af, workflowSubStep.Type)
err := p.fetchAndSetWorkflowStepDefinition(ctx, af, workflowSubStep.Type)
if err != nil {
return err
}
@@ -505,7 +467,7 @@ func (p *Parser) parseWorkflowSteps(ctx context.Context, af *Appfile) error {
return nil
}
func (p *Parser) parseWorkflowStep(ctx context.Context, af *Appfile, workflowStepType string) error {
func (p *Parser) fetchAndSetWorkflowStepDefinition(ctx context.Context, af *Appfile, workflowStepType string) error {
if step.IsBuiltinWorkflowStepType(workflowStepType) {
return nil
}
@@ -520,36 +482,36 @@ func (p *Parser) parseWorkflowStep(ctx context.Context, af *Appfile, workflowSte
return nil
}
func (p *Parser) makeWorkload(ctx context.Context, name, typ string, capType types.CapType, props *runtime.RawExtension) (*Workload, error) {
func (p *Parser) makeComponent(ctx context.Context, name, typ string, capType types.CapType, props *runtime.RawExtension) (*Component, error) {
templ, err := p.tmplLoader.LoadTemplate(ctx, p.client, typ, capType)
if err != nil {
return nil, errors.WithMessagef(err, "fetch component/policy type of %s", name)
}
return p.convertTemplate2Workload(name, typ, props, templ)
return p.convertTemplate2Component(name, typ, props, templ)
}
func (p *Parser) makeWorkloadFromRevision(name, typ string, capType types.CapType, props *runtime.RawExtension, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
func (p *Parser) makeComponentFromRevision(name, typ string, capType types.CapType, props *runtime.RawExtension, appRev *v1beta1.ApplicationRevision) (*Component, error) {
templ, err := LoadTemplateFromRevision(typ, capType, appRev, p.client.RESTMapper())
if err != nil {
return nil, errors.WithMessagef(err, "fetch component/policy type of %s from revision", name)
}
return p.convertTemplate2Workload(name, typ, props, templ)
return p.convertTemplate2Component(name, typ, props, templ)
}
func (p *Parser) convertTemplate2Workload(name, typ string, props *runtime.RawExtension, templ *Template) (*Workload, error) {
func (p *Parser) convertTemplate2Component(name, typ string, props *runtime.RawExtension, templ *Template) (*Component, error) {
settings, err := util.RawExtension2Map(props)
if err != nil {
return nil, errors.WithMessagef(err, "fail to parse settings for %s", name)
}
wlType, err := util.ConvertDefinitionRevName(typ)
cpType, err := util.ConvertDefinitionRevName(typ)
if err != nil {
wlType = typ
cpType = typ
}
return &Workload{
return &Component{
Traits: []*Trait{},
Name: name,
Type: wlType,
Type: cpType,
CapabilityCategory: templ.CapabilityCategory,
FullTemplate: templ,
Params: settings,
@@ -557,10 +519,61 @@ func (p *Parser) convertTemplate2Workload(name, typ string, props *runtime.RawEx
}, nil
}
// parseWorkload resolve an ApplicationComponent and generate a Workload
// parseComponents resolve an Application Components and Traits to generate Component
func (p *Parser) parseComponents(ctx context.Context, af *Appfile) error {
var comps []*Component
for _, c := range af.app.Spec.Components {
comp, err := p.parseComponent(ctx, c)
if err != nil {
return err
}
comps = append(comps, comp)
}
af.ParsedComponents = comps
af.Components = af.app.Spec.Components
setComponentDefinitions(af, comps)
return nil
}
func setComponentDefinitions(af *Appfile, comps []*Component) {
for _, comp := range comps {
if comp == nil {
continue
}
if comp.FullTemplate.ComponentDefinition != nil {
cd := comp.FullTemplate.ComponentDefinition.DeepCopy()
cd.Status = v1beta1.ComponentDefinitionStatus{}
af.RelatedComponentDefinitions[comp.FullTemplate.ComponentDefinition.Name] = cd
}
for _, t := range comp.Traits {
if t == nil {
continue
}
if t.FullTemplate.TraitDefinition != nil {
td := t.FullTemplate.TraitDefinition.DeepCopy()
td.Status = v1beta1.TraitDefinitionStatus{}
af.RelatedTraitDefinitions[t.FullTemplate.TraitDefinition.Name] = td
}
}
}
}
// setComponentDefinitionsFromRevision can set related definitions directly from app revision
func setComponentDefinitionsFromRevision(af *Appfile) {
for k, v := range af.AppRevision.Spec.ComponentDefinitions {
af.RelatedComponentDefinitions[k] = v.DeepCopy()
}
for k, v := range af.AppRevision.Spec.TraitDefinitions {
af.RelatedTraitDefinitions[k] = v.DeepCopy()
}
}
// parseComponent resolve an ApplicationComponent and generate a Component
// containing ALL information required by an Appfile.
func (p *Parser) parseWorkload(ctx context.Context, comp common.ApplicationComponent) (*Workload, error) {
workload, err := p.makeWorkload(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
func (p *Parser) parseComponent(ctx context.Context, comp common.ApplicationComponent) (*Component, error) {
workload, err := p.makeComponent(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
if err != nil {
return nil, err
}
@@ -571,7 +584,7 @@ func (p *Parser) parseWorkload(ctx context.Context, comp common.ApplicationCompo
return workload, nil
}
func (p *Parser) parseTraits(ctx context.Context, workload *Workload, comp common.ApplicationComponent) error {
func (p *Parser) parseTraits(ctx context.Context, workload *Component, comp common.ApplicationComponent) error {
for _, traitValue := range comp.Traits {
properties, err := util.RawExtension2Map(traitValue.Properties)
if err != nil {
@@ -587,10 +600,26 @@ func (p *Parser) parseTraits(ctx context.Context, workload *Workload, comp commo
return nil
}
// ParseWorkloadFromRevision resolve an ApplicationComponent and generate a Workload
func (p *Parser) parseComponentsFromRevision(af *Appfile) error {
var comps []*Component
for _, c := range af.app.Spec.Components {
comp, err := p.ParseComponentFromRevision(c, af.AppRevision)
if err != nil {
return err
}
comps = append(comps, comp)
}
af.ParsedComponents = comps
af.Components = af.app.Spec.Components
// Definitions are already in AppRevision
setComponentDefinitionsFromRevision(af)
return nil
}
// ParseComponentFromRevision resolve an ApplicationComponent and generate a Component
// containing ALL information required by an Appfile from app revision.
func (p *Parser) ParseWorkloadFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
workload, err := p.makeWorkloadFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
func (p *Parser) ParseComponentFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Component, error) {
workload, err := p.makeComponentFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
if err != nil {
return nil, err
}
@@ -602,7 +631,7 @@ func (p *Parser) ParseWorkloadFromRevision(comp common.ApplicationComponent, app
return workload, nil
}
func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision, workload *Workload) error {
func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision, workload *Component) error {
for _, traitValue := range comp.Traits {
properties, err := util.RawExtension2Map(traitValue.Properties)
if err != nil {
@@ -618,35 +647,35 @@ func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRe
return nil
}
// ParseWorkloadFromRevisionAndClient resolve an ApplicationComponent and generate a Workload
// ParseComponentFromRevisionAndClient resolve an ApplicationComponent and generate a Component
// containing ALL information required by an Appfile from app revision, and will fall back to
// load external definitions if not found
func (p *Parser) ParseWorkloadFromRevisionAndClient(ctx context.Context, comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
workload, err := p.makeWorkloadFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
func (p *Parser) ParseComponentFromRevisionAndClient(ctx context.Context, c common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Component, error) {
comp, err := p.makeComponentFromRevision(c.Name, c.Type, types.TypeComponentDefinition, c.Properties, appRev)
if IsNotFoundInAppRevision(err) {
workload, err = p.makeWorkload(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
comp, err = p.makeComponent(ctx, c.Name, c.Type, types.TypeComponentDefinition, c.Properties)
}
if err != nil {
return nil, err
}
for _, traitValue := range comp.Traits {
for _, traitValue := range c.Traits {
properties, err := util.RawExtension2Map(traitValue.Properties)
if err != nil {
return nil, errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
return nil, errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, c.Name)
}
trait, err := p.parseTraitFromRevision(traitValue.Type, properties, appRev)
if IsNotFoundInAppRevision(err) {
trait, err = p.parseTrait(ctx, traitValue.Type, properties)
}
if err != nil {
return nil, errors.WithMessagef(err, "component(%s) parse trait(%s)", comp.Name, traitValue.Type)
return nil, errors.WithMessagef(err, "component(%s) parse trait(%s)", c.Name, traitValue.Type)
}
workload.Traits = append(workload.Traits, trait)
comp.Traits = append(comp.Traits, trait)
}
return workload, nil
return comp, nil
}
func (p *Parser) parseTrait(ctx context.Context, name string, properties map[string]interface{}) (*Trait, error) {
@@ -685,7 +714,7 @@ func (p *Parser) convertTemplate2Trait(name string, properties map[string]interf
}, nil
}
// ValidateComponentNames validate all component names whether repeat in cluster and template
// ValidateComponentNames validate all component names whether repeat in app
func (p *Parser) ValidateComponentNames(app *v1beta1.Application) (int, error) {
compNames := map[string]struct{}{}
for idx, comp := range app.Spec.Components {

View File

@@ -46,7 +46,7 @@ import (
var expectedExceptApp = &Appfile{
Name: "application-sample",
Workloads: []*Workload{
ParsedComponents: []*Component{
{
Name: "myweb",
Type: "worker",
@@ -286,11 +286,11 @@ var _ = Describe("Test application parser", func() {
})
func equal(af, dest *Appfile) bool {
if af.Name != dest.Name || len(af.Workloads) != len(dest.Workloads) {
if af.Name != dest.Name || len(af.ParsedComponents) != len(dest.ParsedComponents) {
return false
}
for i, wd := range af.Workloads {
destWd := dest.Workloads[i]
for i, wd := range af.ParsedComponents {
destWd := dest.ParsedComponents[i]
if wd.Name != destWd.Name || len(wd.Traits) != len(destWd.Traits) {
return false
}
@@ -327,7 +327,7 @@ var _ = Describe("Test application parser", func() {
// prepare verify data
expectedExceptAppfile = &Appfile{
Name: "backport-1-2-test-demo",
Workloads: []*Workload{
ParsedComponents: []*Component{
{
Name: "backport-1-2-test-demo",
Type: "webservice",
@@ -502,14 +502,17 @@ patch: spec: replicas: parameter.replicas
_, err := NewApplicationParser(&mockClient, pd).GenerateAppFile(context.TODO(), &app)
Expect(err).Should(HaveOccurred())
Expect(err.Error() == "failed to get workflow step definition apply-application-unknown: not found").Should(BeTrue())
Expect(err.Error()).Should(SatisfyAll(
ContainSubstring("failed to get workflow step definition apply-application-unknown: not found"),
ContainSubstring("failed to parseWorkflowStepsForLegacyRevision")),
)
})
})
})
func TestParser_parseTraits(t *testing.T) {
type args struct {
workload *Workload
workload *Component
comp common.ApplicationComponent
}
tests := []struct {
@@ -517,7 +520,7 @@ func TestParser_parseTraits(t *testing.T) {
args args
wantErr assert.ErrorAssertionFunc
mockTemplateLoaderFn TemplateLoaderFn
validateFunc func(w *Workload) bool
validateFunc func(w *Component) bool
}{
{
name: "test empty traits",
@@ -574,7 +577,7 @@ func TestParser_parseTraits(t *testing.T) {
},
},
},
workload: &Workload{},
workload: &Component{},
},
wantErr: assert.NoError,
mockTemplateLoaderFn: func(ctx context.Context, reader client.Client, s string, capType types.CapType) (*Template, error) {
@@ -585,7 +588,7 @@ func TestParser_parseTraits(t *testing.T) {
CustomStatus: "healthy",
}, nil
},
validateFunc: func(w *Workload) bool {
validateFunc: func(w *Component) bool {
return w != nil && len(w.Traits) != 0 && w.Traits[0].Name == "expose" && w.Traits[0].Template == "template"
},
},
@@ -608,12 +611,12 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
type args struct {
comp common.ApplicationComponent
appRev *v1beta1.ApplicationRevision
workload *Workload
workload *Component
}
tests := []struct {
name string
args args
validateFunc func(w *Workload) bool
validateFunc func(w *Component) bool
wantErr assert.ErrorAssertionFunc
}{
{
@@ -634,7 +637,7 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
},
},
},
workload: &Workload{},
workload: &Component{},
},
wantErr: assert.Error,
},
@@ -656,7 +659,7 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
},
},
},
workload: &Workload{},
workload: &Component{},
},
wantErr: assert.Error,
},
@@ -685,10 +688,10 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
},
},
},
workload: &Workload{},
workload: &Component{},
},
wantErr: assert.NoError,
validateFunc: func(w *Workload) bool {
validateFunc: func(w *Component) bool {
return w != nil && len(w.Traits) == 1 && w.Traits[0].Name == "expose"
},
},

View File

@@ -34,7 +34,6 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/oam"
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
)
@@ -252,35 +251,33 @@ func verifyRevisionName(capName string, capType types.CapType, apprev *v1beta1.A
// DryRunTemplateLoader return a function that do the same work as
// LoadTemplate, but load template from provided ones before loading from
// cluster through LoadTemplate
func DryRunTemplateLoader(defs []oam.Object) TemplateLoaderFn {
func DryRunTemplateLoader(defs []*unstructured.Unstructured) TemplateLoaderFn {
return func(ctx context.Context, r client.Client, capName string, capType types.CapType) (*Template, error) {
// retrieve provided cap definitions
for _, def := range defs {
if unstructDef, ok := def.(*unstructured.Unstructured); ok {
if unstructDef.GetKind() == v1beta1.ComponentDefinitionKind &&
capType == types.TypeComponentDefinition && unstructDef.GetName() == capName {
compDef := &v1beta1.ComponentDefinition{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructDef.Object, compDef); err != nil {
return nil, errors.Wrap(err, "invalid component definition")
}
tmpl, err := newTemplateOfCompDefinition(compDef)
if err != nil {
return nil, errors.WithMessagef(err, "cannot load template of component definition %q", capName)
}
return tmpl, nil
if def.GetKind() == v1beta1.ComponentDefinitionKind &&
capType == types.TypeComponentDefinition && def.GetName() == capName {
compDef := &v1beta1.ComponentDefinition{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(def.Object, compDef); err != nil {
return nil, errors.Wrap(err, "invalid component definition")
}
if unstructDef.GetKind() == v1beta1.TraitDefinitionKind &&
capType == types.TypeTrait && unstructDef.GetName() == capName {
traitDef := &v1beta1.TraitDefinition{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructDef.Object, traitDef); err != nil {
return nil, errors.Wrap(err, "invalid trait definition")
}
tmpl, err := newTemplateOfTraitDefinition(traitDef)
if err != nil {
return nil, errors.WithMessagef(err, "cannot load template of trait definition %q", capName)
}
return tmpl, nil
tmpl, err := newTemplateOfCompDefinition(compDef)
if err != nil {
return nil, errors.WithMessagef(err, "cannot load template of component definition %q", capName)
}
return tmpl, nil
}
if def.GetKind() == v1beta1.TraitDefinitionKind &&
capType == types.TypeTrait && def.GetName() == capName {
traitDef := &v1beta1.TraitDefinition{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(def.Object, traitDef); err != nil {
return nil, errors.Wrap(err, "invalid trait definition")
}
tmpl, err := newTemplateOfTraitDefinition(traitDef)
if err != nil {
return nil, errors.WithMessagef(err, "cannot load template of trait definition %q", capName)
}
return tmpl, nil
}
}
// not found in provided cap definitions

View File

@@ -24,6 +24,7 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/test"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
ktypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -31,7 +32,6 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/oam"
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
)
@@ -362,7 +362,7 @@ spec:
TraitDefinition: traitDef,
}
dryRunLoadTemplate := DryRunTemplateLoader([]oam.Object{unstrctCompDef, unstrctTraitDef})
dryRunLoadTemplate := DryRunTemplateLoader([]*unstructured.Unstructured{unstrctCompDef, unstrctTraitDef})
compTmpl, err := dryRunLoadTemplate(nil, nil, "myworker", types.TypeComponentDefinition)
if err != nil {
t.Error("failed load template of component defintion", err)

View File

@@ -38,7 +38,7 @@ func TestIsNotFoundInAppRevision(t *testing.T) {
require.True(t, IsNotFoundInAppRevision(fmt.Errorf("ComponentDefinition XXX not found in app revision")))
}
func TestParseWorkloadFromRevisionAndClient(t *testing.T) {
func TestParseComponentFromRevisionAndClient(t *testing.T) {
ctx := context.Background()
cli := fake.NewClientBuilder().WithScheme(scheme).Build()
p := &Parser{
@@ -63,21 +63,21 @@ func TestParseWorkloadFromRevisionAndClient(t *testing.T) {
require.NoError(t, cli.Create(ctx, cd))
require.NoError(t, cli.Create(ctx, td))
appRev.Spec.TraitDefinitions = map[string]*v1beta1.TraitDefinition{"internal": {}}
_, err := p.ParseWorkloadFromRevisionAndClient(ctx, comp, appRev)
_, err := p.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
require.NoError(t, err)
_comp1 := comp.DeepCopy()
_comp1.Type = "bad"
_, err = p.ParseWorkloadFromRevisionAndClient(ctx, *_comp1, appRev)
_, err = p.ParseComponentFromRevisionAndClient(ctx, *_comp1, appRev)
require.Error(t, err)
_comp2 := comp.DeepCopy()
_comp2.Traits[0].Type = "bad"
_, err = p.ParseWorkloadFromRevisionAndClient(ctx, *_comp2, appRev)
_, err = p.ParseComponentFromRevisionAndClient(ctx, *_comp2, appRev)
require.Error(t, err)
_comp3 := comp.DeepCopy()
_comp3.Traits[0].Properties = &runtime.RawExtension{Raw: []byte(`bad`)}
_, err = p.ParseWorkloadFromRevisionAndClient(ctx, *_comp3, appRev)
_, err = p.ParseComponentFromRevisionAndClient(ctx, *_comp3, appRev)
require.Error(t, err)
}

View File

@@ -30,7 +30,7 @@ import (
// ValidateCUESchematicAppfile validates CUE schematic workloads in an Appfile
func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
for _, wl := range a.Workloads {
for _, wl := range a.ParsedComponents {
// because helm & kube schematic has no CUE template
// it only validates CUE schematic workload
if wl.CapabilityCategory != types.CUECategory || wl.Type == v1alpha1.RefObjectsComponentType {
@@ -53,7 +53,7 @@ func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
return nil
}
func newValidationProcessContext(wl *Workload, ctxData velaprocess.ContextData) (process.Context, error) {
func newValidationProcessContext(c *Component, ctxData velaprocess.ContextData) (process.Context, error) {
baseHooks := []process.BaseHook{
// add more hook funcs here to validate CUE base
}
@@ -65,7 +65,7 @@ func newValidationProcessContext(wl *Workload, ctxData velaprocess.ContextData)
ctxData.BaseHooks = baseHooks
ctxData.AuxiliaryHooks = auxiliaryHooks
pCtx := velaprocess.NewContext(ctxData)
if err := wl.EvalContext(pCtx); err != nil {
if err := c.EvalContext(pCtx); err != nil {
return nil, errors.Wrapf(err, "evaluate base template app=%s in namespace=%s", ctxData.AppName, ctxData.Namespace)
}
return pCtx, nil

View File

@@ -34,7 +34,7 @@ var _ = Describe("Test validate CUE schematic Appfile", func() {
DescribeTable("Test validate outputs name unique", func(tc SubTestCase) {
Expect("").Should(BeEmpty())
wl := &Workload{
wl := &Component{
Name: "myweb",
Type: "worker",
CapabilityCategory: types.CUECategory,

View File

@@ -46,9 +46,6 @@ type Args struct {
// AutoGenWorkloadDefinition indicates whether automatic generated workloadDefinition which componentDefinition refers to
AutoGenWorkloadDefinition bool
// EnableCompatibility indicates that will change some functions of controller to adapt to multiple platforms, such as asi.
EnableCompatibility bool
// IgnoreAppWithoutControllerRequirement indicates that application controller will not process the app without 'app.oam.dev/controller-version-require' annotation.
IgnoreAppWithoutControllerRequirement bool
@@ -66,7 +63,6 @@ func (a *Args) AddFlags(fs *pflag.FlagSet, c *Args) {
"definition-revision-limit is the maximum number of component/trait definition useless revisions that will be maintained, if the useless revisions exceed this number, older ones will be GCed first.The default value is 20.")
fs.BoolVar(&a.AutoGenWorkloadDefinition, "autogen-workload-definition", c.AutoGenWorkloadDefinition, "Automatic generated workloadDefinition which componentDefinition refers to.")
fs.IntVar(&a.ConcurrentReconciles, "concurrent-reconciles", c.ConcurrentReconciles, "concurrent-reconciles is the concurrent reconcile number of the controller. The default value is 4")
fs.BoolVar(&a.EnableCompatibility, "enable-asi-compatibility", c.EnableCompatibility, "enable compatibility for asi")
fs.BoolVar(&a.IgnoreAppWithoutControllerRequirement, "ignore-app-without-controller-version", c.IgnoreAppWithoutControllerRequirement, "If true, application controller will not process the app without 'app.oam.dev/controller-version-require' annotation")
fs.BoolVar(&a.IgnoreDefinitionWithoutControllerRequirement, "ignore-definition-without-controller-version", c.IgnoreDefinitionWithoutControllerRequirement, "If true, trait/component/workflowstep definition controller will not process the definition without 'definition.oam.dev/controller-version-require' annotation")
}

View File

@@ -95,7 +95,6 @@ type Reconciler struct {
type options struct {
appRevisionLimit int
concurrentReconciles int
disableStatusUpdate bool
ignoreAppNoCtrlReq bool
controllerVersion string
}
@@ -141,7 +140,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
logCtx.AddTag("publish_version", app.GetAnnotations()[oam.AnnotationPublishVersion])
appParser := appfile.NewApplicationParser(r.Client, r.pd)
handler, err := NewAppHandler(logCtx, r, app, appParser)
handler, err := NewAppHandler(logCtx, r, app)
if err != nil {
return r.endWithNegativeCondition(logCtx, app, condition.ReconcileError(err), common.ApplicationStarting)
}
@@ -179,14 +178,14 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
app.Status.SetConditions(condition.ReadyCondition("Revision"))
r.Recorder.Event(app, event.Normal(velatypes.ReasonRevisoned, velatypes.MessageRevisioned))
if err := handler.UpdateAppLatestRevisionStatus(logCtx); err != nil {
if err := handler.UpdateAppLatestRevisionStatus(logCtx, r.patchStatus); err != nil {
logCtx.Error(err, "Failed to update application status")
return r.endWithNegativeCondition(logCtx, app, condition.ReconcileError(err), common.ApplicationRendering)
}
logCtx.Info("Successfully apply application revision")
if err := handler.ApplyPolicies(logCtx, appFile); err != nil {
logCtx.Error(err, "[Handle ApplyPolicies]")
logCtx.Error(err, "[handle ApplyPolicies]")
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedApply, err))
return r.endWithNegativeCondition(logCtx, app, condition.ErrorCondition(common.PolicyCondition.String(), errors.WithMessage(err, "ApplyPolices")), common.ApplicationPolicyGenerating)
}
@@ -258,7 +257,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
}
var phase = common.ApplicationRunning
if !hasHealthCheckPolicy(appFile.PolicyWorkloads) {
if !hasHealthCheckPolicy(appFile.ParsedPolicies) {
app.Status.Services = handler.services
if !isHealthy(handler.services) {
phase = common.ApplicationUnhealthy
@@ -440,23 +439,26 @@ func (r *Reconciler) endWithNegativeCondition(ctx context.Context, app *v1beta1.
return r.result(fmt.Errorf("object level reconcile error, type: %q, msg: %q", string(condition.Type), condition.Message)).ret()
}
// Application status can be updated by two methods: patch and update.
type method int
const (
patch = iota
update
)
type statusPatcher func(ctx context.Context, app *v1beta1.Application, phase common.ApplicationPhase) error
func (r *Reconciler) patchStatus(ctx context.Context, app *v1beta1.Application, phase common.ApplicationPhase) error {
app.Status.Phase = phase
updateObservedGeneration(app)
if oldApp, ok := originalAppFrom(ctx); ok && oldApp != nil && equality.Semantic.DeepEqual(oldApp.Status, app.Status) {
return nil
}
ctx, cancel := ctrlrec.NewReconcileTerminationContext(ctx)
defer cancel()
if err := r.Status().Patch(ctx, app, client.Merge); err != nil {
// set to -1 to re-run workflow if status is failed to patch
executor.StepStatusCache.Store(fmt.Sprintf("%s-%s", app.Name, app.Namespace), -1)
return err
}
return nil
return r.writeStatusByMethod(ctx, patch, app, phase)
}
func (r *Reconciler) updateStatus(ctx context.Context, app *v1beta1.Application, phase common.ApplicationPhase) error {
return r.writeStatusByMethod(ctx, update, app, phase)
}
func (r *Reconciler) writeStatusByMethod(ctx context.Context, method method, app *v1beta1.Application, phase common.ApplicationPhase) error {
// pre-check if the status is changed
app.Status.Phase = phase
updateObservedGeneration(app)
if oldApp, ok := originalAppFrom(ctx); ok && oldApp != nil && equality.Semantic.DeepEqual(oldApp.Status, app.Status) {
@@ -464,15 +466,17 @@ func (r *Reconciler) updateStatus(ctx context.Context, app *v1beta1.Application,
}
ctx, cancel := ctrlrec.NewReconcileTerminationContext(ctx)
defer cancel()
if !r.disableStatusUpdate {
return r.Status().Update(ctx, app)
var f func() error
switch method {
case patch:
f = func() error { return r.Status().Patch(ctx, app, client.Merge) }
case update:
f = func() error { return r.Status().Update(ctx, app) }
default:
// Should never happen
panic("unknown method")
}
obj, err := app.Unstructured()
if err != nil {
return err
}
if err := r.Status().Update(ctx, obj); err != nil {
// set to -1 to re-run workflow if status is failed to update
if err := f(); err != nil {
executor.StepStatusCache.Store(fmt.Sprintf("%s-%s", app.Name, app.Namespace), -1)
return err
}
@@ -498,7 +502,7 @@ func (r *Reconciler) doWorkflowFinish(logCtx monitorContext.Context, app *v1beta
logCtx.Info("Application manifests has applied by workflow successfully")
}
func hasHealthCheckPolicy(policies []*appfile.Workload) bool {
func hasHealthCheckPolicy(policies []*appfile.Component) bool {
for _, p := range policies {
if p.FullTemplate != nil && p.FullTemplate.PolicyDefinition != nil &&
p.FullTemplate.PolicyDefinition.Spec.ManageHealthCheck {
@@ -648,7 +652,6 @@ func timeReconcile(app *v1beta1.Application) func() {
func parseOptions(args core.Args) options {
return options{
disableStatusUpdate: args.EnableCompatibility,
appRevisionLimit: args.AppRevisionLimit,
concurrentReconciles: args.ConcurrentReconciles,
ignoreAppNoCtrlReq: args.IgnoreAppWithoutControllerRequirement,

View File

@@ -20,6 +20,7 @@ import (
"context"
"sync"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
@@ -45,7 +46,9 @@ import (
// AppHandler handles application reconcile
type AppHandler struct {
r *Reconciler
client.Client
pd *packages.PackageDiscover
app *v1beta1.Application
currentAppRev *v1beta1.ApplicationRevision
latestAppRev *v1beta1.ApplicationRevision
@@ -57,13 +60,12 @@ type AppHandler struct {
services []common.ApplicationComponentStatus
appliedResources []common.ClusterObjectReference
deletedResources []common.ClusterObjectReference
parser *appfile.Parser
mu sync.Mutex
}
// NewAppHandler create new app handler
func NewAppHandler(ctx context.Context, r *Reconciler, app *v1beta1.Application, parser *appfile.Parser) (*AppHandler, error) {
func NewAppHandler(ctx context.Context, r *Reconciler, app *v1beta1.Application) (*AppHandler, error) {
if ctx, ok := ctx.(monitorContext.Context); ok {
subCtx := ctx.Fork("create-app-handler", monitorContext.DurationMetric(func(v float64) {
metrics.AppReconcileStageDurationHistogram.WithLabelValues("create-app-handler").Observe(v)
@@ -75,10 +77,10 @@ func NewAppHandler(ctx context.Context, r *Reconciler, app *v1beta1.Application,
return nil, errors.Wrapf(err, "failed to create resourceKeeper")
}
return &AppHandler{
r: r,
Client: r.Client,
pd: r.pd,
app: app,
resourceKeeper: resourceHandler,
parser: parser,
}, nil
}
@@ -227,13 +229,13 @@ func (h *AppHandler) ProduceArtifacts(ctx context.Context, comps []*types.Compon
}
// collectTraitHealthStatus collect trait health status
func (h *AppHandler) collectTraitHealthStatus(wl *appfile.Workload, tr *appfile.Trait, appRev *v1beta1.ApplicationRevision, overrideNamespace string) (common.ApplicationTraitStatus, []*unstructured.Unstructured, error) {
func (h *AppHandler) collectTraitHealthStatus(comp *appfile.Component, tr *appfile.Trait, appRev *v1beta1.ApplicationRevision, overrideNamespace string) (common.ApplicationTraitStatus, []*unstructured.Unstructured, error) {
defer func(clusterName string) {
wl.Ctx.SetCtx(pkgmulticluster.WithCluster(wl.Ctx.GetCtx(), clusterName))
}(multicluster.ClusterNameInContext(wl.Ctx.GetCtx()))
comp.Ctx.SetCtx(pkgmulticluster.WithCluster(comp.Ctx.GetCtx(), clusterName))
}(multicluster.ClusterNameInContext(comp.Ctx.GetCtx()))
var (
pCtx = wl.Ctx
pCtx = comp.Ctx
appName = appRev.Spec.Application.Name
traitStatus = common.ApplicationTraitStatus{
Type: tr.Name,
@@ -247,57 +249,57 @@ func (h *AppHandler) collectTraitHealthStatus(wl *appfile.Workload, tr *appfile.
pCtx.SetCtx(pkgmulticluster.WithCluster(pCtx.GetCtx(), pkgmulticluster.Local))
}
_accessor := util.NewApplicationResourceNamespaceAccessor(h.app.Namespace, traitOverrideNamespace)
templateContext, err := tr.GetTemplateContext(pCtx, h.r.Client, _accessor)
templateContext, err := tr.GetTemplateContext(pCtx, h.Client, _accessor)
if err != nil {
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, get template context error", appName, wl.Name, tr.Name)
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, get template context error", appName, comp.Name, tr.Name)
}
if ok, err := tr.EvalHealth(templateContext); !ok || err != nil {
traitStatus.Healthy = false
}
traitStatus.Message, err = tr.EvalStatus(templateContext)
if err != nil {
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, evaluate status message error", appName, wl.Name, tr.Name)
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, evaluate status message error", appName, comp.Name, tr.Name)
}
return traitStatus, extractOutputs(templateContext), nil
}
// collectWorkloadHealthStatus collect workload health status
func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, status *common.ApplicationComponentStatus, accessor util.NamespaceAccessor) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, status *common.ApplicationComponentStatus, accessor util.NamespaceAccessor) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
var output *unstructured.Unstructured
var outputs []*unstructured.Unstructured
var (
appName = appRev.Spec.Application.Name
isHealth = true
)
if wl.CapabilityCategory == types.TerraformCategory {
if comp.CapabilityCategory == types.TerraformCategory {
var configuration terraforv1beta2.Configuration
if err := h.r.Client.Get(ctx, client.ObjectKey{Name: wl.Name, Namespace: accessor.Namespace()}, &configuration); err != nil {
if err := h.Client.Get(ctx, client.ObjectKey{Name: comp.Name, Namespace: accessor.Namespace()}, &configuration); err != nil {
if kerrors.IsNotFound(err) {
var legacyConfiguration terraforv1beta1.Configuration
if err := h.r.Client.Get(ctx, client.ObjectKey{Name: wl.Name, Namespace: accessor.Namespace()}, &legacyConfiguration); err != nil {
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, wl.Name)
if err := h.Client.Get(ctx, client.ObjectKey{Name: comp.Name, Namespace: accessor.Namespace()}, &legacyConfiguration); err != nil {
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, comp.Name)
}
isHealth = setStatus(status, legacyConfiguration.Status.ObservedGeneration, legacyConfiguration.Generation,
legacyConfiguration.GetLabels(), appRev.Name, legacyConfiguration.Status.Apply.State, legacyConfiguration.Status.Apply.Message)
} else {
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, wl.Name)
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, comp.Name)
}
} else {
isHealth = setStatus(status, configuration.Status.ObservedGeneration, configuration.Generation, configuration.GetLabels(),
appRev.Name, configuration.Status.Apply.State, configuration.Status.Apply.Message)
}
} else {
templateContext, err := wl.GetTemplateContext(wl.Ctx, h.r.Client, accessor)
templateContext, err := comp.GetTemplateContext(comp.Ctx, h.Client, accessor)
if err != nil {
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, get template context error", appName, wl.Name)
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, get template context error", appName, comp.Name)
}
if ok, err := wl.EvalHealth(templateContext); !ok || err != nil {
if ok, err := comp.EvalHealth(templateContext); !ok || err != nil {
isHealth = false
}
status.Healthy = isHealth
status.Message, err = wl.EvalStatus(templateContext)
status.Message, err = comp.EvalStatus(templateContext)
if err != nil {
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, evaluate workload status message error", appName, wl.Name)
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, evaluate workload status message error", appName, comp.Name)
}
output, outputs = extractOutputAndOutputs(templateContext)
}
@@ -306,14 +308,14 @@ func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, wl *appfil
// nolint
// collectHealthStatus will collect health status of component, including component itself and traits.
func (h *AppHandler) collectHealthStatus(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, overrideNamespace string, skipWorkload bool, traitFilters ...TraitFilter) (*common.ApplicationComponentStatus, *unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
func (h *AppHandler) collectHealthStatus(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, overrideNamespace string, skipWorkload bool, traitFilters ...TraitFilter) (*common.ApplicationComponentStatus, *unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
output := new(unstructured.Unstructured)
outputs := make([]*unstructured.Unstructured, 0)
accessor := util.NewApplicationResourceNamespaceAccessor(h.app.Namespace, overrideNamespace)
var (
status = common.ApplicationComponentStatus{
Name: wl.Name,
WorkloadDefinition: wl.FullTemplate.Reference.Definition,
Name: comp.Name,
WorkloadDefinition: comp.FullTemplate.Reference.Definition,
Healthy: true,
Namespace: accessor.Namespace(),
Cluster: multicluster.ClusterNameInContext(ctx),
@@ -324,7 +326,7 @@ func (h *AppHandler) collectHealthStatus(ctx context.Context, wl *appfile.Worklo
status = h.getServiceStatus(status)
if !skipWorkload {
isHealth, output, outputs, err = h.collectWorkloadHealthStatus(ctx, wl, appRev, &status, accessor)
isHealth, output, outputs, err = h.collectWorkloadHealthStatus(ctx, comp, appRev, &status, accessor)
if err != nil {
return nil, nil, nil, false, err
}
@@ -332,7 +334,7 @@ func (h *AppHandler) collectHealthStatus(ctx context.Context, wl *appfile.Worklo
var traitStatusList []common.ApplicationTraitStatus
collectNext:
for _, tr := range wl.Traits {
for _, tr := range comp.Traits {
for _, filter := range traitFilters {
// If filtered out by one of the filters
if filter(*tr) {
@@ -340,7 +342,7 @@ collectNext:
}
}
traitStatus, _outputs, err := h.collectTraitHealthStatus(wl, tr, appRev, overrideNamespace)
traitStatus, _outputs, err := h.collectTraitHealthStatus(comp, tr, appRev, overrideNamespace)
if err != nil {
return nil, nil, nil, false, err
}
@@ -389,6 +391,7 @@ func setStatus(status *common.ApplicationComponentStatus, observedGeneration, ge
}
// ApplyPolicies will render policies into manifests from appfile and dispatch them
// Note the builtin policy like apply-once, shared-resource, etc. is not handled here.
func (h *AppHandler) ApplyPolicies(ctx context.Context, af *appfile.Appfile) error {
if ctx, ok := ctx.(monitorContext.Context); ok {
subCtx := ctx.Fork("apply-policies", monitorContext.DurationMetric(func(v float64) {

View File

@@ -224,7 +224,7 @@ var _ = Describe("Test deleter resource", func() {
},
},
}
h, err := NewAppHandler(ctx, reconciler, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "default"}}, nil)
h, err := NewAppHandler(ctx, reconciler, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "default"}})
Expect(err).Should(Succeed())
h.appliedResources = appliedRsc
Expect(h.Delete(ctx, "", common.WorkflowResourceCreator, &u))

View File

@@ -18,47 +18,15 @@ package assemble
import (
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/klog/v2"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
)
// NewAppManifests create a AppManifests
func NewAppManifests(appRevision *v1beta1.ApplicationRevision, parser *appfile.Parser) *AppManifests {
return &AppManifests{AppRevision: appRevision, parser: parser}
}
// AppManifests contains configuration to assemble resources recorded in the ApplicationRevision.
// 'Assemble' means expand Application(Component and Trait) into K8s resource and get them ready to go, to be emitted
// into K8s
type AppManifests struct {
AppRevision *v1beta1.ApplicationRevision
WorkloadOptions []WorkloadOption
componentManifests []*types.ComponentManifest
appName string
appNamespace string
appLabels map[string]string
appAnnotations map[string]string
appOwnerRef *metav1.OwnerReference
assembledWorkloads map[string]*unstructured.Unstructured
assembledTraits map[string][]*unstructured.Unstructured
// key is workload reference, values are the references of scopes the workload belongs to
skipWorkloadApplyComp map[string]bool
finalized bool
err error
parser *appfile.Parser
}
// WorkloadOption will be applied to each workloads AFTER it has been assembled by generic rules shown below:
// 1) use component name as workload name
// 2) use application namespace as workload namespace if unspecified
@@ -75,78 +43,6 @@ type WorkloadOption interface {
ApplyToWorkload(*unstructured.Unstructured, *v1beta1.ComponentDefinition, []*unstructured.Unstructured) error
}
// WithWorkloadOption add a WorkloadOption to plug in custom logic applied to each workload
func (am *AppManifests) WithWorkloadOption(wo WorkloadOption) *AppManifests {
if am.WorkloadOptions == nil {
am.WorkloadOptions = make([]WorkloadOption, 0)
}
am.WorkloadOptions = append(am.WorkloadOptions, wo)
return am
}
// WithComponentManifests set component manifests with the given one
func (am *AppManifests) WithComponentManifests(componentManifests []*types.ComponentManifest) *AppManifests {
am.componentManifests = componentManifests
return am
}
// AssembledManifests do assemble and merge all assembled resources(except referenced scopes) into one array
// The result guarantee the order of resources as defined in application originally.
// If it contains more than one component, the resources are well-orderred and also grouped.
// For example, if app = comp1 (wl1 + trait1 + trait2) + comp2 (wl2 + trait3 +trait4),
// the result is [wl1, trait1, trait2, wl2, trait3, trait4]
func (am *AppManifests) AssembledManifests() ([]*unstructured.Unstructured, error) {
if !am.finalized {
am.assemble()
}
if am.err != nil {
return nil, am.err
}
r := make([]*unstructured.Unstructured, 0)
for compName, wl := range am.assembledWorkloads {
skipApplyWorkload := false
ts := am.assembledTraits[compName]
for _, t := range ts {
r = append(r, t.DeepCopy())
if v := t.GetLabels()[oam.LabelManageWorkloadTrait]; v == "true" {
skipApplyWorkload = true
}
}
if !skipApplyWorkload {
r = append(r, wl.DeepCopy())
} else {
klog.InfoS("assemble meet a managedByTrait workload, so skip apply it",
"namespace", am.AppRevision.Namespace, "appRev", am.AppRevision.Name)
}
}
return r, nil
}
// GroupAssembledManifests do assemble and return all resources grouped by components
func (am *AppManifests) GroupAssembledManifests() (
map[string]*unstructured.Unstructured,
map[string][]*unstructured.Unstructured,
error) {
if !am.finalized {
am.assemble()
}
if am.err != nil {
return nil, nil, am.err
}
workloads := make(map[string]*unstructured.Unstructured)
for k, wl := range am.assembledWorkloads {
workloads[k] = wl.DeepCopy()
}
traits := make(map[string][]*unstructured.Unstructured)
for k, ts := range am.assembledTraits {
traits[k] = make([]*unstructured.Unstructured, len(ts))
for i, t := range ts {
traits[k][i] = t.DeepCopy()
}
}
return workloads, traits, nil
}
// checkAutoDetectComponent will check if the standardWorkload is empty,
// currently only Helm-based component is possible to be auto-detected
// TODO implement auto-detect mechanism
@@ -154,35 +50,6 @@ func checkAutoDetectComponent(wl *unstructured.Unstructured) bool {
return wl == nil || (len(wl.GetAPIVersion()) == 0 && len(wl.GetKind()) == 0)
}
func (am *AppManifests) assemble() {
if err := am.complete(); err != nil {
am.finalizeAssemble(err)
return
}
klog.InfoS("Assemble manifests for application", "name", am.appName, "revision", am.AppRevision.GetName())
if err := am.validate(); err != nil {
am.finalizeAssemble(err)
return
}
for _, comp := range am.componentManifests {
klog.InfoS("Assemble manifests for component", "name", comp.Name)
wl, traits, err := PrepareBeforeApply(comp, am.AppRevision, am.WorkloadOptions)
if err != nil {
am.finalizeAssemble(err)
return
}
if wl == nil {
klog.Warningf("component without specify workloadDef can not attach traits currently")
continue
}
am.assembledWorkloads[comp.Name] = wl
am.assembledTraits[comp.Name] = traits
}
am.finalizeAssemble(nil)
}
// PrepareBeforeApply will prepare for some necessary info before apply
func PrepareBeforeApply(comp *types.ComponentManifest, appRev *v1beta1.ApplicationRevision, workloadOpt []WorkloadOption) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
if checkAutoDetectComponent(comp.StandardWorkload) {
@@ -211,55 +78,6 @@ func PrepareBeforeApply(comp *types.ComponentManifest, appRev *v1beta1.Applicati
return wl, assembledTraits, nil
}
func (am *AppManifests) complete() error {
if len(am.componentManifests) == 0 {
var err error
af, err := am.parser.GenerateAppFileFromRevision(am.AppRevision)
if err != nil {
return errors.WithMessage(err, "fail to generate appfile from revision for app manifests complete")
}
am.componentManifests, err = af.GenerateComponentManifests()
if err != nil {
return errors.WithMessage(err, "fail to complete manifests as generate from app revision failed")
}
}
am.appNamespace = am.AppRevision.GetNamespace()
am.appLabels = am.AppRevision.GetLabels()
am.appName = am.AppRevision.GetLabels()[oam.LabelAppName]
am.appAnnotations = am.AppRevision.GetAnnotations()
am.appOwnerRef = metav1.GetControllerOf(am.AppRevision)
am.assembledWorkloads = make(map[string]*unstructured.Unstructured)
am.assembledTraits = make(map[string][]*unstructured.Unstructured)
am.skipWorkloadApplyComp = make(map[string]bool)
return nil
}
func (am *AppManifests) finalizeAssemble(err error) {
am.finalized = true
if err == nil {
klog.InfoS("Successfully assemble manifests for application", "name", am.appName, "revision", am.AppRevision.GetName(), "namespace", am.appNamespace)
return
}
klog.ErrorS(err, "Failed assembling manifests for application", "name", am.appName, "revision", am.AppRevision.GetName())
am.err = errors.WithMessagef(err, "cannot assemble resources' manifests for application %q", am.appName)
}
// AssembleOptions is highly coulped with AppRevision, should check the AppRevision provides all info
// required by AssembleOptions
func (am *AppManifests) validate() error {
if am.appOwnerRef == nil {
return errors.New("AppRevision must have an Application as owner")
}
if len(am.AppRevision.Labels[oam.LabelAppName]) == 0 {
return errors.New("AppRevision must have app name in the label")
}
if len(am.AppRevision.Labels[oam.LabelAppRevisionHash]) == 0 {
return errors.New("AppRevision must have revision hash in the label")
}
return nil
}
func assembleWorkload(compName string, wl *unstructured.Unstructured,
labels map[string]string, resources []*unstructured.Unstructured, appRev *v1beta1.ApplicationRevision, wop []WorkloadOption) (*unstructured.Unstructured, error) {
// use component name as workload name if workload name is not specified

View File

@@ -15,99 +15,3 @@ limitations under the License.
*/
package assemble
import (
"os"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/oam"
)
var _ = Describe("Test Assemble Options", func() {
It("test assemble", func() {
var (
compName = "test-comp"
namespace = "default"
)
appRev := &v1beta1.ApplicationRevision{}
b, err := os.ReadFile("./testdata/apprevision.yaml")
/* appRevision test data is generated based on below application
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: test-assemble
spec:
components:
- name: test-comp
type: webservice
properties:
image: crccheck/hello-world
port: 8000
traits:
- type: ingress
properties:
domain: localhost
http:
"/": 8000
*/
Expect(err).Should(BeNil())
err = yaml.Unmarshal(b, appRev)
Expect(err).Should(BeNil())
ao := NewAppManifests(appRev, appParser)
workloads, traits, err := ao.GroupAssembledManifests()
Expect(err).Should(BeNil())
By("Verify amount of result resources")
allResources, err := ao.AssembledManifests()
Expect(err).Should(BeNil())
Expect(len(allResources)).Should(Equal(3))
By("Verify amount of result grouped resources")
Expect(len(workloads)).Should(Equal(1))
Expect(len(traits[compName])).Should(Equal(2))
By("Verify workload metadata (name, namespace, labels, annotations, ownerRef)")
wl := workloads[compName]
Expect(wl.GetName()).Should(Equal(compName))
Expect(wl.GetNamespace()).Should(Equal(namespace))
labels := wl.GetLabels()
labelKeys := make([]string, 0, len(labels))
for k := range labels {
labelKeys = append(labelKeys, k)
}
Expect(labelKeys).Should(ContainElements(
oam.LabelAppName,
oam.LabelAppRevision,
oam.LabelAppRevisionHash,
oam.LabelAppComponent,
oam.LabelAppComponentRevision,
oam.WorkloadTypeLabel,
oam.LabelOAMResourceType))
Expect(len(wl.GetAnnotations())).Should(Equal(1))
By("Verify trait metadata (name, namespace, labels, annotations, ownerRef)")
trait := traits[compName][0]
Expect(trait.GetName()).Should(ContainSubstring(compName))
Expect(trait.GetNamespace()).Should(Equal(namespace))
labels = trait.GetLabels()
labelKeys = make([]string, 0, len(labels))
for k := range labels {
labelKeys = append(labelKeys, k)
}
Expect(labelKeys).Should(ContainElements(
oam.LabelAppName,
oam.LabelAppRevision,
oam.LabelAppRevisionHash,
oam.LabelAppComponent,
oam.LabelAppComponentRevision,
oam.TraitTypeLabel,
oam.LabelOAMResourceType))
Expect(len(wl.GetAnnotations())).Should(Equal(1))
})
})

View File

@@ -108,8 +108,8 @@ func ByTraitType(readyTraits, checkTraits []*unstructured.Unstructured) TraitFil
// manifestDispatcher is a manifest dispatcher
type manifestDispatcher struct {
run func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error)
healthCheck func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision) (bool, error)
run func(ctx context.Context, c *appfile.Component, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error)
healthCheck func(ctx context.Context, c *appfile.Component, appRev *v1beta1.ApplicationRevision) (bool, error)
}
func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, readyWorkload *unstructured.Unstructured, readyTraits []*unstructured.Unstructured, overrideNamespace string) ([]*manifestDispatcher, error) {
@@ -124,25 +124,25 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
}
dispatcher := new(manifestDispatcher)
dispatcher.healthCheck = func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision) (bool, error) {
skipWorkload, manifests := assembleManifestFn(wl.SkipApplyWorkload)
dispatcher.healthCheck = func(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision) (bool, error) {
skipWorkload, manifests := assembleManifestFn(comp.SkipApplyWorkload)
if !h.resourceKeeper.ContainsResources(manifests) {
return false, nil
}
_, _, _, isHealth, err := h.collectHealthStatus(ctx, wl, appRev, options.OverrideNamespace, skipWorkload,
_, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, appRev, options.OverrideNamespace, skipWorkload,
ByTraitType(readyTraits, options.Traits))
if err != nil {
return false, err
}
return isHealth, nil
}
dispatcher.run = func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error) {
skipWorkload, dispatchManifests := assembleManifestFn(wl.SkipApplyWorkload)
if isHealth, err := dispatcher.healthCheck(ctx, wl, appRev); !isHealth || err != nil {
dispatcher.run = func(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error) {
skipWorkload, dispatchManifests := assembleManifestFn(comp.SkipApplyWorkload)
if isHealth, err := dispatcher.healthCheck(ctx, comp, appRev); !isHealth || err != nil {
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, dispatchManifests...); err != nil {
return false, errors.WithMessage(err, "Dispatch")
}
status, _, _, isHealth, err := h.collectHealthStatus(ctx, wl, appRev, options.OverrideNamespace, skipWorkload,
status, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, appRev, options.OverrideNamespace, skipWorkload,
ByTraitType(readyTraits, options.Traits))
if err != nil {
return false, errors.WithMessage(err, "CollectHealthStatus")
@@ -179,7 +179,7 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
traitType = splitName
}
}
stageType, err = getTraitDispatchStage(h.r.Client, traitType, appRev)
stageType, err = getTraitDispatchStage(h.Client, traitType, appRev)
if err != nil {
return nil, err
}

View File

@@ -95,37 +95,37 @@ func (h *AppHandler) GenerateApplicationSteps(ctx monitorContext.Context,
oam.LabelAppNamespace: app.Namespace,
}
handlerProviders := providers.NewProviders()
kube.Install(handlerProviders, h.r.Client, appLabels, &kube.Handlers{
kube.Install(handlerProviders, h.Client, appLabels, &kube.Handlers{
Apply: h.Dispatch,
Delete: h.Delete,
})
configprovider.Install(handlerProviders, h.r.Client, func(ctx context.Context, resources []*unstructured.Unstructured, applyOptions []apply.ApplyOption) error {
configprovider.Install(handlerProviders, h.Client, func(ctx context.Context, resources []*unstructured.Unstructured, applyOptions []apply.ApplyOption) error {
for _, res := range resources {
res.SetLabels(util.MergeMapOverrideWithDst(res.GetLabels(), appLabels))
}
return h.resourceKeeper.Dispatch(ctx, resources, applyOptions)
})
oamProvider.Install(handlerProviders, app, af, h.r.Client, h.applyComponentFunc(
oamProvider.Install(handlerProviders, app, af, h.Client, h.applyComponentFunc(
appParser, appRev, af), h.renderComponentFunc(appParser, appRev, af))
pCtx := velaprocess.NewContext(generateContextDataFromApp(app, appRev.Name))
renderer := func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Workload, error) {
return appParser.ParseWorkloadFromRevisionAndClient(ctx, comp, appRev)
renderer := func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Component, error) {
return appParser.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
}
multiclusterProvider.Install(handlerProviders, h.r.Client, app, af,
multiclusterProvider.Install(handlerProviders, h.Client, app, af,
h.applyComponentFunc(appParser, appRev, af),
h.checkComponentHealth(appParser, appRev, af),
renderer)
terraformProvider.Install(handlerProviders, app, renderer)
query.Install(handlerProviders, h.r.Client, nil)
query.Install(handlerProviders, h.Client, nil)
instance := generateWorkflowInstance(af, app)
executor.InitializeWorkflowInstance(instance)
runners, err := generator.GenerateRunners(ctx, instance, wfTypes.StepGeneratorOptions{
Providers: handlerProviders,
PackageDiscover: h.r.pd,
PackageDiscover: h.pd,
ProcessCtx: pCtx,
TemplateLoader: template.NewWorkflowStepTemplateRevisionLoader(appRev, h.r.Client.RESTMapper()),
Client: h.r.Client,
TemplateLoader: template.NewWorkflowStepTemplateRevisionLoader(appRev, h.Client.RESTMapper()),
Client: h.Client,
StepConvertor: map[string]func(step workflowv1alpha1.WorkflowStep) (workflowv1alpha1.WorkflowStep, error){
wfTypes.WorkflowStepTypeApplyComponent: func(lstep workflowv1alpha1.WorkflowStep) (workflowv1alpha1.WorkflowStep, error) {
copierStep := lstep.DeepCopy()
@@ -319,7 +319,7 @@ func (h *AppHandler) renderComponentFunc(appParser *appfile.Parser, appRev *v1be
if err != nil {
return nil, nil, err
}
return renderComponentsAndTraits(h.r.Client, manifest, appRev, clusterName, overrideNamespace)
return renderComponentsAndTraits(h.Client, manifest, appRev, clusterName, overrideNamespace)
}
}
@@ -335,7 +335,7 @@ func (h *AppHandler) checkComponentHealth(appParser *appfile.Parser, appRev *v1b
}
wl.Ctx.SetCtx(auth.ContextWithUserInfo(ctx, h.app))
readyWorkload, readyTraits, err := renderComponentsAndTraits(h.r.Client, manifest, appRev, clusterName, overrideNamespace)
readyWorkload, readyTraits, err := renderComponentsAndTraits(h.Client, manifest, appRev, clusterName, overrideNamespace)
if err != nil {
return false, nil, nil, err
}
@@ -378,7 +378,7 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
}
wl.Ctx.SetCtx(auth.ContextWithUserInfo(ctx, h.app))
readyWorkload, readyTraits, err := renderComponentsAndTraits(h.r.Client, manifest, appRev, clusterName, overrideNamespace)
readyWorkload, readyTraits, err := renderComponentsAndTraits(h.Client, manifest, appRev, clusterName, overrideNamespace)
if err != nil {
return nil, nil, false, err
}
@@ -414,7 +414,7 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
if DisableResourceApplyDoubleCheck {
return readyWorkload, readyTraits, isHealth, nil
}
workload, traits, err := getComponentResources(auth.ContextWithUserInfo(ctx, h.app), manifest, wl.SkipApplyWorkload, h.r.Client)
workload, traits, err := getComponentResources(auth.ContextWithUserInfo(ctx, h.app), manifest, wl.SkipApplyWorkload, h.Client)
return workload, traits, isHealth, err
}
}
@@ -439,8 +439,8 @@ func (h *AppHandler) prepareWorkloadAndManifests(ctx context.Context,
comp common.ApplicationComponent,
appRev *v1beta1.ApplicationRevision,
patcher *value.Value,
af *appfile.Appfile) (*appfile.Workload, *types.ComponentManifest, error) {
wl, err := appParser.ParseWorkloadFromRevisionAndClient(ctx, comp, appRev)
af *appfile.Appfile) (*appfile.Component, *types.ComponentManifest, error) {
wl, err := appParser.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
if err != nil {
return nil, nil, errors.WithMessage(err, "ParseWorkload")
}
@@ -457,7 +457,7 @@ func (h *AppHandler) prepareWorkloadAndManifests(ctx context.Context,
ctxData.Cluster = cluster
}
// cluster info are secrets stored in the control plane cluster
ctxData.ClusterVersion = multicluster.GetVersionInfoFromObject(pkgmulticluster.WithCluster(ctx, types.ClusterLocalName), h.r.Client, ctxData.Cluster)
ctxData.ClusterVersion = multicluster.GetVersionInfoFromObject(pkgmulticluster.WithCluster(ctx, types.ClusterLocalName), h.Client, ctxData.Cluster)
ctxData.CompRevision, _ = ctrlutil.ComputeSpecHash(comp)
})
if err != nil {
@@ -490,10 +490,10 @@ func renderComponentsAndTraits(client client.Client, manifest *types.ComponentMa
return readyWorkload, readyTraits, nil
}
func checkSkipApplyWorkload(wl *appfile.Workload) {
for _, trait := range wl.Traits {
func checkSkipApplyWorkload(comp *appfile.Component) {
for _, trait := range comp.Traits {
if trait.FullTemplate.TraitDefinition.Spec.ManageWorkload {
wl.SkipApplyWorkload = true
comp.SkipApplyWorkload = true
break
}
}

View File

@@ -113,7 +113,7 @@ var _ = Describe("Test Application workflow generator", func() {
_, err = af.GeneratePolicyManifests(context.Background())
Expect(err).Should(BeNil())
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
handler, err := NewAppHandler(ctx, reconciler, app)
Expect(err).Should(Succeed())
logCtx := monitorContext.NewTraceContext(ctx, "")
@@ -157,7 +157,7 @@ var _ = Describe("Test Application workflow generator", func() {
_, err = af.GeneratePolicyManifests(context.Background())
Expect(err).Should(BeNil())
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
handler, err := NewAppHandler(ctx, reconciler, app)
Expect(err).Should(Succeed())
logCtx := monitorContext.NewTraceContext(ctx, "")
@@ -199,7 +199,7 @@ var _ = Describe("Test Application workflow generator", func() {
af, err := appParser.GenerateAppFile(ctx, app)
Expect(err).Should(BeNil())
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
handler, err := NewAppHandler(ctx, reconciler, app)
Expect(err).Should(Succeed())
logCtx := monitorContext.NewTraceContext(ctx, "")
@@ -241,7 +241,7 @@ var _ = Describe("Test Application workflow generator", func() {
af, err := appParser.GenerateAppFile(ctx, app)
Expect(err).Should(BeNil())
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
handler, err := NewAppHandler(ctx, reconciler, app)
Expect(err).Should(Succeed())
logCtx := monitorContext.NewTraceContext(ctx, "")
@@ -280,7 +280,7 @@ var _ = Describe("Test Application workflow generator", func() {
af, err := appParser.GenerateAppFile(ctx, app)
Expect(err).Should(BeNil())
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
handler, err := NewAppHandler(ctx, reconciler, app)
Expect(err).Should(Succeed())
logCtx := monitorContext.NewTraceContext(ctx, "")

View File

@@ -114,14 +114,14 @@ func (h *AppHandler) createResourcesConfigMap(ctx context.Context,
ConfigMapKeyPolicy: string(util.MustJSONMarshal(policies)),
},
}
err := h.r.Client.Get(ctx, client.ObjectKey{Name: appRev.Name, Namespace: appRev.Namespace}, &corev1.ConfigMap{})
err := h.Client.Get(ctx, client.ObjectKey{Name: appRev.Name, Namespace: appRev.Namespace}, &corev1.ConfigMap{})
if err == nil {
return nil
}
if err != nil && !apierrors.IsNotFound(err) {
return err
}
return h.r.Client.Create(ctx, cm)
return h.Client.Create(ctx, cm)
}
// SprintComponentManifest formats and returns the resulting string.
@@ -213,7 +213,7 @@ func (h *AppHandler) gatherRevisionSpec(af *appfile.Appfile) (*v1beta1.Applicati
},
},
}
for _, w := range af.Workloads {
for _, w := range af.ParsedComponents {
if w == nil {
continue
}
@@ -238,7 +238,7 @@ func (h *AppHandler) gatherRevisionSpec(af *appfile.Appfile) (*v1beta1.Applicati
}
}
}
for _, p := range af.PolicyWorkloads {
for _, p := range af.ParsedPolicies {
if p == nil || p.FullTemplate == nil {
continue
}
@@ -283,7 +283,7 @@ func (h *AppHandler) getLatestAppRevision(ctx context.Context) error {
}
latestRevName := h.app.Status.LatestRevision.Name
latestAppRev := &v1beta1.ApplicationRevision{}
if err := h.r.Get(ctx, client.ObjectKey{Name: latestRevName, Namespace: h.app.Namespace}, latestAppRev); err != nil {
if err := h.Get(ctx, client.ObjectKey{Name: latestRevName, Namespace: h.app.Namespace}, latestAppRev); err != nil {
klog.ErrorS(err, "Failed to get latest app revision", "appRevisionName", latestRevName)
return errors.Wrapf(err, "fail to get latest app revision %s", latestRevName)
}
@@ -403,7 +403,7 @@ func (h *AppHandler) currentAppRevIsNew(ctx context.Context) (bool, bool, error)
return false, false, nil
}
revs, err := GetAppRevisions(ctx, h.r.Client, h.app.Name, h.app.Namespace)
revs, err := GetAppRevisions(ctx, h.Client, h.app.Name, h.app.Namespace)
if err != nil {
klog.ErrorS(err, "Failed to list app revision", "appName", h.app.Name)
return false, false, errors.Wrap(err, "failed to list app revision")
@@ -567,9 +567,9 @@ func (h *AppHandler) FinalizeAndApplyAppRevision(ctx context.Context) error {
sharding.PropagateScheduledShardIDLabel(h.app, appRev)
gotAppRev := &v1beta1.ApplicationRevision{}
if err := h.r.Get(ctx, client.ObjectKey{Name: appRev.Name, Namespace: appRev.Namespace}, gotAppRev); err != nil {
if err := h.Get(ctx, client.ObjectKey{Name: appRev.Name, Namespace: appRev.Namespace}, gotAppRev); err != nil {
if apierrors.IsNotFound(err) {
return h.r.Create(ctx, appRev)
return h.Create(ctx, appRev)
}
return err
}
@@ -588,12 +588,12 @@ func (h *AppHandler) FinalizeAndApplyAppRevision(ctx context.Context) error {
appRev.Spec.Compression.SetType(compression.Zstd)
}
return h.r.Update(ctx, appRev)
return h.Update(ctx, appRev)
}
// UpdateAppLatestRevisionStatus only call to update app's latest revision status after applying manifests successfully
// otherwise it will override previous revision which is used during applying to do GC jobs
func (h *AppHandler) UpdateAppLatestRevisionStatus(ctx context.Context) error {
func (h *AppHandler) UpdateAppLatestRevisionStatus(ctx context.Context, patchStatus statusPatcher) error {
if DisableAllApplicationRevision {
return nil
}
@@ -614,7 +614,7 @@ func (h *AppHandler) UpdateAppLatestRevisionStatus(ctx context.Context) error {
Revision: int64(revNum),
RevisionHash: h.currentRevHash,
}
if err := h.r.patchStatus(ctx, h.app, common.ApplicationRendering); err != nil {
if err := patchStatus(ctx, h.app, common.ApplicationRendering); err != nil {
klog.InfoS("Failed to update the latest appConfig revision to status", "application", klog.KObj(h.app),
"latest revision", revName, "err", err)
return err
@@ -635,13 +635,13 @@ func (h *AppHandler) UpdateApplicationRevisionStatus(ctx context.Context, appRev
// Versioned the context backend values.
if wfStatus.ContextBackend != nil {
var cm corev1.ConfigMap
if err := h.r.Client.Get(ctx, ktypes.NamespacedName{Namespace: wfStatus.ContextBackend.Namespace, Name: wfStatus.ContextBackend.Name}, &cm); err != nil {
if err := h.Client.Get(ctx, ktypes.NamespacedName{Namespace: wfStatus.ContextBackend.Namespace, Name: wfStatus.ContextBackend.Name}, &cm); err != nil {
klog.Error(err, "[UpdateApplicationRevisionStatus] failed to load the context values", "ApplicationRevision", appRev.Name)
}
appRev.Status.WorkflowContext = cm.Data
}
if err := h.r.Client.Status().Update(ctx, appRev); err != nil {
if err := h.Client.Status().Update(ctx, appRev); err != nil {
if logCtx, ok := ctx.(monitorContext.Context); ok {
logCtx.Error(err, "[UpdateApplicationRevisionStatus] failed to update application revision status", "ApplicationRevision", appRev.Name)
} else {

View File

@@ -117,7 +117,7 @@ var _ = Describe("test generate revision ", func() {
appRevision2 = *appRevision1.DeepCopy()
appRevision2.Name = "appRevision2"
_handler, err := NewAppHandler(ctx, reconciler, &app, nil)
_handler, err := NewAppHandler(ctx, reconciler, &app)
Expect(err).Should(Succeed())
handler = _handler
})
@@ -177,7 +177,7 @@ var _ = Describe("test generate revision ", func() {
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
prevHash := generatedAppfile.AppRevisionHash
handler.app.Status.LatestRevision = &common.Revision{Name: generatedAppfile.AppRevisionName, Revision: 1, RevisionHash: generatedAppfile.AppRevisionHash}
generatedAppfile.Workloads[0].FullTemplate.ComponentDefinition = nil
generatedAppfile.ParsedComponents[0].FullTemplate.ComponentDefinition = nil
generatedAppfile.RelatedComponentDefinitions = map[string]*v1beta1.ComponentDefinition{}
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
nonChangeHash := generatedAppfile.AppRevisionHash
@@ -201,12 +201,12 @@ var _ = Describe("test generate revision ", func() {
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
curApp := &v1beta1.Application{}
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
curApp)
},
@@ -216,7 +216,7 @@ var _ = Describe("test generate revision ", func() {
curAppRevision := &v1beta1.ApplicationRevision{}
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
curAppRevision)
},
@@ -241,7 +241,7 @@ var _ = Describe("test generate revision ", func() {
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
curApp)
},
@@ -254,7 +254,7 @@ var _ = Describe("test generate revision ", func() {
curAppRevision = &v1beta1.ApplicationRevision{}
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: lastRevision},
curAppRevision)
},
@@ -278,10 +278,10 @@ var _ = Describe("test generate revision ", func() {
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
curApp)
},
@@ -295,7 +295,7 @@ var _ = Describe("test generate revision ", func() {
curAppRevision = &v1beta1.ApplicationRevision{}
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
curAppRevision)
},
@@ -322,10 +322,10 @@ var _ = Describe("test generate revision ", func() {
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
curApp)
},
@@ -339,7 +339,7 @@ var _ = Describe("test generate revision ", func() {
curAppRevision = &v1beta1.ApplicationRevision{}
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
curAppRevision)
},
@@ -366,19 +366,19 @@ var _ = Describe("test generate revision ", func() {
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
curApp := &v1beta1.Application{}
Eventually(
func() error {
return handler.r.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
return handler.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
}, time.Second*10, time.Millisecond*500).Should(BeNil())
Expect(curApp.Status.LatestRevision.Revision).Should(BeEquivalentTo(1))
By("Verify the created appRevision is exactly what it is")
curAppRevision := &v1beta1.ApplicationRevision{}
Eventually(
func() error {
return handler.r.Get(ctx,
return handler.Get(ctx,
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
curAppRevision)
},
@@ -399,7 +399,7 @@ var _ = Describe("test generate revision ", func() {
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
Eventually(
func() error {
return handler.r.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
return handler.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
}, time.Second*10, time.Millisecond*500).Should(BeNil())
// no new revision should be created
Expect(curApp.Status.LatestRevision.Name).Should(Equal(lastRevision))
@@ -409,7 +409,7 @@ var _ = Describe("test generate revision ", func() {
curAppRevision = &v1beta1.ApplicationRevision{}
Eventually(
func() error {
return handler.r.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: lastRevision}, curAppRevision)
return handler.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: lastRevision}, curAppRevision)
}, time.Second*5, time.Millisecond*500).Should(BeNil())
Expect(err).Should(Succeed())
Expect(curAppRevision.GetLabels()[oam.LabelAppRevisionHash]).Should(Equal(appHash1))
@@ -734,7 +734,7 @@ status: {}
Expect(k8sClient.Create(ctx, &apprev)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
// prepare handler
_handler, err := NewAppHandler(ctx, reconciler, &app, nil)
_handler, err := NewAppHandler(ctx, reconciler, &app)
Expect(err).Should(Succeed())
handler = _handler

View File

@@ -35,6 +35,9 @@ import (
pkgdef "github.com/oam-dev/kubevela/pkg/definition"
)
// GoProxyEnvKey with the environment variable name that defines the GOPROXY preferences.
const GoProxyEnvKey = "GOPROXY"
var (
mainModuleVersionKey langArgKey = "MainModuleVersion"
goProxyKey langArgKey = "GoProxy"
@@ -48,11 +51,13 @@ var (
goProxy = LangArg{
Name: goProxyKey,
Desc: "The proxy for go get/go mod tidy command",
Default: "https://goproxy.cn,direct",
Default: "",
}
)
func init() {
// Propagate the environment GOPROXY variable to the tests that are executed through external containers.
goProxy.Default = os.Getenv(GoProxyEnvKey)
registerLangArg("go", mainModuleVersion, goProxy)
}

View File

@@ -23,8 +23,6 @@ const (
LabelAppName = "app.oam.dev/name"
// LabelAppRevision records the name of Application, it's equal to name of AppConfig created by Application
LabelAppRevision = "app.oam.dev/appRevision"
// LabelAppDeployment records the name of AppDeployment.
LabelAppDeployment = "app.oam.dev/appDeployment"
// LabelAppComponent records the name of Component
LabelAppComponent = "app.oam.dev/component"
// LabelReplicaKey records the replica key of Component
@@ -62,11 +60,6 @@ const (
// LabelControllerRevisionComponent indicate which component the revision belong to
LabelControllerRevisionComponent = "controller.oam.dev/component"
// LabelComponentRevisionHash records the hash value of a component
LabelComponentRevisionHash = "app.oam.dev/component-revision-hash"
// LabelAddonsName records the name of initializer stored in configMap
LabelAddonsName = "addons.oam.dev/type"
// LabelAddonName indicates the name of the corresponding Addon
LabelAddonName = "addons.oam.dev/name"
@@ -142,13 +135,6 @@ const (
// its controller should not try to reconcile it
AnnotationAppRevision = "app.oam.dev/app-revision"
// AnnotationAppRevisionOnly the Application update should only generate revision,
// not any appContexts or components.
AnnotationAppRevisionOnly = "app.oam.dev/revision-only"
// AnnotationWorkflowContext is used to pass in the workflow context marshalled in json format.
AnnotationWorkflowContext = "app.oam.dev/workflow-context"
// AnnotationKubeVelaVersion is used to record current KubeVela version
AnnotationKubeVelaVersion = "oam.dev/kubevela-version"
@@ -158,15 +144,9 @@ const (
// AnnotationFilterLabelKeys is used to filter labels passed to workload and trait, split by comma
AnnotationFilterLabelKeys = "filter.oam.dev/label-keys"
// AnnotationSkipGC is used to tell application to skip gc workload/trait
AnnotationSkipGC = "app.oam.dev/skipGC"
// AnnotationDefinitionRevisionName is used to specify the name of DefinitionRevision in component/trait definition
AnnotationDefinitionRevisionName = "definitionrevision.oam.dev/name"
// AnnotationAddonsName records the name of initializer stored in configMap
AnnotationAddonsName = "addons.oam.dev/name"
// AnnotationLastAppliedConfiguration is kubectl annotations for 3-way merge
AnnotationLastAppliedConfiguration = "kubectl.kubernetes.io/last-applied-configuration"
@@ -189,12 +169,6 @@ const (
// AnnotationAppAlias specifies the alias for application in db.
AnnotationAppAlias = "app.oam.dev/appAlias"
// AnnotationWorkloadGVK indicates the managed workload's GVK by trait
AnnotationWorkloadGVK = "trait.oam.dev/workload-gvk"
// AnnotationWorkloadName indicates the managed workload's name by trait
AnnotationWorkloadName = "trait.oam.dev/workload-name"
// AnnotationControllerRequirement indicates the controller version that can process the application/definition.
AnnotationControllerRequirement = "app.oam.dev/controller-version-require"

View File

@@ -32,8 +32,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/pkg/oam"
)
// Args is args for controller-runtime client
@@ -125,7 +123,7 @@ func (a *Args) GetClient() (client.Client, error) {
}
// GetFakeClient returns a fake client with the definition objects preloaded
func (a *Args) GetFakeClient(defs []oam.Object) (client.Client, error) {
func (a *Args) GetFakeClient(defs []*unstructured.Unstructured) (client.Client, error) {
if a.client != nil {
return a.client, nil
}
@@ -136,9 +134,7 @@ func (a *Args) GetFakeClient(defs []oam.Object) (client.Client, error) {
}
objs := make([]client.Object, 0, len(defs))
for _, def := range defs {
if unstructDef, ok := def.(*unstructured.Unstructured); ok {
objs = append(objs, unstructDef)
}
objs = append(objs, def)
}
return fake.NewClientBuilder().WithObjects(objs...).WithScheme(a.Schema).Build(), nil
}

View File

@@ -53,7 +53,7 @@ type ComponentRender func(ctx context.Context, comp common.ApplicationComponent,
type ComponentHealthCheck func(ctx context.Context, comp common.ApplicationComponent, patcher *value.Value, clusterName string, overrideNamespace string) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error)
// WorkloadRenderer renderer to render application component into workload
type WorkloadRenderer func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Workload, error)
type WorkloadRenderer func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Component, error)
type provider struct {
render ComponentRender

View File

@@ -33,14 +33,14 @@ import (
"github.com/oam-dev/kubevela/pkg/appfile"
)
func fakeWorkloadRenderer(_ context.Context, comp apicommon.ApplicationComponent) (*appfile.Workload, error) {
func fakeWorkloadRenderer(_ context.Context, comp apicommon.ApplicationComponent) (*appfile.Component, error) {
if strings.HasPrefix(comp.Name, "error") {
return nil, errors.New(comp.Name)
}
if strings.HasPrefix(comp.Name, "terraform") {
return &appfile.Workload{CapabilityCategory: types.TerraformCategory}, nil
return &appfile.Component{CapabilityCategory: types.TerraformCategory}, nil
}
return &appfile.Workload{CapabilityCategory: types.CUECategory}, nil
return &appfile.Component{CapabilityCategory: types.CUECategory}, nil
}
func TestLoadTerraformComponents(t *testing.T) {

View File

@@ -174,7 +174,7 @@ func (g *DeployWorkflowStepGenerator) Generate(app *v1beta1.Application, existin
steps = append(steps, workflowv1alpha1.WorkflowStep{
WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{
Name: "deploy",
Type: "deploy",
Type: DeployWorkflowStep,
Properties: util.Object2RawExtension(map[string]interface{}{"policies": append([]string{}, overrides...)}),
},
})

View File

@@ -20,6 +20,7 @@ import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -290,3 +291,10 @@ func TestWorkflowStepGenerator(t *testing.T) {
})
}
}
func TestIsBuiltinWorkflowStepType(t *testing.T) {
assert.True(t, IsBuiltinWorkflowStepType("suspend"))
assert.True(t, IsBuiltinWorkflowStepType("apply-component"))
assert.True(t, IsBuiltinWorkflowStepType("step-group"))
assert.True(t, IsBuiltinWorkflowStepType("builtin-apply-component"))
}

View File

@@ -71,7 +71,7 @@ func ApplyTerraform(app *v1beta1.Application, k8sClient client.Client, ioStream
return nil, err
}
for i, wl := range appFile.Workloads {
for i, wl := range appFile.ParsedComponents {
switch wl.CapabilityCategory {
case types.TerraformCategory:
name := wl.Name
@@ -191,8 +191,8 @@ func generateSecretFromTerraformOutput(k8sClient client.Client, outputList []str
}
// getTerraformJSONFiles gets Terraform JSON files or modules from workload
func getTerraformJSONFiles(wl *appfile.Workload, ctxData process.ContextData) ([]byte, error) {
pCtx, err := appfile.PrepareProcessContext(wl, ctxData)
func getTerraformJSONFiles(comp *appfile.Component, ctxData process.ContextData) ([]byte, error) {
pCtx, err := appfile.PrepareProcessContext(comp, ctxData)
if err != nil {
return nil, err
}

View File

@@ -190,7 +190,7 @@ func PrintComponentListFromRegistry(registry Registry, ioStreams cmdutil.IOStrea
// InstallCompByNameFromRegistry will install given componentName comp to cluster from registry
func InstallCompByNameFromRegistry(args common2.Args, ioStream cmdutil.IOStreams, compName string, registry Registry) error {
capObj, data, err := registry.GetCap(compName)
_, data, err := registry.GetCap(compName)
if err != nil {
return err
}
@@ -200,7 +200,7 @@ func InstallCompByNameFromRegistry(args common2.Args, ioStream cmdutil.IOStreams
return err
}
err = common.InstallComponentDefinition(k8sClient, data, ioStream, &capObj)
err = common.InstallComponentDefinition(k8sClient, data, ioStream)
if err != nil {
return err
}

View File

@@ -42,7 +42,6 @@ import (
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile/dryrun"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/utils/common"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
)
@@ -119,7 +118,7 @@ func (d *debugOpts) debugApplication(ctx context.Context, wargs *WorkflowArgs, c
return d.debugWorkflow(ctx, wargs, cli, pd, ioStreams)
}
dryRunOpt := dryrun.NewDryRunOption(cli, config, pd, []oam.Object{}, false)
dryRunOpt := dryrun.NewDryRunOption(cli, config, pd, []*unstructured.Unstructured{}, false)
comps, _, err := dryRunOpt.ExecuteDryRun(ctx, app)
if err != nil {
ioStreams.Info(color.RedString("%s%s", emojiFail, err.Error()))

View File

@@ -26,17 +26,17 @@ import (
"strings"
wfv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/pkg/workflow/step"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
apicommon "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
corev1beta1 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile/dryrun"
@@ -46,6 +46,7 @@ import (
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/common"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
"github.com/oam-dev/kubevela/pkg/workflow/step"
)
// DryRunCmdOptions contains dry-run cmd options
@@ -130,7 +131,7 @@ func DryRunApplication(cmdOption *DryRunCmdOptions, c common.Args, namespace str
var err error
var buff = bytes.Buffer{}
var objs []oam.Object
var objs []*unstructured.Unstructured
if cmdOption.DefinitionFile != "" {
objs, err = ReadDefinitionsFromFile(cmdOption.DefinitionFile)
if err != nil {
@@ -142,6 +143,7 @@ func DryRunApplication(cmdOption *DryRunCmdOptions, c common.Args, namespace str
var newClient client.Client
if cmdOption.OfflineMode {
// We will load a fake client with all the objects present in the definitions file preloaded
objs = includeBuiltinWorkflowStepDefinition(objs)
newClient, err = c.GetFakeClient(objs)
} else {
// Load an actual client here
@@ -185,7 +187,7 @@ func DryRunApplication(cmdOption *DryRunCmdOptions, c common.Args, namespace str
return buff, nil
}
func readObj(path string) (oam.Object, error) {
func readObj(path string) (*unstructured.Unstructured, error) {
switch {
case strings.HasSuffix(path, ".cue"):
def := pkgdef.Definition{Unstructured: unstructured.Unstructured{}}
@@ -209,7 +211,7 @@ func readObj(path string) (oam.Object, error) {
}
// ReadDefinitionsFromFile will read objects from file or dir in the format of yaml
func ReadDefinitionsFromFile(path string) ([]oam.Object, error) {
func ReadDefinitionsFromFile(path string) ([]*unstructured.Unstructured, error) {
fi, err := os.Stat(path)
if err != nil {
return nil, err
@@ -219,10 +221,10 @@ func ReadDefinitionsFromFile(path string) ([]oam.Object, error) {
if err != nil {
return nil, err
}
return []oam.Object{obj}, nil
return []*unstructured.Unstructured{obj}, nil
}
var objs []oam.Object
var objs []*unstructured.Unstructured
//nolint:gosec
fis, err := os.ReadDir(path)
if err != nil {
@@ -401,3 +403,45 @@ func getPolicyNameFromWorkflow(wf *wfv1alpha1.Workflow, policyNameMap map[string
}
return nil
}
// includeBuiltinWorkflowStepDefinition adds builtin workflow step definition to the given objects
// A few builtin workflow steps have cue definition. They should be included when building offline fake client.
func includeBuiltinWorkflowStepDefinition(objs []*unstructured.Unstructured) []*unstructured.Unstructured {
deployUnstructured, _ := oamutil.Object2Unstructured(deployDefinition)
return append(objs, deployUnstructured)
}
// deployDefinition is the definition of deploy step
// Copied it here to make dry-run work in offline mode.
var deployDefinition = &corev1beta1.WorkflowStepDefinition{
TypeMeta: metav1.TypeMeta{
Kind: corev1beta1.WorkflowStepDefinitionKind,
APIVersion: corev1beta1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "deploy",
Namespace: oam.SystemDefinitionNamespace,
},
Spec: corev1beta1.WorkflowStepDefinitionSpec{
Schematic: &apicommon.Schematic{
CUE: &apicommon.CUE{Template: `
import (
"vela/op"
)
"deploy": {
type: "workflow-step"
annotations: {
"category": "Application Delivery"
}
labels: {
"scope": "Application"
}
description: "A powerful and unified deploy step for components multi-cluster delivery with policies."
}
// Ignore the template field for it's useless in dry-run.
template: {}`,
},
},
},
}

View File

@@ -224,10 +224,7 @@ var _ = Describe("Testing dry-run", func() {
})
It("Testing dry-run offline", func() {
c := common2.Args{}
c.SetConfig(cfg)
c.SetClient(k8sClient)
opt := DryRunCmdOptions{ApplicationFiles: []string{"test-data/dry-run/testing-dry-run-6.yaml"}, DefinitionFile: "test-data/dry-run/testing-worker-def.yaml", OfflineMode: true}
buff, err := DryRunApplication(&opt, c, "")
Expect(err).Should(BeNil())
@@ -237,6 +234,18 @@ var _ = Describe("Testing dry-run", func() {
Expect(buff.String()).Should(ContainSubstring("workload.oam.dev/type: myworker"))
})
It("Testing dry-run offline with deploy workflow step", func() {
c := common2.Args{}
opt := DryRunCmdOptions{ApplicationFiles: []string{"test-data/dry-run/testing-dry-run-7.yaml"}, DefinitionFile: "test-data/dry-run/testing-worker-def.yaml", OfflineMode: true}
buff, err := DryRunApplication(&opt, c, "")
Expect(err).Should(BeNil())
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-prod)"))
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-default)"))
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
Expect(buff.String()).Should(ContainSubstring("workload.oam.dev/type: myworker"))
})
It("Testing dry-run with default application namespace", func() {
c := common2.Args{}
c.SetConfig(cfg)

View File

@@ -24,12 +24,12 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile/dryrun"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/utils/common"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
)
@@ -101,7 +101,7 @@ func LiveDiffApplication(cmdOption *LiveDiffCmdOptions, c common.Args) (bytes.Bu
if err != nil {
return buff, err
}
objs := []oam.Object{}
var objs []*unstructured.Unstructured
if cmdOption.DefinitionFile != "" {
objs, err = ReadDefinitionsFromFile(cmdOption.DefinitionFile)
if err != nil {

View File

@@ -0,0 +1,31 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: testing-app
spec:
components:
- name: testing-dryrun
type: myworker
properties:
image: oamdev/hello-world:v1
policies:
- name: target-default
type: topology
properties:
clusters: [ "local" ]
namespace: "default"
- name: target-prod
type: topology
properties:
clusters: [ "local" ]
namespace: "prod"
workflow:
steps:
- name: deploy2default
type: deploy
properties:
policies: [ "target-default" ]
- name: deploy2prod
type: deploy
properties:
policies: [ "target-prod" ]

View File

@@ -189,7 +189,7 @@ func PrintTraitListFromRegistry(registry Registry, ioStreams cmdutil.IOStreams,
// InstallTraitByNameFromRegistry will install given traitName trait to cluster
func InstallTraitByNameFromRegistry(args common2.Args, ioStream cmdutil.IOStreams, traitName string, registry Registry) error {
capObj, data, err := registry.GetCap(traitName)
_, data, err := registry.GetCap(traitName)
if err != nil {
return err
}
@@ -199,7 +199,7 @@ func InstallTraitByNameFromRegistry(args common2.Args, ioStream cmdutil.IOStream
return err
}
err = common.InstallTraitDefinition(k8sClient, data, ioStream, &capObj)
err = common.InstallTraitDefinition(k8sClient, data, ioStream)
if err != nil {
return err
}

View File

@@ -23,19 +23,17 @@ import (
"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/oam/util"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
)
// InstallComponentDefinition will add a component into K8s cluster and install its controller
func InstallComponentDefinition(client client.Client, componentData []byte, ioStreams cmdutil.IOStreams, tp *types.Capability) error {
func InstallComponentDefinition(client client.Client, componentData []byte, ioStreams cmdutil.IOStreams) error {
var cd v1beta1.ComponentDefinition
var err error
if componentData == nil {
@@ -46,12 +44,6 @@ func InstallComponentDefinition(client client.Client, componentData []byte, ioSt
}
cd.Namespace = types.DefaultKubeVelaNS
ioStreams.Info("Installing component: " + cd.Name)
if cd.Spec.Workload.Type == "" {
tp.CrdInfo = &types.CRDInfo{
APIVersion: cd.Spec.Workload.Definition.APIVersion,
Kind: cd.Spec.Workload.Definition.Kind,
}
}
if err = client.Create(context.Background(), &cd); err != nil && !apierrors.IsAlreadyExists(err) {
return err
}
@@ -59,7 +51,7 @@ func InstallComponentDefinition(client client.Client, componentData []byte, ioSt
}
// InstallTraitDefinition will add a trait into K8s cluster and install it's controller
func InstallTraitDefinition(client client.Client, traitdata []byte, ioStreams cmdutil.IOStreams, cap *types.Capability) error {
func InstallTraitDefinition(client client.Client, traitdata []byte, ioStreams cmdutil.IOStreams) error {
var td v1beta1.TraitDefinition
var err error
if err = yaml.Unmarshal(traitdata, &td); err != nil {
@@ -67,17 +59,6 @@ func InstallTraitDefinition(client client.Client, traitdata []byte, ioStreams cm
}
td.Namespace = types.DefaultKubeVelaNS
ioStreams.Info("Installing trait " + td.Name)
gvk, err := util.GetGVKFromDefinition(client.RESTMapper(), td.Spec.Reference)
if err != nil {
return err
}
cap.CrdInfo = &types.CRDInfo{
APIVersion: v1.GroupVersion{
Group: gvk.Group,
Version: gvk.Version,
}.String(),
Kind: gvk.Kind,
}
if err = client.Create(context.Background(), &td); err != nil && !apierrors.IsAlreadyExists(err) {
return err
}

View File

@@ -24,7 +24,6 @@ import (
"github.com/pkg/errors"
kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
@@ -171,7 +170,7 @@ func GetComponentsFromClusterWithValidateOption(ctx context.Context, namespace s
continue
}
if validateFlag && defRef.Name != types.AutoDetectWorkloadDefinition {
if err = validateCapabilities(tmp, newClient.RESTMapper(), cd.Name, defRef); err != nil {
if err = validateCapabilities(newClient.RESTMapper(), cd.Name, defRef); err != nil {
return nil, nil, err
}
}
@@ -214,7 +213,7 @@ func GetTraitsFromClusterWithValidateOption(ctx context.Context, namespace strin
}
tmp.Namespace = namespace
if validateFlag {
if err = validateCapabilities(tmp, newClient.RESTMapper(), td.Name, td.Spec.Reference); err != nil {
if err = validateCapabilities(newClient.RESTMapper(), td.Name, td.Spec.Reference); err != nil {
return nil, nil, err
}
}
@@ -285,22 +284,16 @@ func GetPolicies(ctx context.Context, namespace string, c common.Args) ([]types.
}
// validateCapabilities validates whether GVK are successfully retrieved.
func validateCapabilities(tmp *types.Capability, mapper meta.RESTMapper, definitionName string, reference commontypes.DefinitionReference) error {
var err error
gvk, err := util.GetGVKFromDefinition(mapper, reference)
func validateCapabilities(mapper meta.RESTMapper, definitionName string, reference commontypes.DefinitionReference) error {
_, err := util.GetGVKFromDefinition(mapper, reference)
if err != nil {
errMsg := err.Error()
var substr = "no matches for "
if strings.Contains(errMsg, substr) {
err = fmt.Errorf("expected provider: %s", strings.Split(errMsg, substr)[1])
return fmt.Errorf("expected provider: %s", strings.Split(errMsg, substr)[1])
}
return fmt.Errorf("installing capability '%s'... %w", definitionName, err)
}
tmp.CrdInfo = &types.CRDInfo{
APIVersion: metav1.GroupVersion{Group: gvk.Group, Version: gvk.Version}.String(),
Kind: gvk.Kind,
}
return nil
}

View File

@@ -77,10 +77,6 @@ var _ = Describe("DefinitionFiles", func() {
Name: "env",
},
},
CrdInfo: &types.CRDInfo{
APIVersion: "apps/v1",
Kind: "Deployment",
},
Labels: map[string]string{"usecase": "forplugintest"},
}
@@ -110,11 +106,7 @@ var _ = Describe("DefinitionFiles", func() {
},
},
CrdName: "deployments.apps",
CrdInfo: &types.CRDInfo{
APIVersion: "apps/v1",
Kind: "Deployment",
},
Labels: map[string]string{"usecase": "forplugintest"},
Labels: map[string]string{"usecase": "forplugintest"},
}
req, _ := labels.NewRequirement("usecase", selection.Equals, []string{"forplugintest"})

View File

@@ -0,0 +1,36 @@
It's used to define Pod networks directly. hostPort routes the container's port directly to the port on the scheduled node, so that you can access the Pod through the host's IP plus hostPort.
Don't specify a hostPort for a Pod unless it is absolutely necessary(run `DaemonSet` service). When you bind a Pod to a hostPort, it limits the number of places the Pod can be scheduled, because each <hostIP, hostPort, protocol> combination must be unique. If you don't specify the hostIP and protocol explicitly, Kubernetes will use 0.0.0.0 as the default hostIP and TCP as the default protocol.
If you explicitly need to expose a Pod's port on the node, consider using `expose` or `gateway` trait, or exposeType and ports parameter of `webservice` component before resorting to `container-ports` trait.
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: busybox
spec:
components:
- name: busybox
type: webservice
properties:
cpu: "0.5"
exposeType: ClusterIP
image: busybox
memory: 1024Mi
ports:
- expose: false
port: 80
protocol: TCP
- expose: false
port: 801
protocol: TCP
traits:
- type: container-ports
properties:
# you can use container-ports to control multiple containers by filling `containers`
# NOTE: in containers, you must set the container name for each container
containers:
- containerName: busybox
ports:
- containerPort: 80
protocol: TCP
hostPort: 8080
```

View File

@@ -0,0 +1,132 @@
import (
"strconv"
"strings"
)
"container-ports": {
type: "trait"
annotations: {}
labels: {}
description: "Expose on the host and bind the external port to host to enable web traffic for your component."
attributes: {
podDisruptive: true
appliesToWorkloads: ["deployments.apps", "statefulsets.apps", "daemonsets.apps", "jobs.batch"]
}
}
template: {
#PatchParams: {
// +usage=Specify the name of the target container, if not set, use the component name
containerName: *"" | string
// +usage=Specify ports you want customer traffic sent to
ports: *[] | [...{
// +usage=Number of port to expose on the pod's IP address
containerPort: int
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
protocol: *"TCP" | "UDP" | "SCTP"
// +usage=Number of port to expose on the host
hostPort?: int
// +usage=What host IP to bind the external port to.
hostIP?: string
}]
}
PatchContainer: {
_params: #PatchParams
name: _params.containerName
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
_baseContainer: *_|_ | {...}
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
}
if len(_matchContainers_) > 0 {
_baseContainer: _matchContainers_[0]
_basePorts: _baseContainer.ports
if _basePorts == _|_ {
// +patchStrategy=replace
ports: [ for port in _params.ports {
containerPort: port.containerPort
protocol: port.protocol
if port.hostPort != _|_ {
hostPort: port.hostPort
}
if port.hostIP != _|_ {
hostIP: port.hostIP
}
}]
}
if _basePorts != _|_ {
_basePortsMap: {for _basePort in _basePorts {(strings.ToLower(_basePort.protocol) + strconv.FormatInt(_basePort.containerPort, 10)): _basePort}}
_portsMap: {for port in _params.ports {(strings.ToLower(port.protocol) + strconv.FormatInt(port.containerPort, 10)): port}}
// +patchStrategy=replace
ports: [ for portVar in _basePorts {
containerPort: portVar.containerPort
protocol: portVar.protocol
_uniqueKey: strings.ToLower(portVar.protocol) + strconv.FormatInt(portVar.containerPort, 10)
if _portsMap[_uniqueKey] != _|_ {
if _portsMap[_uniqueKey].hostPort != _|_ {
hostPort: _portsMap[_uniqueKey].hostPort
}
if _portsMap[_uniqueKey].hostIP != _|_ {
hostIP: _portsMap[_uniqueKey].hostIP
}
}
if _portsMap[_uniqueKey] == _|_ {
if portVar.name != _|_ {
name: portVar.name
}
}
}] + [ for port in _params.ports if _basePortsMap[strings.ToLower(port.protocol)+strconv.FormatInt(port.containerPort, 10)] == _|_ {
if port.containerPort != _|_ {
containerPort: port.containerPort
}
if port.protocol != _|_ {
protocol: port.protocol
}
if port.hostPort != _|_ {
hostPort: port.hostPort
}
if port.hostIP != _|_ {
hostIP: port.hostIP
}
}]
}
}
}
patch: spec: template: spec: {
if parameter.containers == _|_ {
// +patchKey=name
containers: [{
PatchContainer & {_params: {
if parameter.containerName == "" {
containerName: context.name
}
if parameter.containerName != "" {
containerName: parameter.containerName
}
ports: parameter.ports
}}
}]
}
if parameter.containers != _|_ {
// +patchKey=name
containers: [ for c in parameter.containers {
if c.containerName == "" {
err: "container name must be set for containers"
}
if c.containerName != "" {
PatchContainer & {_params: c}
}
}]
}
}
parameter: *#PatchParams | close({
// +usage=Specify the container ports for multiple containers
containers: [...#PatchParams]
})
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]
}