mirror of
https://github.com/kubevela/kubevela.git
synced 2026-03-01 09:10:43 +00:00
Compare commits
69 Commits
v1.2.0-rc.
...
v1.2.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29ecc5c0df | ||
|
|
20c11f2b84 | ||
|
|
e9f7cf7c23 | ||
|
|
cebeff867a | ||
|
|
7902a19aae | ||
|
|
f98b8c7d8a | ||
|
|
ee8773e1cf | ||
|
|
8cf2f20846 | ||
|
|
2c6e8e7de7 | ||
|
|
dbfd6a1d10 | ||
|
|
ce8e652802 | ||
|
|
9968211163 | ||
|
|
c86776cca1 | ||
|
|
11a1b2fa72 | ||
|
|
cd036b87ae | ||
|
|
7e447c6532 | ||
|
|
b836f86484 | ||
|
|
d34372bf47 | ||
|
|
12f392cd92 | ||
|
|
af27e6a776 | ||
|
|
f57815a5bf | ||
|
|
69527b257c | ||
|
|
d88d4d8eca | ||
|
|
4e881b44af | ||
|
|
800b50cf0b | ||
|
|
3d9e1c7d80 | ||
|
|
fccc5df25e | ||
|
|
6cee468743 | ||
|
|
102a155194 | ||
|
|
f39a3fb792 | ||
|
|
8b5d7ed395 | ||
|
|
5b1c47c918 | ||
|
|
c298c98f25 | ||
|
|
7f7a9dcac0 | ||
|
|
b4732ed275 | ||
|
|
bfbdb85503 | ||
|
|
f41e0a3bb5 | ||
|
|
19a542ff11 | ||
|
|
d64c78db47 | ||
|
|
ceb95229cd | ||
|
|
ece47b5961 | ||
|
|
8be11a7e7e | ||
|
|
b354d2faa9 | ||
|
|
3af323365b | ||
|
|
6a512c02a6 | ||
|
|
b30ca0c8a2 | ||
|
|
1a50dd76b5 | ||
|
|
b17abe0081 | ||
|
|
12a106fcfe | ||
|
|
53d3ff6915 | ||
|
|
d4762e09cd | ||
|
|
578aae6482 | ||
|
|
96485ea0db | ||
|
|
251c440453 | ||
|
|
770894412a | ||
|
|
4d6c0eb9d5 | ||
|
|
53081d043b | ||
|
|
8495465087 | ||
|
|
5f31b9aad0 | ||
|
|
9f2e43756e | ||
|
|
8033279751 | ||
|
|
070b313897 | ||
|
|
c170cecd34 | ||
|
|
acac0554f3 | ||
|
|
1bceea29be | ||
|
|
3066cde46b | ||
|
|
15be6bc388 | ||
|
|
ac6b125b7f | ||
|
|
24c00fc99b |
6
.github/workflows/registry.yml
vendored
6
.github/workflows/registry.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
||||
|
||||
- name: Build & Pushing vela-core for ACR
|
||||
run: |
|
||||
docker build --build-arg GOPROXY=https://proxy.golang.org -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }} .
|
||||
docker build --build-arg GOPROXY=https://proxy.golang.org --build-arg VERSION=${{ steps.get_version.outputs.VERSION }} --build-arg GITVERSION=git-${{ steps.vars.outputs.git_revision }} -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }} .
|
||||
docker push kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
|
||||
- uses: docker/build-push-action@v2
|
||||
name: Build & Pushing vela-core for Dockerhub and GHCR
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
|
||||
- name: Build & Pushing vela-apiserver for ACR
|
||||
run: |
|
||||
docker build --build-arg GOPROXY=https://proxy.golang.org -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }} -f Dockerfile.apiserver .
|
||||
docker build --build-arg GOPROXY=https://proxy.golang.org --build-arg VERSION=${{ steps.get_version.outputs.VERSION }} --build-arg GITVERSION=git-${{ steps.vars.outputs.git_revision }} -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }} -f Dockerfile.apiserver .
|
||||
docker push kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }}
|
||||
- uses: docker/build-push-action@v2
|
||||
name: Build & Pushing vela-apiserver for Dockerhub and GHCR
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
|
||||
- name: Build & Pushing vela runtime rollout for ACR
|
||||
run: |
|
||||
docker build --build-arg GOPROXY=https://proxy.golang.org -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }} .
|
||||
docker build --build-arg GOPROXY=https://proxy.golang.org --build-arg VERSION=${{ steps.get_version.outputs.VERSION }} --build-arg GITVERSION=git-${{ steps.vars.outputs.git_revision }} -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }} .
|
||||
docker push kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }}
|
||||
- uses: docker/build-push-action@v2
|
||||
name: Build & Pushing runtime rollout for Dockerhub and GHCR
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -142,7 +142,7 @@ jobs:
|
||||
- name: Update Homebrew formula
|
||||
uses: dawidd6/action-homebrew-bump-formula@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.HOMEBREW_TOKEN }}
|
||||
formula: kubevela
|
||||
tag: ${{ github.ref }}
|
||||
revision: ${{ github.sha }}
|
||||
|
||||
@@ -213,6 +213,8 @@ const (
|
||||
WorkflowStateFinished WorkflowState = "finished"
|
||||
// WorkflowStateExecuting means workflow is still running or waiting some steps.
|
||||
WorkflowStateExecuting WorkflowState = "executing"
|
||||
// WorkflowStateSkipping means it will skip this reconcile and let next reconcile to handle it.
|
||||
WorkflowStateSkipping WorkflowState = "skipping"
|
||||
)
|
||||
|
||||
// ApplicationComponentStatus record the health status of App component
|
||||
@@ -289,8 +291,6 @@ type AppStatus struct {
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
Rollout *AppRolloutStatus `json:"rollout,omitempty"`
|
||||
|
||||
Phase ApplicationPhase `json:"status,omitempty"`
|
||||
|
||||
// Components record the related Components created by Application Controller
|
||||
|
||||
@@ -45,11 +45,6 @@ func (in *AppRolloutStatus) DeepCopy() *AppRolloutStatus {
|
||||
func (in *AppStatus) DeepCopyInto(out *AppStatus) {
|
||||
*out = *in
|
||||
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
|
||||
if in.Rollout != nil {
|
||||
in, out := &in.Rollout, &out.Rollout
|
||||
*out = new(AppRolloutStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Components != nil {
|
||||
in, out := &in.Components, &out.Components
|
||||
*out = make([]v1.ObjectReference, len(*in))
|
||||
|
||||
@@ -45,10 +45,11 @@ func (in *EnvTraitPatch) ToApplicationTrait() *common.ApplicationTrait {
|
||||
|
||||
// EnvComponentPatch is the patch to component
|
||||
type EnvComponentPatch struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
Traits []EnvTraitPatch `json:"traits,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
Traits []EnvTraitPatch `json:"traits,omitempty"`
|
||||
ExternalRevision string `json:"externalRevision,omitempty"`
|
||||
}
|
||||
|
||||
// ToApplicationComponent convert EnvComponentPatch into ApplicationComponent
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
// AppRolloutSpec defines how to describe an upgrade between different apps
|
||||
type AppRolloutSpec struct {
|
||||
// TargetAppRevisionName contains the name of the applicationRevision that we need to upgrade to.
|
||||
TargetAppRevisionName string `json:"targetAppRevisionName"`
|
||||
|
||||
// SourceAppRevisionName contains the name of the applicationRevision that we need to upgrade from.
|
||||
// it can be empty only when the rolling is only a scale event
|
||||
SourceAppRevisionName string `json:"sourceAppRevisionName,omitempty"`
|
||||
|
||||
// The list of component to upgrade in the application.
|
||||
// We only support single component application so far
|
||||
// TODO: (RZ) Support multiple components in an application
|
||||
// +optional
|
||||
ComponentList []string `json:"componentList,omitempty"`
|
||||
|
||||
// RolloutPlan is the details on how to rollout the resources
|
||||
RolloutPlan v1alpha1.RolloutPlan `json:"rolloutPlan"`
|
||||
|
||||
// RevertOnDelete revert the rollout when the rollout CR is deleted
|
||||
// It will remove the target app from the kubernetes if it's set to true
|
||||
// +optional
|
||||
RevertOnDelete *bool `json:"revertOnDelete,omitempty"`
|
||||
}
|
||||
|
||||
// AppRolloutStatus defines the observed state of AppRollout
|
||||
type AppRolloutStatus struct {
|
||||
v1alpha1.RolloutStatus `json:",inline"`
|
||||
|
||||
// LastUpgradedTargetAppRevision contains the name of the app that we upgraded to
|
||||
// We will restart the rollout if this is not the same as the spec
|
||||
LastUpgradedTargetAppRevision string `json:"lastTargetAppRevision"`
|
||||
|
||||
// LastSourceAppRevision contains the name of the app that we need to upgrade from.
|
||||
// We will restart the rollout if this is not the same as the spec
|
||||
LastSourceAppRevision string `json:"LastSourceAppRevision,omitempty"`
|
||||
}
|
||||
|
||||
// AppRollout is the Schema for the AppRollout API
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories={oam},shortName=approllout
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="TARGET",type=string,JSONPath=`.status.rolloutStatus.rolloutTargetSize`
|
||||
// +kubebuilder:printcolumn:name="UPGRADED",type=string,JSONPath=`.status.rolloutStatus.upgradedReplicas`
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.rolloutStatus.upgradedReadyReplicas`
|
||||
// +kubebuilder:printcolumn:name="BATCH-STATE",type=string,JSONPath=`.status.rolloutStatus.batchRollingState`
|
||||
// +kubebuilder:printcolumn:name="ROLLING-STATE",type=string,JSONPath=`.status.rolloutStatus.rollingState`
|
||||
// +kubebuilder:printcolumn:name="AGE",type=date,JSONPath=".metadata.creationTimestamp"
|
||||
type AppRollout struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec AppRolloutSpec `json:"spec,omitempty"`
|
||||
Status AppRolloutStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// AppRolloutList contains a list of AppRollout
|
||||
// +kubebuilder:object:root=true
|
||||
type AppRolloutList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []AppRollout `json:"items"`
|
||||
}
|
||||
@@ -64,8 +64,6 @@ func ApplicationV1alpha2ToV1beta1(v1a2 *Application, v1b1 *v1beta1.Application)
|
||||
Scopes: scopes,
|
||||
})
|
||||
}
|
||||
// 3.2) convert Spec.RolloutPlan
|
||||
v1b1.Spec.RolloutPlan = v1a2.Spec.RolloutPlan.DeepCopy()
|
||||
|
||||
// 4) convert Status common.AppStatus
|
||||
v1b1.Status = *v1a2.Status.DeepCopy()
|
||||
@@ -131,8 +129,6 @@ func (app *Application) ConvertFrom(src conversion.Hub) error {
|
||||
Scopes: scopes,
|
||||
})
|
||||
}
|
||||
// 3.2) convert Spec.RolloutPlan
|
||||
app.Spec.RolloutPlan = sourceApp.Spec.RolloutPlan.DeepCopy()
|
||||
|
||||
// 4) convert Status common.AppStatus
|
||||
app.Status = *sourceApp.Status.DeepCopy()
|
||||
|
||||
@@ -109,14 +109,6 @@ var (
|
||||
ApplicationKindVersionKind = SchemeGroupVersion.WithKind(ApplicationKind)
|
||||
)
|
||||
|
||||
// AppRollout type metadata.
|
||||
var (
|
||||
AppRolloutKind = reflect.TypeOf(AppRollout{}).Name()
|
||||
AppRolloutGroupKind = schema.GroupKind{Group: Group, Kind: AppRolloutKind}.String()
|
||||
AppRolloutKindAPIVersion = ApplicationKind + "." + SchemeGroupVersion.String()
|
||||
AppRolloutKindVersionKind = SchemeGroupVersion.WithKind(AppRolloutKind)
|
||||
)
|
||||
|
||||
// ApplicationRevision type metadata
|
||||
var (
|
||||
ApplicationRevisionKind = reflect.TypeOf(ApplicationRevision{}).Name()
|
||||
@@ -135,6 +127,5 @@ func init() {
|
||||
SchemeBuilder.Register(&ManualScalerTrait{}, &ManualScalerTraitList{})
|
||||
SchemeBuilder.Register(&HealthScope{}, &HealthScopeList{})
|
||||
SchemeBuilder.Register(&Application{}, &ApplicationList{})
|
||||
SchemeBuilder.Register(&AppRollout{}, &AppRolloutList{})
|
||||
SchemeBuilder.Register(&ApplicationRevision{}, &ApplicationRevisionList{})
|
||||
}
|
||||
|
||||
@@ -76,107 +76,6 @@ func (in *AppReference) DeepCopy() *AppReference {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRollout) DeepCopyInto(out *AppRollout) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRollout.
|
||||
func (in *AppRollout) DeepCopy() *AppRollout {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRollout)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *AppRollout) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRolloutList) DeepCopyInto(out *AppRolloutList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]AppRollout, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRolloutList.
|
||||
func (in *AppRolloutList) DeepCopy() *AppRolloutList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRolloutList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *AppRolloutList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRolloutSpec) DeepCopyInto(out *AppRolloutSpec) {
|
||||
*out = *in
|
||||
if in.ComponentList != nil {
|
||||
in, out := &in.ComponentList, &out.ComponentList
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.RolloutPlan.DeepCopyInto(&out.RolloutPlan)
|
||||
if in.RevertOnDelete != nil {
|
||||
in, out := &in.RevertOnDelete, &out.RevertOnDelete
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRolloutSpec.
|
||||
func (in *AppRolloutSpec) DeepCopy() *AppRolloutSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRolloutSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRolloutStatus) DeepCopyInto(out *AppRolloutStatus) {
|
||||
*out = *in
|
||||
in.RolloutStatus.DeepCopyInto(&out.RolloutStatus)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRolloutStatus.
|
||||
func (in *AppRolloutStatus) DeepCopy() *AppRolloutStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRolloutStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppStatus) DeepCopyInto(out *AppStatus) {
|
||||
*out = *in
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
Copyright 2021. The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
)
|
||||
|
||||
// AppDeploymentPhase defines the phase that the AppDeployment is undergoing.
|
||||
type AppDeploymentPhase string
|
||||
|
||||
const (
|
||||
// PhaseRolling is the phase when the AppDeployment is rolling live instances from old revisions to new ones.
|
||||
PhaseRolling AppDeploymentPhase = "Rolling"
|
||||
|
||||
// PhaseCompleted is the phase when the AppDeployment is done with reconciliation.
|
||||
PhaseCompleted AppDeploymentPhase = "Completed"
|
||||
|
||||
// PhaseFailed is the phase when the AppDeployment has failed in reconciliation due to unexpected conditions.
|
||||
PhaseFailed AppDeploymentPhase = "Failed"
|
||||
)
|
||||
|
||||
// HTTPMatchRequest specifies a set of criterion to be met in order for the
|
||||
// rule to be applied to the HTTP request. For example, the following
|
||||
// restricts the rule to match only requests where the URL path
|
||||
// starts with /ratings/v2/ and the request contains a custom `end-user` header
|
||||
// with value `jason`.
|
||||
type HTTPMatchRequest struct {
|
||||
// URI defines how to match with an URI.
|
||||
URI *URIMatch `json:"uri,omitempty"`
|
||||
}
|
||||
|
||||
// URIMatch defines the rules to match with an URI.
|
||||
type URIMatch struct {
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRule defines the rules to match and split http traffic across revisions.
|
||||
type HTTPRule struct {
|
||||
|
||||
// Match defines the conditions to be satisfied for the rule to be
|
||||
// activated. All conditions inside a single match block have AND
|
||||
// semantics, while the list of match blocks have OR semantics. The rule
|
||||
// is matched if any one of the match blocks succeed.
|
||||
Match []*HTTPMatchRequest `json:"match,omitempty"`
|
||||
|
||||
// WeightedTargets defines the revision targets to select and route traffic to.
|
||||
WeightedTargets []WeightedTarget `json:"weightedTargets,omitempty"`
|
||||
}
|
||||
|
||||
// WeightedTarget defines the revision target to select and route traffic to.
|
||||
type WeightedTarget struct {
|
||||
|
||||
// RevisionName is the name of the app revision.
|
||||
RevisionName string `json:"revisionName,omitempty"`
|
||||
|
||||
// ComponentName is the name of the component.
|
||||
// Note that it is the original component name in the Application. No need to append revision.
|
||||
ComponentName string `json:"componentName,omitempty"`
|
||||
|
||||
// Port is the port to route traffic towards.
|
||||
Port int `json:"port,omitempty"`
|
||||
|
||||
// Weight defines the proportion of traffic to be forwarded to the service
|
||||
// version. (0-100). Sum of weights across destinations SHOULD BE == 100.
|
||||
// If there is only one destination in a rule, the weight value is assumed to
|
||||
// be 100.
|
||||
Weight int `json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
// Traffic defines the traffic rules to apply across revisions.
|
||||
type Traffic struct {
|
||||
// Hosts are the destination hosts to which traffic is being sent. Could
|
||||
// be a DNS name with wildcard prefix or an IP address.
|
||||
Hosts []string `json:"hosts,omitempty"`
|
||||
|
||||
// Gateways specifies the names of gateways that should apply these rules.
|
||||
// Gateways in other namespaces may be referred to by
|
||||
// `<gateway namespace>/<gateway name>`; specifying a gateway with no
|
||||
// namespace qualifier is the same as specifying the AppDeployment's namespace.
|
||||
Gateways []string `json:"gateways,omitempty"`
|
||||
|
||||
// HTTP defines the rules to match and split http traffoc across revisions.
|
||||
HTTP []HTTPRule `json:"http,omitempty"`
|
||||
}
|
||||
|
||||
// AppRevision specifies an AppRevision resource to and the rules to apply to it.
|
||||
type AppRevision struct {
|
||||
// RevisionName is the name of the AppRevision.
|
||||
RevisionName string `json:"revisionName,omitempty"`
|
||||
|
||||
// Placement defines the cluster placement rules for an app revision.
|
||||
Placement []common.ClusterPlacement `json:"placement,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterPlacementStatus shows the placement results of a cluster.
|
||||
type ClusterPlacementStatus struct {
|
||||
// ClusterName indicates the name of the cluster to deploy apps to.
|
||||
// If empty, it indicates the host cluster per se.
|
||||
ClusterName string `json:"clusterName,omitempty"`
|
||||
|
||||
// Replicas indicates the replica number of an app revision to deploy to a cluster.
|
||||
Replicas int `json:"replicas,omitempty"`
|
||||
}
|
||||
|
||||
// PlacementStatus shows the cluster placement results of an app revision.
|
||||
type PlacementStatus struct {
|
||||
// RevisionName is the name of the AppRevision.
|
||||
RevisionName string `json:"revisionName,omitempty"`
|
||||
|
||||
// Clusters shows cluster placement results.
|
||||
Clusters []ClusterPlacementStatus `json:"clusters,omitempty"`
|
||||
}
|
||||
|
||||
// AppDeploymentSpec defines how to describe an upgrade between different apps
|
||||
type AppDeploymentSpec struct {
|
||||
|
||||
// Traffic defines the traffic rules to apply across revisions.
|
||||
Traffic *Traffic `json:"traffic,omitempty"`
|
||||
|
||||
// AppRevision specifies AppRevision resources to and the rules to apply to them.
|
||||
AppRevisions []AppRevision `json:"appRevisions,omitempty"`
|
||||
}
|
||||
|
||||
// AppDeploymentStatus defines the observed state of AppDeployment
|
||||
type AppDeploymentStatus struct {
|
||||
// Conditions represents the latest available observations of a CloneSet's current state.
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
|
||||
// Phase shows the phase that the AppDeployment is undergoing.
|
||||
// If Phase is Rolling, no update should be made to the spec.
|
||||
Phase AppDeploymentPhase `json:"phase,omitempty"`
|
||||
|
||||
// Placement shows the cluster placement results of the app revisions.
|
||||
Placement []PlacementStatus `json:"placement,omitempty"`
|
||||
}
|
||||
|
||||
// AppDeployment is the Schema for the AppDeployment API
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories={oam},shortName=appdeploy
|
||||
// +kubebuilder:subresource:status
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type AppDeployment struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec AppDeploymentSpec `json:"spec,omitempty"`
|
||||
Status AppDeploymentStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// AppDeploymentList contains a list of AppDeployment
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type AppDeploymentList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []AppDeployment `json:"items"`
|
||||
}
|
||||
@@ -17,12 +17,14 @@
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -86,11 +88,6 @@ type ApplicationSpec struct {
|
||||
Workflow *Workflow `json:"workflow,omitempty"`
|
||||
|
||||
// TODO(wonderflow): we should have application level scopes supported here
|
||||
|
||||
// RolloutPlan is the details on how to rollout the resources
|
||||
// The controller simply replace the old resources with the new one if there is no rollout plan involved
|
||||
// +optional
|
||||
RolloutPlan *v1alpha1.RolloutPlan `json:"rolloutPlan,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
@@ -144,3 +141,36 @@ func (app *Application) GetComponent(workloadType string) *common.ApplicationCom
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unstructured convert application to unstructured.Unstructured.
|
||||
func (app *Application) Unstructured() (*unstructured.Unstructured, error) {
|
||||
var obj = &unstructured.Unstructured{}
|
||||
app.SetGroupVersionKind(ApplicationKindVersionKind)
|
||||
bt, err := json.Marshal(app)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := obj.UnmarshalJSON(bt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if app.Status.Services == nil {
|
||||
if err := unstructured.SetNestedSlice(obj.Object, []interface{}{}, "status", "services"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if app.Status.AppliedResources == nil {
|
||||
if err := unstructured.SetNestedSlice(obj.Object, []interface{}{}, "status", "appliedResources"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if wfStatus := app.Status.Workflow; wfStatus != nil && wfStatus.Steps == nil {
|
||||
if err := unstructured.SetNestedSlice(obj.Object, []interface{}{}, "status", "workflow", "steps"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
Copyright 2021. The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
// AppRolloutSpec defines how to describe an upgrade between different apps
|
||||
type AppRolloutSpec struct {
|
||||
// TargetAppRevisionName contains the name of the applicationConfiguration that we need to upgrade to.
|
||||
// Here we use an applicationConfiguration as a revision of an application, thus the name alone is suffice
|
||||
TargetAppRevisionName string `json:"targetAppRevisionName"`
|
||||
|
||||
// SourceAppRevisionName contains the name of the applicationConfiguration that we need to upgrade from.
|
||||
// it can be empty only when it's the first time to deploy the application
|
||||
SourceAppRevisionName string `json:"sourceAppRevisionName,omitempty"`
|
||||
|
||||
// The list of component to upgrade in the application.
|
||||
// We only support single component application so far
|
||||
// TODO: (RZ) Support multiple components in an application
|
||||
// +optional
|
||||
ComponentList []string `json:"componentList,omitempty"`
|
||||
|
||||
// RolloutPlan is the details on how to rollout the resources
|
||||
RolloutPlan v1alpha1.RolloutPlan `json:"rolloutPlan"`
|
||||
|
||||
// RevertOnDelete revert the failed rollout when the rollout CR is deleted
|
||||
// It will revert the change back to the source version at once (not in batches)
|
||||
// Default is false
|
||||
// +optional
|
||||
RevertOnDelete bool `json:"revertOnDelete,omitempty"`
|
||||
}
|
||||
|
||||
// AppRollout is the Schema for the AppRollout API
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories={oam},shortName=approllout
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="TARGET",type=string,JSONPath=`.status.rolloutTargetSize`
|
||||
// +kubebuilder:printcolumn:name="UPGRADED",type=string,JSONPath=`.status.upgradedReplicas`
|
||||
// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.upgradedReadyReplicas`
|
||||
// +kubebuilder:printcolumn:name="BATCH-STATE",type=string,JSONPath=`.status.batchRollingState`
|
||||
// +kubebuilder:printcolumn:name="ROLLING-STATE",type=string,JSONPath=`.status.rollingState`
|
||||
// +kubebuilder:printcolumn:name="AGE",type=date,JSONPath=".metadata.creationTimestamp"
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type AppRollout struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec AppRolloutSpec `json:"spec,omitempty"`
|
||||
Status common.AppRolloutStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// AppRolloutList contains a list of AppRollout
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type AppRolloutList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []AppRollout `json:"items"`
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// ClusterSpec defines the desired state of Cluster
|
||||
type ClusterSpec struct {
|
||||
// KubeconfigSecretRef specifies the reference to the secret
|
||||
// that contains the kubeconfig in field `config`.
|
||||
KubeconfigSecretRef LocalSecretReference `json:"kubeconfigSecretRef,omitempty"`
|
||||
}
|
||||
|
||||
// LocalSecretReference is a reference to a secret within the enclosing
|
||||
// namespace.
|
||||
type LocalSecretReference struct {
|
||||
// Name of a secret within the enclosing namespace.
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ClusterStatus defines the observed state of Cluster
|
||||
type ClusterStatus struct {
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Cluster is the Schema for the clusters API
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ClusterSpec `json:"spec,omitempty"`
|
||||
Status ClusterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ClusterList contains a list of Cluster
|
||||
type ClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Cluster `json:"items"`
|
||||
}
|
||||
@@ -96,14 +96,6 @@ var (
|
||||
ApplicationKindVersionKind = SchemeGroupVersion.WithKind(ApplicationKind)
|
||||
)
|
||||
|
||||
// AppRollout type metadata.
|
||||
var (
|
||||
AppRolloutKind = reflect.TypeOf(AppRollout{}).Name()
|
||||
AppRolloutGroupKind = schema.GroupKind{Group: Group, Kind: AppRolloutKind}.String()
|
||||
AppRolloutKindAPIVersion = ApplicationKind + "." + SchemeGroupVersion.String()
|
||||
AppRolloutKindVersionKind = SchemeGroupVersion.WithKind(AppRolloutKind)
|
||||
)
|
||||
|
||||
// ApplicationRevision type metadata
|
||||
var (
|
||||
ApplicationRevisionKind = reflect.TypeOf(ApplicationRevision{}).Name()
|
||||
@@ -128,22 +120,6 @@ var (
|
||||
ResourceTrackerKindVersionKind = SchemeGroupVersion.WithKind(ResourceTrackerKind)
|
||||
)
|
||||
|
||||
// AppDeployment type metadata.
|
||||
var (
|
||||
AppDeploymentKind = reflect.TypeOf(AppDeployment{}).Name()
|
||||
AppDeploymentGroupKind = schema.GroupKind{Group: Group, Kind: AppDeploymentKind}.String()
|
||||
AppDeploymentKindAPIVersion = AppDeploymentKind + "." + SchemeGroupVersion.String()
|
||||
AppDeploymentKindVersionKind = SchemeGroupVersion.WithKind(AppDeploymentKind)
|
||||
)
|
||||
|
||||
// Cluster type metadata.
|
||||
var (
|
||||
ClusterKind = reflect.TypeOf(Cluster{}).Name()
|
||||
ClusterGroupKind = schema.GroupKind{Group: Group, Kind: ClusterKind}.String()
|
||||
ClusterKindAPIVersion = ApplicationKind + "." + SchemeGroupVersion.String()
|
||||
ClusterKindVersionKind = SchemeGroupVersion.WithKind(ClusterKind)
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ComponentDefinition{}, &ComponentDefinitionList{})
|
||||
SchemeBuilder.Register(&WorkloadDefinition{}, &WorkloadDefinitionList{})
|
||||
@@ -153,10 +129,7 @@ func init() {
|
||||
SchemeBuilder.Register(&DefinitionRevision{}, &DefinitionRevisionList{})
|
||||
SchemeBuilder.Register(&ScopeDefinition{}, &ScopeDefinitionList{})
|
||||
SchemeBuilder.Register(&Application{}, &ApplicationList{})
|
||||
SchemeBuilder.Register(&AppRollout{}, &AppRolloutList{})
|
||||
SchemeBuilder.Register(&ApplicationRevision{}, &ApplicationRevisionList{})
|
||||
SchemeBuilder.Register(&AppDeployment{}, &AppDeploymentList{})
|
||||
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
|
||||
SchemeBuilder.Register(&ResourceTracker{}, &ResourceTrackerList{})
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ func (in *ResourceTracker) findMangedResourceIndex(mr ManagedResource) int {
|
||||
}
|
||||
|
||||
// AddManagedResource add object to managed resources, if exists, update
|
||||
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool) {
|
||||
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool) (updated bool) {
|
||||
gvk := rsc.GetObjectKind().GroupVersionKind()
|
||||
mr := ManagedResource{
|
||||
ClusterObjectReference: common.ClusterObjectReference{
|
||||
@@ -206,17 +206,21 @@ func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool)
|
||||
mr.Data = &runtime.RawExtension{Object: rsc}
|
||||
}
|
||||
if idx := in.findMangedResourceIndex(mr); idx >= 0 {
|
||||
if reflect.DeepEqual(in.Spec.ManagedResources[idx], mr) {
|
||||
return false
|
||||
}
|
||||
in.Spec.ManagedResources[idx] = mr
|
||||
} else {
|
||||
in.Spec.ManagedResources = append(in.Spec.ManagedResources, mr)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// DeleteManagedResource if remove flag is on, it will remove the object from recorded resources.
|
||||
// otherwise, it will mark the object as deleted instead of removing it
|
||||
// workflow stage: resources are marked as deleted (and execute the deletion action)
|
||||
// state-keep stage: resources marked as deleted and successfully deleted will be removed from resourcetracker
|
||||
func (in *ResourceTracker) DeleteManagedResource(rsc client.Object, remove bool) {
|
||||
func (in *ResourceTracker) DeleteManagedResource(rsc client.Object, remove bool) (updated bool) {
|
||||
gvk := rsc.GetObjectKind().GroupVersionKind()
|
||||
mr := ManagedResource{
|
||||
ClusterObjectReference: common.ClusterObjectReference{
|
||||
@@ -234,6 +238,9 @@ func (in *ResourceTracker) DeleteManagedResource(rsc client.Object, remove bool)
|
||||
if remove {
|
||||
in.Spec.ManagedResources = append(in.Spec.ManagedResources[:idx], in.Spec.ManagedResources[idx+1:]...)
|
||||
} else {
|
||||
if reflect.DeepEqual(in.Spec.ManagedResources[idx], mr) {
|
||||
return false
|
||||
}
|
||||
in.Spec.ManagedResources[idx] = mr
|
||||
}
|
||||
} else {
|
||||
@@ -241,6 +248,7 @@ func (in *ResourceTracker) DeleteManagedResource(rsc client.Object, remove bool)
|
||||
in.Spec.ManagedResources = append(in.Spec.ManagedResources, mr)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// addClusterObjectReference
|
||||
|
||||
@@ -25,118 +25,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppDeployment) DeepCopyInto(out *AppDeployment) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppDeployment.
|
||||
func (in *AppDeployment) DeepCopy() *AppDeployment {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppDeployment)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *AppDeployment) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppDeploymentList) DeepCopyInto(out *AppDeploymentList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]AppDeployment, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppDeploymentList.
|
||||
func (in *AppDeploymentList) DeepCopy() *AppDeploymentList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppDeploymentList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *AppDeploymentList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppDeploymentSpec) DeepCopyInto(out *AppDeploymentSpec) {
|
||||
*out = *in
|
||||
if in.Traffic != nil {
|
||||
in, out := &in.Traffic, &out.Traffic
|
||||
*out = new(Traffic)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.AppRevisions != nil {
|
||||
in, out := &in.AppRevisions, &out.AppRevisions
|
||||
*out = make([]AppRevision, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppDeploymentSpec.
|
||||
func (in *AppDeploymentSpec) DeepCopy() *AppDeploymentSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppDeploymentSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppDeploymentStatus) DeepCopyInto(out *AppDeploymentStatus) {
|
||||
*out = *in
|
||||
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
|
||||
if in.Placement != nil {
|
||||
in, out := &in.Placement, &out.Placement
|
||||
*out = make([]PlacementStatus, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppDeploymentStatus.
|
||||
func (in *AppDeploymentStatus) DeepCopy() *AppDeploymentStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppDeploymentStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppPolicy) DeepCopyInto(out *AppPolicy) {
|
||||
*out = *in
|
||||
@@ -157,108 +47,6 @@ func (in *AppPolicy) DeepCopy() *AppPolicy {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRevision) DeepCopyInto(out *AppRevision) {
|
||||
*out = *in
|
||||
if in.Placement != nil {
|
||||
in, out := &in.Placement, &out.Placement
|
||||
*out = make([]common.ClusterPlacement, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRevision.
|
||||
func (in *AppRevision) DeepCopy() *AppRevision {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRevision)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRollout) DeepCopyInto(out *AppRollout) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRollout.
|
||||
func (in *AppRollout) DeepCopy() *AppRollout {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRollout)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *AppRollout) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRolloutList) DeepCopyInto(out *AppRolloutList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]AppRollout, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRolloutList.
|
||||
func (in *AppRolloutList) DeepCopy() *AppRolloutList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRolloutList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *AppRolloutList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppRolloutSpec) DeepCopyInto(out *AppRolloutSpec) {
|
||||
*out = *in
|
||||
if in.ComponentList != nil {
|
||||
in, out := &in.ComponentList, &out.ComponentList
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.RolloutPlan.DeepCopyInto(&out.RolloutPlan)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRolloutSpec.
|
||||
func (in *AppRolloutSpec) DeepCopy() *AppRolloutSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppRolloutSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Application) DeepCopyInto(out *Application) {
|
||||
*out = *in
|
||||
@@ -472,11 +260,6 @@ func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) {
|
||||
*out = new(Workflow)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.RolloutPlan != nil {
|
||||
in, out := &in.RolloutPlan, &out.RolloutPlan
|
||||
*out = new(v1alpha1.RolloutPlan)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSpec.
|
||||
@@ -489,111 +272,6 @@ func (in *ApplicationSpec) DeepCopy() *ApplicationSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Cluster) DeepCopyInto(out *Cluster) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
||||
func (in *Cluster) DeepCopy() *Cluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Cluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Cluster) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Cluster, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
|
||||
func (in *ClusterList) DeepCopy() *ClusterList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterPlacementStatus) DeepCopyInto(out *ClusterPlacementStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPlacementStatus.
|
||||
func (in *ClusterPlacementStatus) DeepCopy() *ClusterPlacementStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterPlacementStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
||||
*out = *in
|
||||
out.KubeconfigSecretRef = in.KubeconfigSecretRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
|
||||
func (in *ClusterSpec) DeepCopy() *ClusterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
|
||||
func (in *ClusterStatus) DeepCopy() *ClusterStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ComponentDefinition) DeepCopyInto(out *ComponentDefinition) {
|
||||
*out = *in
|
||||
@@ -789,72 +467,6 @@ func (in *DefinitionRevisionSpec) DeepCopy() *DefinitionRevisionSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPMatchRequest) DeepCopyInto(out *HTTPMatchRequest) {
|
||||
*out = *in
|
||||
if in.URI != nil {
|
||||
in, out := &in.URI, &out.URI
|
||||
*out = new(URIMatch)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPMatchRequest.
|
||||
func (in *HTTPMatchRequest) DeepCopy() *HTTPMatchRequest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HTTPMatchRequest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPRule) DeepCopyInto(out *HTTPRule) {
|
||||
*out = *in
|
||||
if in.Match != nil {
|
||||
in, out := &in.Match, &out.Match
|
||||
*out = make([]*HTTPMatchRequest, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(HTTPMatchRequest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.WeightedTargets != nil {
|
||||
in, out := &in.WeightedTargets, &out.WeightedTargets
|
||||
*out = make([]WeightedTarget, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRule.
|
||||
func (in *HTTPRule) DeepCopy() *HTTPRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HTTPRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LocalSecretReference) DeepCopyInto(out *LocalSecretReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalSecretReference.
|
||||
func (in *LocalSecretReference) DeepCopy() *LocalSecretReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LocalSecretReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManagedResource) DeepCopyInto(out *ManagedResource) {
|
||||
*out = *in
|
||||
@@ -877,26 +489,6 @@ func (in *ManagedResource) DeepCopy() *ManagedResource {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PlacementStatus) DeepCopyInto(out *PlacementStatus) {
|
||||
*out = *in
|
||||
if in.Clusters != nil {
|
||||
in, out := &in.Clusters, &out.Clusters
|
||||
*out = make([]ClusterPlacementStatus, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementStatus.
|
||||
func (in *PlacementStatus) DeepCopy() *PlacementStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PlacementStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyDefinition) DeepCopyInto(out *PolicyDefinition) {
|
||||
*out = *in
|
||||
@@ -1178,38 +770,6 @@ func (in *ScopeDefinitionSpec) DeepCopy() *ScopeDefinitionSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Traffic) DeepCopyInto(out *Traffic) {
|
||||
*out = *in
|
||||
if in.Hosts != nil {
|
||||
in, out := &in.Hosts, &out.Hosts
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Gateways != nil {
|
||||
in, out := &in.Gateways, &out.Gateways
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.HTTP != nil {
|
||||
in, out := &in.HTTP, &out.HTTP
|
||||
*out = make([]HTTPRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Traffic.
|
||||
func (in *Traffic) DeepCopy() *Traffic {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Traffic)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TraitDefinition) DeepCopyInto(out *TraitDefinition) {
|
||||
*out = *in
|
||||
@@ -1331,36 +891,6 @@ func (in *TraitDefinitionStatus) DeepCopy() *TraitDefinitionStatus {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *URIMatch) DeepCopyInto(out *URIMatch) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new URIMatch.
|
||||
func (in *URIMatch) DeepCopy() *URIMatch {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(URIMatch)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WeightedTarget) DeepCopyInto(out *WeightedTarget) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WeightedTarget.
|
||||
func (in *WeightedTarget) DeepCopy() *WeightedTarget {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WeightedTarget)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Workflow) DeepCopyInto(out *Workflow) {
|
||||
*out = *in
|
||||
|
||||
@@ -179,6 +179,8 @@ type Capability struct {
|
||||
|
||||
// Terraform
|
||||
TerraformConfiguration string `json:"terraformConfiguration,omitempty"`
|
||||
ConfigurationType string `json:"configurationType,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
|
||||
// KubeTemplate
|
||||
KubeTemplate runtime.RawExtension `json:"kubetemplate,omitempty"`
|
||||
|
||||
@@ -48,6 +48,14 @@ const (
|
||||
LabelDefinitionDeprecated = "custom.definition.oam.dev/deprecated"
|
||||
// LabelDefinitionHidden is the label which describe whether the capability is hidden by UI
|
||||
LabelDefinitionHidden = "custom.definition.oam.dev/ui-hidden"
|
||||
// LabelNodeRoleGateway gateway role of node
|
||||
LabelNodeRoleGateway = "node-role.kubernetes.io/gateway"
|
||||
// LabelNodeRoleWorker worker role of node
|
||||
LabelNodeRoleWorker = "node-role.kubernetes.io/worker"
|
||||
// AnnoIngressControllerHTTPSPort define ingress controller listen port for https
|
||||
AnnoIngressControllerHTTPSPort = "ingress.controller/https-port"
|
||||
// AnnoIngressControllerHTTPPort define ingress controller listen port for http
|
||||
AnnoIngressControllerHTTPPort = "ingress.controller/http-port"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -70,20 +78,27 @@ type EnvMeta struct {
|
||||
const (
|
||||
// TagCommandType used for tag cli category
|
||||
TagCommandType = "commandType"
|
||||
|
||||
// TagCommandOrder defines the order
|
||||
TagCommandOrder = "commandOrder"
|
||||
|
||||
// TypeStart defines one category
|
||||
TypeStart = "Getting Started"
|
||||
|
||||
// TypeApp defines one category
|
||||
TypeApp = "Managing Applications"
|
||||
// TypeCap defines one category
|
||||
TypeCap = "Managing Capabilities"
|
||||
|
||||
// TypeCD defines workflow Management operations
|
||||
TypeCD = "Continuous Delivery"
|
||||
|
||||
// TypeExtension defines one category
|
||||
TypeExtension = "Managing Extension"
|
||||
|
||||
// TypeSystem defines one category
|
||||
TypeSystem = "System"
|
||||
// TypeDefinition defines one category
|
||||
TypeDefinition = "Managing Definitions"
|
||||
TypeSystem = "Others"
|
||||
|
||||
// TypePlugin defines one category used in Kubectl Plugin
|
||||
TypePlugin = "Plugin Command"
|
||||
// TypeUISchema defines one category
|
||||
TypeUISchema = "Managing UISchema"
|
||||
)
|
||||
|
||||
// LabelArg is the argument `label` of a definition
|
||||
|
||||
@@ -1,246 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.6.2
|
||||
name: appdeployments.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: AppDeployment
|
||||
listKind: AppDeploymentList
|
||||
plural: appdeployments
|
||||
shortNames:
|
||||
- appdeploy
|
||||
singular: appdeployment
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: AppDeployment is the Schema for the AppDeployment API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: AppDeploymentSpec defines how to describe an upgrade between
|
||||
different apps
|
||||
properties:
|
||||
appRevisions:
|
||||
description: AppRevision specifies AppRevision resources to and the
|
||||
rules to apply to them.
|
||||
items:
|
||||
description: AppRevision specifies an AppRevision resource to and
|
||||
the rules to apply to it.
|
||||
properties:
|
||||
placement:
|
||||
description: Placement defines the cluster placement rules for
|
||||
an app revision.
|
||||
items:
|
||||
description: ClusterPlacement defines the cluster placement
|
||||
rules for an app revision.
|
||||
properties:
|
||||
clusterSelector:
|
||||
description: ClusterSelector selects the cluster to deploy
|
||||
apps to. If not specified, it indicates the host cluster
|
||||
per se.
|
||||
properties:
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Labels defines the label selector to
|
||||
select the cluster.
|
||||
type: object
|
||||
name:
|
||||
description: Name is the name of the cluster.
|
||||
type: string
|
||||
type: object
|
||||
distribution:
|
||||
description: Distribution defines the replica distribution
|
||||
of an AppRevision to a cluster.
|
||||
properties:
|
||||
replicas:
|
||||
description: Replicas is the replica number.
|
||||
type: integer
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
revisionName:
|
||||
description: RevisionName is the name of the AppRevision.
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
traffic:
|
||||
description: Traffic defines the traffic rules to apply across revisions.
|
||||
properties:
|
||||
gateways:
|
||||
description: Gateways specifies the names of gateways that should
|
||||
apply these rules. Gateways in other namespaces may be referred
|
||||
to by `<gateway namespace>/<gateway name>`; specifying a gateway
|
||||
with no namespace qualifier is the same as specifying the AppDeployment's
|
||||
namespace.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
hosts:
|
||||
description: Hosts are the destination hosts to which traffic
|
||||
is being sent. Could be a DNS name with wildcard prefix or an
|
||||
IP address.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
http:
|
||||
description: HTTP defines the rules to match and split http traffoc
|
||||
across revisions.
|
||||
items:
|
||||
description: HTTPRule defines the rules to match and split http
|
||||
traffic across revisions.
|
||||
properties:
|
||||
match:
|
||||
description: Match defines the conditions to be satisfied
|
||||
for the rule to be activated. All conditions inside a
|
||||
single match block have AND semantics, while the list
|
||||
of match blocks have OR semantics. The rule is matched
|
||||
if any one of the match blocks succeed.
|
||||
items:
|
||||
description: HTTPMatchRequest specifies a set of criterion
|
||||
to be met in order for the rule to be applied to the
|
||||
HTTP request. For example, the following restricts the
|
||||
rule to match only requests where the URL path starts
|
||||
with /ratings/v2/ and the request contains a custom
|
||||
`end-user` header with value `jason`.
|
||||
properties:
|
||||
uri:
|
||||
description: URI defines how to match with an URI.
|
||||
properties:
|
||||
prefix:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
weightedTargets:
|
||||
description: WeightedTargets defines the revision targets
|
||||
to select and route traffic to.
|
||||
items:
|
||||
description: WeightedTarget defines the revision target
|
||||
to select and route traffic to.
|
||||
properties:
|
||||
componentName:
|
||||
description: ComponentName is the name of the component.
|
||||
Note that it is the original component name in the
|
||||
Application. No need to append revision.
|
||||
type: string
|
||||
port:
|
||||
description: Port is the port to route traffic towards.
|
||||
type: integer
|
||||
revisionName:
|
||||
description: RevisionName is the name of the app revision.
|
||||
type: string
|
||||
weight:
|
||||
description: Weight defines the proportion of traffic
|
||||
to be forwarded to the service version. (0-100).
|
||||
Sum of weights across destinations SHOULD BE ==
|
||||
100. If there is only one destination in a rule,
|
||||
the weight value is assumed to be 100.
|
||||
type: integer
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: AppDeploymentStatus defines the observed state of AppDeployment
|
||||
properties:
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition
|
||||
transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's
|
||||
last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition from
|
||||
one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True,
|
||||
False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each condition
|
||||
type may apply to a resource at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
phase:
|
||||
description: Phase shows the phase that the AppDeployment is undergoing.
|
||||
If Phase is Rolling, no update should be made to the spec.
|
||||
type: string
|
||||
placement:
|
||||
description: Placement shows the cluster placement results of the
|
||||
app revisions.
|
||||
items:
|
||||
description: PlacementStatus shows the cluster placement results
|
||||
of an app revision.
|
||||
properties:
|
||||
clusters:
|
||||
description: Clusters shows cluster placement results.
|
||||
items:
|
||||
description: ClusterPlacementStatus shows the placement results
|
||||
of a cluster.
|
||||
properties:
|
||||
clusterName:
|
||||
description: ClusterName indicates the name of the cluster
|
||||
to deploy apps to. If empty, it indicates the host cluster
|
||||
per se.
|
||||
type: string
|
||||
replicas:
|
||||
description: Replicas indicates the replica number of
|
||||
an app revision to deploy to a cluster.
|
||||
type: integer
|
||||
type: object
|
||||
type: array
|
||||
revisionName:
|
||||
description: RevisionName is the name of the AppRevision.
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -677,113 +677,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of
|
||||
AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of
|
||||
the app that we need to upgrade from. We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the
|
||||
Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time
|
||||
this condition transitioned from one status to
|
||||
another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about
|
||||
this condition's last transition from one status
|
||||
to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last
|
||||
transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently
|
||||
True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one
|
||||
of each condition type may apply to a resource
|
||||
at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working
|
||||
on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string
|
||||
that uniquely represent the last pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources We update this field
|
||||
only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the
|
||||
name of the app that we upgraded to We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that
|
||||
uniquely represent the new pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods
|
||||
upgraded by the rollout controller that have a Ready
|
||||
Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded
|
||||
by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application
|
||||
services
|
||||
@@ -2324,324 +2217,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout
|
||||
the resources The controller simply replace the old resources
|
||||
with the new one if there is no rollout plan involved
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition
|
||||
(included) will have the target resource specification
|
||||
while the rest still have the source resource This is
|
||||
designed for the operators to manually rollout Default
|
||||
is the the number of batches which will rollout all
|
||||
the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout
|
||||
process to automatically check certain metrics before
|
||||
complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics
|
||||
used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template
|
||||
object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an
|
||||
object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access
|
||||
statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to
|
||||
a container within a pod, this would take
|
||||
on a value like: "spec.containers{name}" (where
|
||||
"name" refers to the name of the container
|
||||
that triggered the event) or if no container
|
||||
name is specified "spec.containers[2]" (container
|
||||
with index 2 in this pod). This syntax is
|
||||
chosen only to have some well-defined way
|
||||
of referencing a part of an object. TODO:
|
||||
this design is not final and this field is
|
||||
subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which
|
||||
this reference is made, if any. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its
|
||||
size has to be exactly the same as the NumBatches (if
|
||||
set) The total number cannot exceed the targetSize or
|
||||
the size of the source resource We will IGNORE the last
|
||||
batch's replica field if it's a percentage since round
|
||||
errors can lead to inaccurate sum We highly recommend
|
||||
to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the
|
||||
each batch rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for
|
||||
the batch rollout to interact with an external
|
||||
process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference
|
||||
to external checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the
|
||||
expected http status code that we will accept
|
||||
as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for
|
||||
this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method,
|
||||
default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the
|
||||
batch rollout process to automatically check certain
|
||||
metrics before moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference
|
||||
to metrics used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows
|
||||
size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this
|
||||
metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric
|
||||
template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece
|
||||
of an object instead of an entire object,
|
||||
this string should contain a valid JSON/Go
|
||||
field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference
|
||||
is to a container within a pod, this
|
||||
would take on a value like: "spec.containers{name}"
|
||||
(where "name" refers to the name of
|
||||
the container that triggered the event)
|
||||
or if no container name is specified
|
||||
"spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is
|
||||
chosen only to have some well-defined
|
||||
way of referencing a part of an object.
|
||||
TODO: this design is not final and this
|
||||
field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More
|
||||
info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion
|
||||
to which this reference is made, if
|
||||
any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between
|
||||
instances upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number
|
||||
of pods that is unavailable during the upgrade.
|
||||
We will mark the batch as ready as long as there
|
||||
are less or equal number of pods unavailable than
|
||||
this number. default = 0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it
|
||||
is mutually exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to
|
||||
upgrade in this batch it can be an absolute number
|
||||
(ex: 5) or a percentage of total pods we will
|
||||
ignore the percentage of the last batch to just
|
||||
fill the gap it is mutually exclusive with the
|
||||
PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the
|
||||
rollout plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout
|
||||
to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected
|
||||
http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this
|
||||
webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default
|
||||
is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default
|
||||
is the same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
workflow:
|
||||
description: 'Workflow defines how to customize the control
|
||||
logic. If workflow is specified, Vela won''t apply any resource,
|
||||
@@ -2937,113 +2512,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of
|
||||
AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of
|
||||
the app that we need to upgrade from. We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the
|
||||
Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time
|
||||
this condition transitioned from one status to
|
||||
another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about
|
||||
this condition's last transition from one status
|
||||
to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last
|
||||
transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently
|
||||
True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one
|
||||
of each condition type may apply to a resource
|
||||
at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working
|
||||
on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string
|
||||
that uniquely represent the last pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources We update this field
|
||||
only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the
|
||||
name of the app that we upgraded to We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that
|
||||
uniquely represent the new pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods
|
||||
upgraded by the rollout controller that have a Ready
|
||||
Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded
|
||||
by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application
|
||||
services
|
||||
|
||||
@@ -485,82 +485,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app that we need to upgrade from. We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that uniquely represent the last pod template each workload type could use different ways to identify that so we cannot compare between resources We update this field only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of the app that we upgraded to We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely represent the new pod template each workload type could use different ways to identify that so we cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application services
|
||||
items:
|
||||
@@ -876,234 +800,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout the resources The controller simply replace the old resources with the new one if there is no rollout plan involved
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition (included) will have the target resource specification while the rest still have the source resource This is designed for the operators to manually rollout Default is the the number of batches which will rollout all the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout process to automatically check certain metrics before complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its size has to be exactly the same as the NumBatches (if set) The total number cannot exceed the targetSize or the size of the source resource We will IGNORE the last batch's replica field if it's a percentage since round errors can lead to inaccurate sum We highly recommend to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the each batch rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for the batch rollout to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the batch rollout process to automatically check certain metrics before moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between instances upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number of pods that is unavailable during the upgrade. We will mark the batch as ready as long as there are less or equal number of pods unavailable than this number. default = 0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it is mutually exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to upgrade in this batch it can be an absolute number (ex: 5) or a percentage of total pods we will ignore the percentage of the last batch to just fill the gap it is mutually exclusive with the PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the rollout plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default is the same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
workflow:
|
||||
description: 'Workflow defines how to customize the control logic. If workflow is specified, Vela won''t apply any resource, but provide rendered output in AppRevision. Workflow steps are executed in array order, and each step: - will have a context in annotation. - should mark "finish" phase in status.conditions.'
|
||||
properties:
|
||||
@@ -1311,82 +1007,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app that we need to upgrade from. We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that uniquely represent the last pod template each workload type could use different ways to identify that so we cannot compare between resources We update this field only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of the app that we upgraded to We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely represent the new pod template each workload type could use different ways to identify that so we cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application services
|
||||
items:
|
||||
|
||||
@@ -1,954 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.6.2
|
||||
name: approllouts.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: AppRollout
|
||||
listKind: AppRolloutList
|
||||
plural: approllouts
|
||||
shortNames:
|
||||
- approllout
|
||||
singular: approllout
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.rolloutStatus.rolloutTargetSize
|
||||
name: TARGET
|
||||
type: string
|
||||
- jsonPath: .status.rolloutStatus.upgradedReplicas
|
||||
name: UPGRADED
|
||||
type: string
|
||||
- jsonPath: .status.rolloutStatus.upgradedReadyReplicas
|
||||
name: READY
|
||||
type: string
|
||||
- jsonPath: .status.rolloutStatus.batchRollingState
|
||||
name: BATCH-STATE
|
||||
type: string
|
||||
- jsonPath: .status.rolloutStatus.rollingState
|
||||
name: ROLLING-STATE
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: AGE
|
||||
type: date
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: AppRollout is the Schema for the AppRollout API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: AppRolloutSpec defines how to describe an upgrade between
|
||||
different apps
|
||||
properties:
|
||||
componentList:
|
||||
description: 'The list of component to upgrade in the application.
|
||||
We only support single component application so far TODO: (RZ) Support
|
||||
multiple components in an application'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
revertOnDelete:
|
||||
description: RevertOnDelete revert the rollout when the rollout CR
|
||||
is deleted It will remove the target app from the kubernetes if
|
||||
it's set to true
|
||||
type: boolean
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout the resources
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition
|
||||
(included) will have the target resource specification while
|
||||
the rest still have the source resource This is designed for
|
||||
the operators to manually rollout Default is the the number
|
||||
of batches which will rollout all the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout process
|
||||
to automatically check certain metrics before complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics used
|
||||
for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead
|
||||
of an entire object, this string should contain a
|
||||
valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container
|
||||
within a pod, this would take on a value like: "spec.containers{name}"
|
||||
(where "name" refers to the name of the container
|
||||
that triggered the event) or if no container name
|
||||
is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to
|
||||
have some well-defined way of referencing a part of
|
||||
an object. TODO: this design is not final and this
|
||||
field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this
|
||||
reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its size has
|
||||
to be exactly the same as the NumBatches (if set) The total
|
||||
number cannot exceed the targetSize or the size of the source
|
||||
resource We will IGNORE the last batch's replica field if it's
|
||||
a percentage since round errors can lead to inaccurate sum We
|
||||
highly recommend to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the each batch
|
||||
rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for the batch
|
||||
rollout to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected
|
||||
http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default
|
||||
is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the batch rollout
|
||||
process to automatically check certain metrics before
|
||||
moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics
|
||||
used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template
|
||||
object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object
|
||||
instead of an entire object, this string should
|
||||
contain a valid JSON/Go field access statement,
|
||||
such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a
|
||||
container within a pod, this would take on a
|
||||
value like: "spec.containers{name}" (where "name"
|
||||
refers to the name of the container that triggered
|
||||
the event) or if no container name is specified
|
||||
"spec.containers[2]" (container with index 2
|
||||
in this pod). This syntax is chosen only to
|
||||
have some well-defined way of referencing a
|
||||
part of an object. TODO: this design is not
|
||||
final and this field is subject to change in
|
||||
the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which
|
||||
this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between instances
|
||||
upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number of
|
||||
pods that is unavailable during the upgrade. We will mark
|
||||
the batch as ready as long as there are less or equal
|
||||
number of pods unavailable than this number. default =
|
||||
0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it is mutually
|
||||
exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to upgrade
|
||||
in this batch it can be an absolute number (ex: 5) or
|
||||
a percentage of total pods we will ignore the percentage
|
||||
of the last batch to just fill the gap it is mutually
|
||||
exclusive with the PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the rollout
|
||||
plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout to
|
||||
interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected http
|
||||
status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default is the
|
||||
same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
sourceAppRevisionName:
|
||||
description: SourceAppRevisionName contains the name of the applicationRevision
|
||||
that we need to upgrade from. it can be empty only when the rolling
|
||||
is only a scale event
|
||||
type: string
|
||||
targetAppRevisionName:
|
||||
description: TargetAppRevisionName contains the name of the applicationRevision
|
||||
that we need to upgrade to.
|
||||
type: string
|
||||
required:
|
||||
- rolloutPlan
|
||||
- targetAppRevisionName
|
||||
type: object
|
||||
status:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app that
|
||||
we need to upgrade from. We will restart the rollout if this is
|
||||
not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status is
|
||||
rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition
|
||||
transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's
|
||||
last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition from
|
||||
one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True,
|
||||
False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each condition
|
||||
type may apply to a resource at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked it
|
||||
starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that uniquely
|
||||
represent the last pod template each workload type could use different
|
||||
ways to identify that so we cannot compare between resources We
|
||||
update this field only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of the
|
||||
app that we upgraded to We will restart the rollout if this is not
|
||||
the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does not
|
||||
change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does not
|
||||
change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely represent
|
||||
the new pod template each workload type could use different ways
|
||||
to identify that so we cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded
|
||||
by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by the
|
||||
rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.rolloutTargetSize
|
||||
name: TARGET
|
||||
type: string
|
||||
- jsonPath: .status.upgradedReplicas
|
||||
name: UPGRADED
|
||||
type: string
|
||||
- jsonPath: .status.upgradedReadyReplicas
|
||||
name: READY
|
||||
type: string
|
||||
- jsonPath: .status.batchRollingState
|
||||
name: BATCH-STATE
|
||||
type: string
|
||||
- jsonPath: .status.rollingState
|
||||
name: ROLLING-STATE
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: AGE
|
||||
type: date
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: AppRollout is the Schema for the AppRollout API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: AppRolloutSpec defines how to describe an upgrade between
|
||||
different apps
|
||||
properties:
|
||||
componentList:
|
||||
description: 'The list of component to upgrade in the application.
|
||||
We only support single component application so far TODO: (RZ) Support
|
||||
multiple components in an application'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
revertOnDelete:
|
||||
description: RevertOnDelete revert the failed rollout when the rollout
|
||||
CR is deleted It will revert the change back to the source version
|
||||
at once (not in batches) Default is false
|
||||
type: boolean
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout the resources
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition
|
||||
(included) will have the target resource specification while
|
||||
the rest still have the source resource This is designed for
|
||||
the operators to manually rollout Default is the the number
|
||||
of batches which will rollout all the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout process
|
||||
to automatically check certain metrics before complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics used
|
||||
for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead
|
||||
of an entire object, this string should contain a
|
||||
valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container
|
||||
within a pod, this would take on a value like: "spec.containers{name}"
|
||||
(where "name" refers to the name of the container
|
||||
that triggered the event) or if no container name
|
||||
is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to
|
||||
have some well-defined way of referencing a part of
|
||||
an object. TODO: this design is not final and this
|
||||
field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this
|
||||
reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its size has
|
||||
to be exactly the same as the NumBatches (if set) The total
|
||||
number cannot exceed the targetSize or the size of the source
|
||||
resource We will IGNORE the last batch's replica field if it's
|
||||
a percentage since round errors can lead to inaccurate sum We
|
||||
highly recommend to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the each batch
|
||||
rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for the batch
|
||||
rollout to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected
|
||||
http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default
|
||||
is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the batch rollout
|
||||
process to automatically check certain metrics before
|
||||
moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics
|
||||
used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template
|
||||
object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object
|
||||
instead of an entire object, this string should
|
||||
contain a valid JSON/Go field access statement,
|
||||
such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a
|
||||
container within a pod, this would take on a
|
||||
value like: "spec.containers{name}" (where "name"
|
||||
refers to the name of the container that triggered
|
||||
the event) or if no container name is specified
|
||||
"spec.containers[2]" (container with index 2
|
||||
in this pod). This syntax is chosen only to
|
||||
have some well-defined way of referencing a
|
||||
part of an object. TODO: this design is not
|
||||
final and this field is subject to change in
|
||||
the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which
|
||||
this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between instances
|
||||
upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number of
|
||||
pods that is unavailable during the upgrade. We will mark
|
||||
the batch as ready as long as there are less or equal
|
||||
number of pods unavailable than this number. default =
|
||||
0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it is mutually
|
||||
exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to upgrade
|
||||
in this batch it can be an absolute number (ex: 5) or
|
||||
a percentage of total pods we will ignore the percentage
|
||||
of the last batch to just fill the gap it is mutually
|
||||
exclusive with the PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the rollout
|
||||
plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout to
|
||||
interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected http
|
||||
status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default is the
|
||||
same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
sourceAppRevisionName:
|
||||
description: SourceAppRevisionName contains the name of the applicationConfiguration
|
||||
that we need to upgrade from. it can be empty only when it's the
|
||||
first time to deploy the application
|
||||
type: string
|
||||
targetAppRevisionName:
|
||||
description: TargetAppRevisionName contains the name of the applicationConfiguration
|
||||
that we need to upgrade to. Here we use an applicationConfiguration
|
||||
as a revision of an application, thus the name alone is suffice
|
||||
type: string
|
||||
required:
|
||||
- rolloutPlan
|
||||
- targetAppRevisionName
|
||||
type: object
|
||||
status:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app that
|
||||
we need to upgrade from. We will restart the rollout if this is
|
||||
not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status is
|
||||
rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition
|
||||
transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's
|
||||
last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition from
|
||||
one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True,
|
||||
False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each condition
|
||||
type may apply to a resource at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked it
|
||||
starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that uniquely
|
||||
represent the last pod template each workload type could use different
|
||||
ways to identify that so we cannot compare between resources We
|
||||
update this field only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of the
|
||||
app that we upgraded to We will restart the rollout if this is not
|
||||
the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does not
|
||||
change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does not
|
||||
change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely represent
|
||||
the new pod template each workload type could use different ways
|
||||
to identify that so we cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded
|
||||
by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by the
|
||||
rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.6.2
|
||||
name: clusters.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
kind: Cluster
|
||||
listKind: ClusterList
|
||||
plural: clusters
|
||||
singular: cluster
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Cluster is the Schema for the clusters API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ClusterSpec defines the desired state of Cluster
|
||||
properties:
|
||||
kubeconfigSecretRef:
|
||||
description: KubeconfigSecretRef specifies the reference to the secret
|
||||
that contains the kubeconfig in field `config`.
|
||||
properties:
|
||||
name:
|
||||
description: Name of a secret within the enclosing namespace.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: ClusterStatus defines the observed state of Cluster
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -22,6 +22,10 @@ spec:
|
||||
app: {{ template "kubevela.name" . }}-admission-create
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: create
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.admissionWebhooks.patch.image.repository }}:{{ .Values.admissionWebhooks.patch.image.tag }}
|
||||
|
||||
@@ -22,6 +22,10 @@ spec:
|
||||
app: {{ template "kubevela.name" . }}-admission-patch
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: patch
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.admissionWebhooks.patch.image.repository }}:{{ .Values.admissionWebhooks.patch.image.tag }}
|
||||
|
||||
@@ -198,6 +198,10 @@ spec:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: create
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.admissionWebhooks.patch.image.repository }}:{{ .Values.admissionWebhooks.patch.image.tag }}
|
||||
@@ -241,6 +245,10 @@ spec:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: patch
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.multicluster.clusterGateway.image.repository }}:{{ .Values.multicluster.clusterGateway.image.tag }}
|
||||
|
||||
@@ -32,21 +32,30 @@ spec:
|
||||
kind: "Ingress"
|
||||
metadata: {
|
||||
name: context.name
|
||||
annotations: "kubernetes.io/ingress.class": parameter.class
|
||||
annotations: {
|
||||
if !parameter.classInSpec {
|
||||
"kubernetes.io/ingress.class": parameter.class
|
||||
}
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
if parameter.classInSpec {
|
||||
ingressClassName: parameter.class
|
||||
}
|
||||
rules: [{
|
||||
host: parameter.domain
|
||||
http: paths: [
|
||||
for k, v in parameter.http {
|
||||
path: k
|
||||
pathType: "ImplementationSpecific"
|
||||
backend: service: {
|
||||
name: context.name
|
||||
port: number: v
|
||||
}
|
||||
},
|
||||
]
|
||||
}]
|
||||
}
|
||||
spec: rules: [{
|
||||
host: parameter.domain
|
||||
http: paths: [
|
||||
for k, v in parameter.http {
|
||||
path: k
|
||||
pathType: "ImplementationSpecific"
|
||||
backend: service: {
|
||||
name: context.name
|
||||
port: number: v
|
||||
}
|
||||
},
|
||||
]
|
||||
}]
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the domain you want to expose
|
||||
@@ -57,6 +66,9 @@ spec:
|
||||
|
||||
// +usage=Specify the class of ingress to use
|
||||
class: *"nginx" | string
|
||||
|
||||
// +usage=Set ingress class in '.spec.ingressClassName' instead of 'kubernetes.io/ingress.class' annotation.
|
||||
classInSpec: *false | bool
|
||||
}
|
||||
status:
|
||||
customStatus: |-
|
||||
|
||||
@@ -17,6 +17,27 @@ spec:
|
||||
)
|
||||
|
||||
parameter: {
|
||||
lark?: {
|
||||
// +usage=Specify the the lark url, you can either sepcify it in value or use secretRef
|
||||
url: {
|
||||
value: string
|
||||
} | {
|
||||
secretRef: {
|
||||
// +usage=name is the name of the secret
|
||||
name: string
|
||||
// +usage=key is the key in the secret
|
||||
key: string
|
||||
}
|
||||
}
|
||||
// +useage=Specify the message that you want to sent
|
||||
message: {
|
||||
// +usage=msg_type can be text, post, image, interactive, share_chat, share_user, audio, media, file, sticker
|
||||
msg_type: string
|
||||
// +usage=content should be json encode string
|
||||
content: string
|
||||
}
|
||||
}
|
||||
|
||||
dingding?: {
|
||||
// +usage=Specify the the dingding url, you can either sepcify it in value or use secretRef
|
||||
url: {
|
||||
@@ -207,6 +228,35 @@ spec:
|
||||
}
|
||||
}
|
||||
}
|
||||
lark: op.#Steps & {
|
||||
if parameter.lark != _|_ {
|
||||
if parameter.lark.url.value != _|_ {
|
||||
lark1: op.#Lark & {
|
||||
message: parameter.lark.message
|
||||
larkUrl: parameter.lark.url.value
|
||||
}
|
||||
}
|
||||
if parameter.lark.url.secretRef != _|_ && parameter.lark.url.value == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
kind: "Secret"
|
||||
metadata: {
|
||||
name: parameter.lark.url.secretRef.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.lark.url.secretRef.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
lark2: op.#Lark & {
|
||||
message: parameter.lark.message
|
||||
larkUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
slack: op.#Steps & {
|
||||
if parameter.slack != _|_ {
|
||||
if parameter.slack.url.value != _|_ {
|
||||
|
||||
@@ -109,10 +109,10 @@ spec:
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the labels in the workload
|
||||
labels?: {...}
|
||||
labels?: [string]: string
|
||||
|
||||
// +usage=Specify the annotations in the workload
|
||||
annotations?: {...}
|
||||
annotations?: [string]: string
|
||||
|
||||
// +usage=Specify number of tasks to run in parallel
|
||||
// +short=c
|
||||
|
||||
@@ -11,6 +11,10 @@ spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
mountsArray: {
|
||||
pvc: *[
|
||||
for v in parameter.volumeMounts.pvc {
|
||||
@@ -152,6 +156,12 @@ spec:
|
||||
{
|
||||
containerPort: v.port
|
||||
protocol: v.protocol
|
||||
if v.name != _|_ {
|
||||
name: v.name
|
||||
}
|
||||
if v.name == _|_ {
|
||||
name: "port-" + strconv.FormatInt(v.port, 10)
|
||||
}
|
||||
}}]
|
||||
}
|
||||
|
||||
@@ -262,6 +272,12 @@ spec:
|
||||
for v in parameter.ports if v.expose == true {
|
||||
port: v.port
|
||||
targetPort: v.port
|
||||
if v.name != _|_ {
|
||||
name: v.name
|
||||
}
|
||||
if v.name == _|_ {
|
||||
name: "port-" + strconv.FormatInt(v.port, 10)
|
||||
}
|
||||
},
|
||||
]
|
||||
outputs: {
|
||||
@@ -280,10 +296,10 @@ spec:
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the labels in the workload
|
||||
labels?: {...}
|
||||
labels?: [string]: string
|
||||
|
||||
// +usage=Specify the annotations in the workload
|
||||
annotations?: {...}
|
||||
annotations?: [string]: string
|
||||
|
||||
// +usage=Which image would you like to use for your service
|
||||
// +short=i
|
||||
@@ -304,6 +320,8 @@ spec:
|
||||
ports?: [...{
|
||||
// +usage=Number of port to expose on the pod's IP address
|
||||
port: int
|
||||
// +usage=Name of the port
|
||||
name?: string
|
||||
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
|
||||
protocol: *"TCP" | "UDP" | "SCTP"
|
||||
// +usage=Specify if the port should be exposed
|
||||
@@ -494,12 +512,7 @@ spec:
|
||||
replica: strconv.FormatInt(context.output.status.readyReplicas, 10)
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.status.replicas, 10)
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
message: ""
|
||||
}
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.spec.replicas, 10)
|
||||
healthPolicy: |-
|
||||
ready: {
|
||||
if context.output.status.readyReplicas == _|_ {
|
||||
@@ -509,12 +522,7 @@ spec:
|
||||
replica: context.output.status.readyReplicas
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
isHealth: context.output.status.replicas == ready.replica
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
isHealth: false
|
||||
}
|
||||
isHealth: context.output.spec.replicas == ready.replica
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
|
||||
@@ -405,12 +405,7 @@ spec:
|
||||
replica: strconv.FormatInt(context.output.status.readyReplicas, 10)
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.status.replicas, 10)
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
message: ""
|
||||
}
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.spec.replicas, 10)
|
||||
healthPolicy: |-
|
||||
ready: {
|
||||
if context.output.status.readyReplicas == _|_ {
|
||||
@@ -420,12 +415,7 @@ spec:
|
||||
replica: context.output.status.readyReplicas
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
isHealth: context.output.status.replicas == ready.replica
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
isHealth: false
|
||||
}
|
||||
isHealth: context.output.spec.replicas == ready.replica
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
|
||||
@@ -90,6 +90,10 @@ spec:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "kubevela.selectorLabels" . | nindent 8 }}
|
||||
annotations:
|
||||
prometheus.io/path: /metrics
|
||||
prometheus.io/port: "8080"
|
||||
prometheus.io/scrape: "true"
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
@@ -130,6 +134,7 @@ spec:
|
||||
{{ if .Values.multicluster.enabled }}
|
||||
- "--enable-cluster-gateway"
|
||||
{{ end }}
|
||||
- "--application-re-sync-period={{ .Values.controllerArgs.reSyncPeriod }}"
|
||||
image: {{ .Values.imageRegistry }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
|
||||
resources:
|
||||
|
||||
40
charts/vela-core/templates/velaql/endpoints.yaml
Normal file
40
charts/vela-core/templates/velaql/endpoints.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
apiVersion: "v1"
|
||||
kind: "ConfigMap"
|
||||
metadata:
|
||||
name: "service-endpoints-view"
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
data:
|
||||
template: |
|
||||
import (
|
||||
"vela/ql"
|
||||
)
|
||||
parameter: {
|
||||
appName: string
|
||||
appNs: string
|
||||
cluster?: string
|
||||
clusterNs?: string
|
||||
}
|
||||
resources: ql.#CollectServiceEndpoints & {
|
||||
app: {
|
||||
name: parameter.appName
|
||||
namespace: parameter.appNs
|
||||
filter: {
|
||||
if parameter.cluster != _|_ {
|
||||
cluster: parameter.cluster
|
||||
}
|
||||
if parameter.clusterNs != _|_ {
|
||||
clusterNamespace: parameter.clusterNs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if resources.err == _|_ {
|
||||
status: {
|
||||
endpoints: resources.list
|
||||
}
|
||||
}
|
||||
if resources.err != _|_ {
|
||||
status: {
|
||||
error: resources.err
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,9 @@ affinity: {}
|
||||
rbac:
|
||||
create: true
|
||||
|
||||
controllerArgs:
|
||||
reSyncPeriod: 5m
|
||||
|
||||
admissionWebhooks:
|
||||
enabled: true
|
||||
failurePolicy: Fail
|
||||
|
||||
@@ -677,113 +677,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of
|
||||
AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of
|
||||
the app that we need to upgrade from. We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the
|
||||
Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time
|
||||
this condition transitioned from one status to
|
||||
another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about
|
||||
this condition's last transition from one status
|
||||
to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last
|
||||
transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently
|
||||
True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one
|
||||
of each condition type may apply to a resource
|
||||
at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working
|
||||
on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string
|
||||
that uniquely represent the last pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources We update this field
|
||||
only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the
|
||||
name of the app that we upgraded to We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that
|
||||
uniquely represent the new pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods
|
||||
upgraded by the rollout controller that have a Ready
|
||||
Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded
|
||||
by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application
|
||||
services
|
||||
@@ -2324,324 +2217,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout
|
||||
the resources The controller simply replace the old resources
|
||||
with the new one if there is no rollout plan involved
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition
|
||||
(included) will have the target resource specification
|
||||
while the rest still have the source resource This is
|
||||
designed for the operators to manually rollout Default
|
||||
is the the number of batches which will rollout all
|
||||
the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout
|
||||
process to automatically check certain metrics before
|
||||
complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics
|
||||
used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template
|
||||
object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an
|
||||
object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access
|
||||
statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to
|
||||
a container within a pod, this would take
|
||||
on a value like: "spec.containers{name}" (where
|
||||
"name" refers to the name of the container
|
||||
that triggered the event) or if no container
|
||||
name is specified "spec.containers[2]" (container
|
||||
with index 2 in this pod). This syntax is
|
||||
chosen only to have some well-defined way
|
||||
of referencing a part of an object. TODO:
|
||||
this design is not final and this field is
|
||||
subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which
|
||||
this reference is made, if any. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its
|
||||
size has to be exactly the same as the NumBatches (if
|
||||
set) The total number cannot exceed the targetSize or
|
||||
the size of the source resource We will IGNORE the last
|
||||
batch's replica field if it's a percentage since round
|
||||
errors can lead to inaccurate sum We highly recommend
|
||||
to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the
|
||||
each batch rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for
|
||||
the batch rollout to interact with an external
|
||||
process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference
|
||||
to external checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the
|
||||
expected http status code that we will accept
|
||||
as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for
|
||||
this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method,
|
||||
default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the
|
||||
batch rollout process to automatically check certain
|
||||
metrics before moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference
|
||||
to metrics used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows
|
||||
size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this
|
||||
metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric
|
||||
template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece
|
||||
of an object instead of an entire object,
|
||||
this string should contain a valid JSON/Go
|
||||
field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference
|
||||
is to a container within a pod, this
|
||||
would take on a value like: "spec.containers{name}"
|
||||
(where "name" refers to the name of
|
||||
the container that triggered the event)
|
||||
or if no container name is specified
|
||||
"spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is
|
||||
chosen only to have some well-defined
|
||||
way of referencing a part of an object.
|
||||
TODO: this design is not final and this
|
||||
field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More
|
||||
info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion
|
||||
to which this reference is made, if
|
||||
any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between
|
||||
instances upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number
|
||||
of pods that is unavailable during the upgrade.
|
||||
We will mark the batch as ready as long as there
|
||||
are less or equal number of pods unavailable than
|
||||
this number. default = 0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it
|
||||
is mutually exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to
|
||||
upgrade in this batch it can be an absolute number
|
||||
(ex: 5) or a percentage of total pods we will
|
||||
ignore the percentage of the last batch to just
|
||||
fill the gap it is mutually exclusive with the
|
||||
PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the
|
||||
rollout plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout
|
||||
to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected
|
||||
http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this
|
||||
webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default
|
||||
is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default
|
||||
is the same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
workflow:
|
||||
description: 'Workflow defines how to customize the control
|
||||
logic. If workflow is specified, Vela won''t apply any resource,
|
||||
@@ -2937,113 +2512,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of
|
||||
AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of
|
||||
the app that we need to upgrade from. We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the
|
||||
Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time
|
||||
this condition transitioned from one status to
|
||||
another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about
|
||||
this condition's last transition from one status
|
||||
to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last
|
||||
transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently
|
||||
True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one
|
||||
of each condition type may apply to a resource
|
||||
at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working
|
||||
on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string
|
||||
that uniquely represent the last pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources We update this field
|
||||
only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the
|
||||
name of the app that we upgraded to We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that
|
||||
uniquely represent the new pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods
|
||||
upgraded by the rollout controller that have a Ready
|
||||
Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded
|
||||
by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application
|
||||
services
|
||||
|
||||
@@ -485,82 +485,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app that we need to upgrade from. We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that uniquely represent the last pod template each workload type could use different ways to identify that so we cannot compare between resources We update this field only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of the app that we upgraded to We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely represent the new pod template each workload type could use different ways to identify that so we cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application services
|
||||
items:
|
||||
@@ -876,234 +800,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout the resources The controller simply replace the old resources with the new one if there is no rollout plan involved
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition (included) will have the target resource specification while the rest still have the source resource This is designed for the operators to manually rollout Default is the the number of batches which will rollout all the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout process to automatically check certain metrics before complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its size has to be exactly the same as the NumBatches (if set) The total number cannot exceed the targetSize or the size of the source resource We will IGNORE the last batch's replica field if it's a percentage since round errors can lead to inaccurate sum We highly recommend to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the each batch rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for the batch rollout to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the batch rollout process to automatically check certain metrics before moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between instances upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number of pods that is unavailable during the upgrade. We will mark the batch as ready as long as there are less or equal number of pods unavailable than this number. default = 0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it is mutually exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to upgrade in this batch it can be an absolute number (ex: 5) or a percentage of total pods we will ignore the percentage of the last batch to just fill the gap it is mutually exclusive with the PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the rollout plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default is the same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
workflow:
|
||||
description: 'Workflow defines how to customize the control logic. If workflow is specified, Vela won''t apply any resource, but provide rendered output in AppRevision. Workflow steps are executed in array order, and each step: - will have a context in annotation. - should mark "finish" phase in status.conditions.'
|
||||
properties:
|
||||
@@ -1311,82 +1007,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app that we need to upgrade from. We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that uniquely represent the last pod template each workload type could use different ways to identify that so we cannot compare between resources We update this field only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of the app that we upgraded to We will restart the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources. This is determined once the initial spec verification and does not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely represent the new pod template each workload type could use different ways to identify that so we cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application services
|
||||
items:
|
||||
|
||||
@@ -32,21 +32,30 @@ spec:
|
||||
kind: "Ingress"
|
||||
metadata: {
|
||||
name: context.name
|
||||
annotations: "kubernetes.io/ingress.class": parameter.class
|
||||
annotations: {
|
||||
if !parameter.classInSpec {
|
||||
"kubernetes.io/ingress.class": parameter.class
|
||||
}
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
if parameter.classInSpec {
|
||||
ingressClassName: parameter.class
|
||||
}
|
||||
rules: [{
|
||||
host: parameter.domain
|
||||
http: paths: [
|
||||
for k, v in parameter.http {
|
||||
path: k
|
||||
pathType: "ImplementationSpecific"
|
||||
backend: service: {
|
||||
name: context.name
|
||||
port: number: v
|
||||
}
|
||||
},
|
||||
]
|
||||
}]
|
||||
}
|
||||
spec: rules: [{
|
||||
host: parameter.domain
|
||||
http: paths: [
|
||||
for k, v in parameter.http {
|
||||
path: k
|
||||
pathType: "ImplementationSpecific"
|
||||
backend: service: {
|
||||
name: context.name
|
||||
port: number: v
|
||||
}
|
||||
},
|
||||
]
|
||||
}]
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the domain you want to expose
|
||||
@@ -57,6 +66,9 @@ spec:
|
||||
|
||||
// +usage=Specify the class of ingress to use
|
||||
class: *"nginx" | string
|
||||
|
||||
// +usage=Set ingress class in '.spec.ingressClassName' instead of 'kubernetes.io/ingress.class' annotation.
|
||||
classInSpec: *false | bool
|
||||
}
|
||||
status:
|
||||
customStatus: |-
|
||||
|
||||
@@ -17,6 +17,27 @@ spec:
|
||||
)
|
||||
|
||||
parameter: {
|
||||
lark?: {
|
||||
// +usage=Specify the the lark url, you can either sepcify it in value or use secretRef
|
||||
url: {
|
||||
value: string
|
||||
} | {
|
||||
secretRef: {
|
||||
// +usage=name is the name of the secret
|
||||
name: string
|
||||
// +usage=key is the key in the secret
|
||||
key: string
|
||||
}
|
||||
}
|
||||
// +useage=Specify the message that you want to sent
|
||||
message: {
|
||||
// +usage=msg_type can be text, post, image, interactive, share_chat, share_user, audio, media, file, sticker
|
||||
msg_type: string
|
||||
// +usage=content should be json encode string
|
||||
content: string
|
||||
}
|
||||
}
|
||||
|
||||
dingding?: {
|
||||
// +usage=Specify the the dingding url, you can either sepcify it in value or use secretRef
|
||||
url: {
|
||||
@@ -207,6 +228,35 @@ spec:
|
||||
}
|
||||
}
|
||||
}
|
||||
lark: op.#Steps & {
|
||||
if parameter.lark != _|_ {
|
||||
if parameter.lark.url.value != _|_ {
|
||||
lark1: op.#Lark & {
|
||||
message: parameter.lark.message
|
||||
larkUrl: parameter.lark.url.value
|
||||
}
|
||||
}
|
||||
if parameter.lark.url.secretRef != _|_ && parameter.lark.url.value == _|_ {
|
||||
read: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
kind: "Secret"
|
||||
metadata: {
|
||||
name: parameter.lark.url.secretRef.name
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoded: base64.Decode(null, read.value.data[parameter.lark.url.secretRef.key])
|
||||
stringValue: op.#ConvertString & {bt: decoded}
|
||||
lark2: op.#Lark & {
|
||||
message: parameter.lark.message
|
||||
larkUrl: stringValue.str
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
slack: op.#Steps & {
|
||||
if parameter.slack != _|_ {
|
||||
if parameter.slack.url.value != _|_ {
|
||||
|
||||
@@ -109,10 +109,10 @@ spec:
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the labels in the workload
|
||||
labels?: {...}
|
||||
labels?: [string]: string
|
||||
|
||||
// +usage=Specify the annotations in the workload
|
||||
annotations?: {...}
|
||||
annotations?: [string]: string
|
||||
|
||||
// +usage=Specify number of tasks to run in parallel
|
||||
// +short=c
|
||||
|
||||
@@ -11,6 +11,10 @@ spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
mountsArray: {
|
||||
pvc: *[
|
||||
for v in parameter.volumeMounts.pvc {
|
||||
@@ -152,6 +156,12 @@ spec:
|
||||
{
|
||||
containerPort: v.port
|
||||
protocol: v.protocol
|
||||
if v.name != _|_ {
|
||||
name: v.name
|
||||
}
|
||||
if v.name == _|_ {
|
||||
name: "port-" + strconv.FormatInt(v.port, 10)
|
||||
}
|
||||
}}]
|
||||
}
|
||||
|
||||
@@ -262,6 +272,12 @@ spec:
|
||||
for v in parameter.ports if v.expose == true {
|
||||
port: v.port
|
||||
targetPort: v.port
|
||||
if v.name != _|_ {
|
||||
name: v.name
|
||||
}
|
||||
if v.name == _|_ {
|
||||
name: "port-" + strconv.FormatInt(v.port, 10)
|
||||
}
|
||||
},
|
||||
]
|
||||
outputs: {
|
||||
@@ -280,10 +296,10 @@ spec:
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the labels in the workload
|
||||
labels?: {...}
|
||||
labels?: [string]: string
|
||||
|
||||
// +usage=Specify the annotations in the workload
|
||||
annotations?: {...}
|
||||
annotations?: [string]: string
|
||||
|
||||
// +usage=Which image would you like to use for your service
|
||||
// +short=i
|
||||
@@ -304,6 +320,8 @@ spec:
|
||||
ports?: [...{
|
||||
// +usage=Number of port to expose on the pod's IP address
|
||||
port: int
|
||||
// +usage=Name of the port
|
||||
name?: string
|
||||
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
|
||||
protocol: *"TCP" | "UDP" | "SCTP"
|
||||
// +usage=Specify if the port should be exposed
|
||||
@@ -494,12 +512,7 @@ spec:
|
||||
replica: strconv.FormatInt(context.output.status.readyReplicas, 10)
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.status.replicas, 10)
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
message: ""
|
||||
}
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.spec.replicas, 10)
|
||||
healthPolicy: |-
|
||||
ready: {
|
||||
if context.output.status.readyReplicas == _|_ {
|
||||
@@ -509,12 +522,7 @@ spec:
|
||||
replica: context.output.status.readyReplicas
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
isHealth: context.output.status.replicas == ready.replica
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
isHealth: false
|
||||
}
|
||||
isHealth: context.output.spec.replicas == ready.replica
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
|
||||
@@ -405,12 +405,7 @@ spec:
|
||||
replica: strconv.FormatInt(context.output.status.readyReplicas, 10)
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.status.replicas, 10)
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
message: ""
|
||||
}
|
||||
message: "Ready:" + ready.replica + "/" + strconv.FormatInt(context.output.spec.replicas, 10)
|
||||
healthPolicy: |-
|
||||
ready: {
|
||||
if context.output.status.readyReplicas == _|_ {
|
||||
@@ -420,12 +415,7 @@ spec:
|
||||
replica: context.output.status.readyReplicas
|
||||
}
|
||||
}
|
||||
if context.output.status.replicas != _|_ {
|
||||
isHealth: context.output.status.replicas == ready.replica
|
||||
}
|
||||
if context.output.status.replicas == _|_ {
|
||||
isHealth: false
|
||||
}
|
||||
isHealth: context.output.spec.replicas == ready.replica
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
|
||||
@@ -92,6 +92,10 @@ spec:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "kubevela.selectorLabels" . | nindent 8 }}
|
||||
annotations:
|
||||
prometheus.io/path: /metrics
|
||||
prometheus.io/port: "8080"
|
||||
prometheus.io/scrape: "true"
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
|
||||
@@ -30,13 +30,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/klog/v2/klogr"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
|
||||
ctrlClient "github.com/oam-dev/kubevela/pkg/client"
|
||||
standardcontroller "github.com/oam-dev/kubevela/pkg/controller"
|
||||
commonconfig "github.com/oam-dev/kubevela/pkg/controller/common"
|
||||
oamcontroller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
@@ -74,7 +73,6 @@ func main() {
|
||||
var healthAddr string
|
||||
var disableCaps string
|
||||
var storageDriver string
|
||||
var syncPeriod time.Duration
|
||||
var applyOnceOnly string
|
||||
var qps float64
|
||||
var burst int
|
||||
@@ -110,8 +108,8 @@ func main() {
|
||||
"For the purpose of some production environment that workload or trait should not be affected if no spec change, available options: on, off, force.")
|
||||
flag.StringVar(&disableCaps, "disable-caps", "", "To be disabled builtin capability list.")
|
||||
flag.StringVar(&storageDriver, "storage-driver", "Local", "Application file save to the storage driver")
|
||||
flag.DurationVar(&syncPeriod, "informer-re-sync-interval", 60*time.Minute,
|
||||
"controller shared informer lister full re-sync period")
|
||||
flag.DurationVar(&commonconfig.ApplicationReSyncPeriod, "application-re-sync-period", 5*time.Minute,
|
||||
"Re-sync period for application to re-sync, also known as the state-keep interval.")
|
||||
flag.DurationVar(&commonconfig.ReconcileTimeout, "reconcile-timeout", time.Minute*3,
|
||||
"the timeout for controller reconcile")
|
||||
flag.StringVar(&oam.SystemDefinitonNamespace, "system-definition-namespace", "vela-system", "define the namespace of the system-level definition")
|
||||
@@ -131,6 +129,8 @@ func main() {
|
||||
flag.DurationVar(&retryPeriod, "leader-election-retry-period", 2*time.Second,
|
||||
"The duration the LeaderElector clients should wait between tries of actions")
|
||||
flag.BoolVar(&enableClusterGateway, "enable-cluster-gateway", false, "Enable cluster-gateway to use multicluster, disabled by default.")
|
||||
flag.BoolVar(&controllerArgs.EnableCompatibility, "enable-asi-compatibility", false, "enable compatibility for asi")
|
||||
standardcontroller.AddOptimizeFlags()
|
||||
|
||||
flag.Parse()
|
||||
// setup logging
|
||||
@@ -205,12 +205,16 @@ func main() {
|
||||
Port: webhookPort,
|
||||
CertDir: certDir,
|
||||
HealthProbeBindAddress: healthAddr,
|
||||
SyncPeriod: &syncPeriod,
|
||||
LeaderElectionResourceLock: leaderElectionResourceLock,
|
||||
LeaseDuration: &leaseDuration,
|
||||
RenewDeadline: &renewDeadline,
|
||||
RetryPeriod: &retryPeriod,
|
||||
ClientDisableCacheFor: []client.Object{&appsv1.ControllerRevision{}},
|
||||
// SyncPeriod is configured with default value, aka. 10h. First, controller-runtime does not
|
||||
// recommend use it as a time trigger, instead, it is expected to work for failure tolerance
|
||||
// of controller-runtime. Additionally, set this value will affect not only application
|
||||
// controller but also all other controllers like definition controller. Therefore, for
|
||||
// functionalities like state-keep, they should be invented in other ways.
|
||||
NewClient: ctrlClient.DefaultNewControllerClient,
|
||||
})
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Unable to create a controller manager")
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/plugin/cli"
|
||||
"github.com/oam-dev/kubevela/references/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -9,6 +9,7 @@ This guide helps you get started developing KubeVela.
|
||||
3. ginkgo 1.14.0+ (just for [E2E test](./developer-guide.md#e2e-test))
|
||||
4. golangci-lint 1.38.0+, it will install automatically if you run `make`, you can [install it manually](https://golangci-lint.run/usage/install/#local-installation) if the installation is too slow.
|
||||
5. kubebuilder v3.1.0+ and you need to manually install the dependency tools for unit test.
|
||||
6. [CUE binary](https://github.com/cue-lang/cue/releases) v0.3.0+
|
||||
|
||||
<details>
|
||||
<summary>Install Kubebuilder manually</summary>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
| apply-once-only | string | false | For the purpose of some production environment that workload or trait should not be affected if no spec change, available options: on, off, force. |
|
||||
| disable-caps | string | "" | To be disabled builtin capability list. |
|
||||
| storage-driver | string | Local | Application file save to the storage driver |
|
||||
| informer-re-sync-interval | time | 1h | Controller shared informer lister full re-sync period, the interval between two routinely reconciles for one CR (like Application) if no changes made to it. |
|
||||
| application-re-sync-period | time | 5m | Re-sync period for application to re-sync, also known as the state-keep interval. |
|
||||
| reconcile-timeout | time | 3m | The timeout for controller reconcile. |
|
||||
| system-definition-namespace | string | vela-system | define the namespace of the system-level definition |
|
||||
| concurrent-reconciles | int | 4 | The concurrent reconcile number of the controller. You can increase the degree of concurrency if a large number of CPU cores are provided to the controller. |
|
||||
|
||||
@@ -504,6 +504,31 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/payload_types": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "list application trigger payload types",
|
||||
"operationId": "ListPayloadTypes",
|
||||
"responses": {
|
||||
"200": {},
|
||||
"400": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bcode.Bcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/{name}": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
@@ -1707,6 +1732,133 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/{name}/triggers": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "list application triggers",
|
||||
"operationId": "listApplicationTriggers",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "identifier of the application ",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.ListApplicationTriggerResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bcode.Bcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "create one application trigger",
|
||||
"operationId": "createApplicationTrigger",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "identifier of the application ",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.CreateApplicationTriggerRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.ApplicationTriggerBase"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bcode.Bcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/{name}/triggers/{token}": {
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "delete one application trigger",
|
||||
"operationId": "deleteApplicationTrigger",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "identifier of the application ",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "identifier of the trigger",
|
||||
"name": "token",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.EmptyResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bcode.Bcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/{name}/workflows": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
@@ -2738,9 +2890,9 @@
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"workflowstep",
|
||||
"component",
|
||||
"trait"
|
||||
"trait",
|
||||
"workflowstep"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "query the definition type",
|
||||
@@ -2817,7 +2969,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/enabled-addon": {
|
||||
"/api/v1/enabled_addon": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
@@ -3302,6 +3454,52 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/webhook/{token}": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"tags": [
|
||||
"webhook"
|
||||
],
|
||||
"summary": "handle application webhook request",
|
||||
"operationId": "handleApplicationWebhook",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "identifier of the application ",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.HandleApplicationTriggerWebhookRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.ApplicationDeployResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bcode.Bcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/namespaces/{namespace}/applications/{appname}": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
@@ -3424,6 +3622,8 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"*v1.ApplicationTriggerBase": {},
|
||||
"*v1.EmptyResponse": {},
|
||||
"addon.Dependency": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@@ -3604,11 +3804,11 @@
|
||||
},
|
||||
"common.AppRolloutStatus": {
|
||||
"required": [
|
||||
"batchRollingState",
|
||||
"currentBatch",
|
||||
"upgradedReadyReplicas",
|
||||
"rollingState",
|
||||
"upgradedReadyReplicas",
|
||||
"currentBatch",
|
||||
"upgradedReplicas",
|
||||
"batchRollingState",
|
||||
"lastTargetAppRevision"
|
||||
],
|
||||
"properties": {
|
||||
@@ -4204,6 +4404,9 @@
|
||||
"applyAppConfig": {
|
||||
"type": "string"
|
||||
},
|
||||
"codeInfo": {
|
||||
"$ref": "#/definitions/model.CodeInfo"
|
||||
},
|
||||
"createTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
@@ -4214,6 +4417,9 @@
|
||||
"envName": {
|
||||
"type": "string"
|
||||
},
|
||||
"imageInfo": {
|
||||
"$ref": "#/definitions/model.ImageInfo"
|
||||
},
|
||||
"note": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -4290,8 +4496,8 @@
|
||||
},
|
||||
"model.Cluster": {
|
||||
"required": [
|
||||
"updateTime",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"name",
|
||||
"alias",
|
||||
"description",
|
||||
@@ -4355,6 +4561,86 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.CodeInfo": {
|
||||
"properties": {
|
||||
"branch": {
|
||||
"type": "string"
|
||||
},
|
||||
"commit": {
|
||||
"type": "string"
|
||||
},
|
||||
"user": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.ImageInfo": {
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"repository": {
|
||||
"$ref": "#/definitions/model.ImageRepository"
|
||||
},
|
||||
"resource": {
|
||||
"$ref": "#/definitions/model.ImageResource"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.ImageRepository": {
|
||||
"required": [
|
||||
"name",
|
||||
"namespace",
|
||||
"fullName",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"createTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"fullName": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.ImageResource": {
|
||||
"required": [
|
||||
"digest",
|
||||
"tag",
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"createTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"digest": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.JSONStruct": {
|
||||
"type": "object"
|
||||
},
|
||||
@@ -4601,6 +4887,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AddonBaseStatus": {
|
||||
"required": [
|
||||
"name",
|
||||
"phase"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AddonDefinition": {
|
||||
"properties": {
|
||||
"description": {
|
||||
@@ -4614,6 +4914,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AddonInfo": {
|
||||
"required": [
|
||||
"Meta",
|
||||
"registryName"
|
||||
],
|
||||
"properties": {
|
||||
"Meta": {
|
||||
"$ref": "#/definitions/addon.Meta"
|
||||
},
|
||||
"registryName": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.AddonRegistry": {
|
||||
"required": [
|
||||
"name"
|
||||
@@ -4716,9 +5030,15 @@
|
||||
"force"
|
||||
],
|
||||
"properties": {
|
||||
"codeInfo": {
|
||||
"$ref": "#/definitions/model.CodeInfo"
|
||||
},
|
||||
"force": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"imageInfo": {
|
||||
"$ref": "#/definitions/model.ImageInfo"
|
||||
},
|
||||
"note": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -4732,16 +5052,17 @@
|
||||
},
|
||||
"v1.ApplicationDeployResponse": {
|
||||
"required": [
|
||||
"createTime",
|
||||
"version",
|
||||
"status",
|
||||
"reason",
|
||||
"deployUser",
|
||||
"note",
|
||||
"envName",
|
||||
"triggerType"
|
||||
"triggerType",
|
||||
"version",
|
||||
"createTime"
|
||||
],
|
||||
"properties": {
|
||||
"codeInfo": {
|
||||
"$ref": "#/definitions/model.CodeInfo"
|
||||
},
|
||||
"createTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
@@ -4752,6 +5073,9 @@
|
||||
"envName": {
|
||||
"type": "string"
|
||||
},
|
||||
"imageInfo": {
|
||||
"$ref": "#/definitions/model.ImageInfo"
|
||||
},
|
||||
"note": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -4829,13 +5153,14 @@
|
||||
"createTime",
|
||||
"version",
|
||||
"status",
|
||||
"reason",
|
||||
"deployUser",
|
||||
"note",
|
||||
"envName",
|
||||
"triggerType"
|
||||
],
|
||||
"properties": {
|
||||
"codeInfo": {
|
||||
"$ref": "#/definitions/model.CodeInfo"
|
||||
},
|
||||
"createTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
@@ -4846,6 +5171,9 @@
|
||||
"envName": {
|
||||
"type": "string"
|
||||
},
|
||||
"imageInfo": {
|
||||
"$ref": "#/definitions/model.ImageInfo"
|
||||
},
|
||||
"note": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -4991,6 +5319,51 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ApplicationTriggerBase": {
|
||||
"required": [
|
||||
"name",
|
||||
"workflowName",
|
||||
"type",
|
||||
"payloadType",
|
||||
"token",
|
||||
"createTime",
|
||||
"updateTime"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
"type": "string"
|
||||
},
|
||||
"componentName": {
|
||||
"type": "string"
|
||||
},
|
||||
"createTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"payloadType": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"updateTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"workflowName": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ClusterBase": {
|
||||
"required": [
|
||||
"name",
|
||||
@@ -5339,6 +5712,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.CreateApplicationTriggerRequest": {
|
||||
"required": [
|
||||
"name",
|
||||
"workflowName",
|
||||
"type",
|
||||
"payloadType"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
"type": "string"
|
||||
},
|
||||
"componentName": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"payloadType": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"workflowName": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.CreateCloudClusterRequest": {
|
||||
"required": [
|
||||
"accessKeyID",
|
||||
@@ -5637,10 +6041,10 @@
|
||||
"v1.DetailAddonResponse": {
|
||||
"required": [
|
||||
"name",
|
||||
"description",
|
||||
"invisible",
|
||||
"version",
|
||||
"description",
|
||||
"icon",
|
||||
"invisible",
|
||||
"schema",
|
||||
"uiSchema",
|
||||
"definitions"
|
||||
@@ -5682,6 +6086,9 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"registryName": {
|
||||
"type": "string"
|
||||
},
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -5707,13 +6114,13 @@
|
||||
},
|
||||
"v1.DetailApplicationResponse": {
|
||||
"required": [
|
||||
"name",
|
||||
"alias",
|
||||
"project",
|
||||
"description",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"icon",
|
||||
"name",
|
||||
"policies",
|
||||
"envBindings",
|
||||
"status",
|
||||
@@ -5775,20 +6182,20 @@
|
||||
},
|
||||
"v1.DetailClusterResponse": {
|
||||
"required": [
|
||||
"apiServerURL",
|
||||
"icon",
|
||||
"createTime",
|
||||
"status",
|
||||
"provider",
|
||||
"reason",
|
||||
"alias",
|
||||
"description",
|
||||
"labels",
|
||||
"dashboardURL",
|
||||
"kubeConfig",
|
||||
"updateTime",
|
||||
"createTime",
|
||||
"name",
|
||||
"kubeConfigSecret",
|
||||
"alias",
|
||||
"icon",
|
||||
"reason",
|
||||
"apiServerURL",
|
||||
"dashboardURL",
|
||||
"name",
|
||||
"description",
|
||||
"labels",
|
||||
"resourceInfo"
|
||||
],
|
||||
"properties": {
|
||||
@@ -5846,13 +6253,13 @@
|
||||
},
|
||||
"v1.DetailComponentResponse": {
|
||||
"required": [
|
||||
"type",
|
||||
"createTime",
|
||||
"creator",
|
||||
"updateTime",
|
||||
"name",
|
||||
"alias",
|
||||
"appPrimaryKey"
|
||||
"updateTime",
|
||||
"appPrimaryKey",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -5983,16 +6390,16 @@
|
||||
},
|
||||
"v1.DetailRevisionResponse": {
|
||||
"required": [
|
||||
"reason",
|
||||
"status",
|
||||
"workflowName",
|
||||
"triggerType",
|
||||
"createTime",
|
||||
"version",
|
||||
"deployUser",
|
||||
"note",
|
||||
"workflowName",
|
||||
"updateTime",
|
||||
"version",
|
||||
"reason",
|
||||
"triggerType",
|
||||
"envName",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"appPrimaryKey"
|
||||
],
|
||||
"properties": {
|
||||
@@ -6002,6 +6409,9 @@
|
||||
"applyAppConfig": {
|
||||
"type": "string"
|
||||
},
|
||||
"codeInfo": {
|
||||
"$ref": "#/definitions/model.CodeInfo"
|
||||
},
|
||||
"createTime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
@@ -6012,6 +6422,9 @@
|
||||
"envName": {
|
||||
"type": "string"
|
||||
},
|
||||
"imageInfo": {
|
||||
"$ref": "#/definitions/model.ImageInfo"
|
||||
},
|
||||
"note": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -6041,9 +6454,9 @@
|
||||
},
|
||||
"v1.DetailTargetResponse": {
|
||||
"required": [
|
||||
"name",
|
||||
"createTime",
|
||||
"updateTime"
|
||||
"updateTime",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -6137,14 +6550,14 @@
|
||||
},
|
||||
"v1.DetailWorkflowResponse": {
|
||||
"required": [
|
||||
"alias",
|
||||
"description",
|
||||
"default",
|
||||
"updateTime",
|
||||
"createTime",
|
||||
"name",
|
||||
"description",
|
||||
"enable",
|
||||
"default",
|
||||
"alias",
|
||||
"envName",
|
||||
"createTime"
|
||||
"updateTime"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -6323,6 +6736,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.HandleApplicationTriggerWebhookRequest": {
|
||||
"properties": {
|
||||
"codeInfo": {
|
||||
"$ref": "#/definitions/model.CodeInfo"
|
||||
},
|
||||
"upgrade": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/model.JSONStruct"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ListAddonRegistryResponse": {
|
||||
"required": [
|
||||
"registries"
|
||||
@@ -6344,7 +6770,7 @@
|
||||
"addons": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/addon.Meta"
|
||||
"$ref": "#/definitions/v1.AddonInfo"
|
||||
}
|
||||
},
|
||||
"message": {
|
||||
@@ -6391,6 +6817,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ListApplicationTriggerResponse": {
|
||||
"required": [
|
||||
"triggers"
|
||||
],
|
||||
"properties": {
|
||||
"triggers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.ApplicationTriggerBase"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ListCloudClusterCreationResponse": {
|
||||
"required": [
|
||||
"creations"
|
||||
|
||||
@@ -14,8 +14,12 @@ spec:
|
||||
ports:
|
||||
- port: 8000
|
||||
- port: 8001
|
||||
name: exposeport1
|
||||
protocol: UDP
|
||||
expose: true
|
||||
expose: true
|
||||
- port: 8002
|
||||
protocol: UDP
|
||||
expose: true
|
||||
volumeMounts:
|
||||
pvc:
|
||||
- name: my-mount
|
||||
|
||||
74
docs/examples/envbinding/envpatch-with-wild-match.yaml
Normal file
74
docs/examples/envbinding/envpatch-with-wild-match.yaml
Normal file
@@ -0,0 +1,74 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: example-app
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: podinfo
|
||||
type: webservice
|
||||
properties:
|
||||
image: stefanprodan/podinfo
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
- name: hello-world
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
- name: nginx
|
||||
type: worker
|
||||
properties:
|
||||
image: nginx
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
policies:
|
||||
- name: example-multi-env-policy
|
||||
type: env-binding
|
||||
properties:
|
||||
envs:
|
||||
- name: test
|
||||
placement:
|
||||
clusterSelector:
|
||||
name: local
|
||||
namespaceSelector:
|
||||
name: test
|
||||
patch:
|
||||
components:
|
||||
- name: podinfo # patch to component named podinfo, no type check
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 2
|
||||
|
||||
- name: staging
|
||||
placement:
|
||||
clusterSelector:
|
||||
name: remote
|
||||
patch:
|
||||
components: # patch to all webservice components
|
||||
- type: webservice
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 3
|
||||
|
||||
- name: prod
|
||||
placement:
|
||||
clusterSelector:
|
||||
name: remote
|
||||
namespaceSelector:
|
||||
name: prod
|
||||
patch:
|
||||
components: # patch to all components
|
||||
- traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 3
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: app-aws-s3
|
||||
spec:
|
||||
components:
|
||||
- name: sample-s3
|
||||
type: aws-s3
|
||||
properties:
|
||||
bucket: vela-website-202110191745
|
||||
acl: private
|
||||
|
||||
writeConnectionSecretToRef:
|
||||
name: s3-conn
|
||||
@@ -29,6 +29,12 @@ spec:
|
||||
msgtype: text
|
||||
text:
|
||||
content: Hello KubeVela
|
||||
lark:
|
||||
url:
|
||||
value: <lark-url>
|
||||
message:
|
||||
msg_type: "text"
|
||||
content: "{\"text\":\" Hello KubeVela\"}"
|
||||
slack:
|
||||
url:
|
||||
# use url in secret
|
||||
|
||||
@@ -47,13 +47,13 @@ var _ = Describe("Addon Test", func() {
|
||||
It("Enable addon test-addon", func() {
|
||||
output, err := e2e.Exec("vela addon enable test-addon")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).To(ContainSubstring("Successfully enable addon"))
|
||||
Expect(output).To(ContainSubstring("enabled Successfully."))
|
||||
})
|
||||
|
||||
It("Upgrade addon test-addon", func() {
|
||||
output, err := e2e.Exec("vela addon upgrade test-addon")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).To(ContainSubstring("Successfully enable addon"))
|
||||
Expect(output).To(ContainSubstring("enabled Successfully."))
|
||||
})
|
||||
|
||||
It("Disable addon test-addon", func() {
|
||||
@@ -68,7 +68,7 @@ var _ = Describe("Addon Test", func() {
|
||||
It("Enable addon with input", func() {
|
||||
output, err := e2e.LongTimeExec("vela addon enable test-addon example=redis", 300*time.Second)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).To(ContainSubstring("Successfully enable addon"))
|
||||
Expect(output).To(ContainSubstring("enabled Successfully."))
|
||||
})
|
||||
|
||||
It("Disable addon test-addon", func() {
|
||||
|
||||
@@ -119,25 +119,25 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
Context("Test kubectl vela show", func() {
|
||||
It("Test show componentDefinition reference", func() {
|
||||
cdName := "test-show-task"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", cdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", cdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring(showCdResult))
|
||||
})
|
||||
It("Test show traitDefinition reference", func() {
|
||||
tdName := "test-sidecar"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", tdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring(showTdResult))
|
||||
})
|
||||
It("Test show componentDefinition use Helm Charts as Workload", func() {
|
||||
cdName := "test-webapp-chart"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", cdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", cdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring("Properties"))
|
||||
})
|
||||
It("Test show componentDefinition def with raw Kube mode", func() {
|
||||
cdName := "kube-worker"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", cdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", cdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring("image"))
|
||||
Expect(output).Should(ContainSubstring("The value will be applied to fields: [spec.template.spec.containers[0].image]."))
|
||||
@@ -146,26 +146,26 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
})
|
||||
It("Test show traitDefinition def with raw Kube mode", func() {
|
||||
tdName := "service-kube"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", tdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring("targetPort"))
|
||||
Expect(output).Should(ContainSubstring("target port num for service provider."))
|
||||
})
|
||||
It("Test show traitDefinition def with cue single map parameter", func() {
|
||||
tdName := "annotations"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", tdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring("map[string]string"))
|
||||
})
|
||||
It("Test show webservice def with cue ignore annotation ", func() {
|
||||
tdName := "webservice"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", tdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).ShouldNot(ContainSubstring("addRevisionLabel"))
|
||||
})
|
||||
It("Test show webservice def with cue ignore annotation ", func() {
|
||||
tdName := "mywebservice"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", tdName))
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).ShouldNot(ContainSubstring("addRevisionLabel"))
|
||||
Expect(output).ShouldNot(ContainSubstring("mySecretKey"))
|
||||
|
||||
1
go.mod
1
go.mod
@@ -70,7 +70,6 @@ require (
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
gotest.tools v2.2.0+incompatible
|
||||
helm.sh/helm/v3 v3.6.1
|
||||
istio.io/api v0.0.0-20210128181506-0c4b8e54850f
|
||||
istio.io/client-go v0.0.0-20210128182905-ee2edd059e02
|
||||
k8s.io/api v0.22.1
|
||||
k8s.io/apiextensions-apiserver v0.22.1
|
||||
|
||||
31
hack/docgen/REDAME.md
Normal file
31
hack/docgen/REDAME.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# KubeVela.io CLI Reference Doc
|
||||
|
||||
1. step up these two projects in the same folder.
|
||||
|
||||
```shell
|
||||
$ tree -L 1
|
||||
.
|
||||
├── kubevela
|
||||
└── kubevela.io
|
||||
```
|
||||
|
||||
2. Run generate command in kubevela root dir.
|
||||
|
||||
```shell
|
||||
cd kubevela/
|
||||
go run ./hack/docgen/gen.go
|
||||
```
|
||||
|
||||
3. Update more docs such as i18n zh
|
||||
|
||||
```shell
|
||||
$ go run ./hack/docgen/gen.go ../kubevela.io/i18n/zh/docusaurus-plugin-content-docs/current/cli
|
||||
scanning rootPath of CLI docs for replace: ../kubevela.io/i18n/zh/docusaurus-plugin-content-docs/current/cli
|
||||
```
|
||||
|
||||
4. Then you can check the difference in kubevela.io.
|
||||
|
||||
```shell
|
||||
cd ../kubevela.io
|
||||
git status
|
||||
```
|
||||
@@ -17,16 +17,156 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/references/cli"
|
||||
|
||||
"github.com/spf13/cobra/doc"
|
||||
)
|
||||
|
||||
// PrintCLIByTag print custom defined index
|
||||
func PrintCLIByTag(cmd *cobra.Command, all []*cobra.Command, tag string) string {
|
||||
var result string
|
||||
pl := cli.PrintList{}
|
||||
for _, c := range all {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
if val, ok := c.Annotations[types.TagCommandType]; !ok || val != tag {
|
||||
continue
|
||||
}
|
||||
cname := cmd.Name() + " " + c.Name()
|
||||
link := cname
|
||||
link = strings.Replace(link, " ", "_", -1)
|
||||
pl = append(pl, cli.Printable{Order: c.Annotations[types.TagCommandOrder], Long: fmt.Sprintf("* [%s](%s)\t - %s\n", cname, link, c.Long)})
|
||||
|
||||
}
|
||||
|
||||
sort.Sort(pl)
|
||||
|
||||
for _, v := range pl {
|
||||
result += v.Long
|
||||
}
|
||||
result += "\n"
|
||||
return result
|
||||
}
|
||||
|
||||
// GenMarkdownTreeForIndex will generate the markdown doc for vela index
|
||||
func GenMarkdownTreeForIndex(cmd *cobra.Command, dir string) error {
|
||||
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md"
|
||||
filename := filepath.Join(dir, basename)
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err = io.WriteString(f, "---\ntitle: CLI Commands\n---\n\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tp := range []string{types.TypeStart, types.TypeApp, types.TypeCD, types.TypeExtension, types.TypeSystem} {
|
||||
// write header of type
|
||||
_, err = io.WriteString(f, "## "+tp+"\n\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
str := PrintCLIByTag(cmd, cmd.Commands(), tp)
|
||||
// write header of type
|
||||
_, err = io.WriteString(f, str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = io.WriteString(f, "###### Auto generated by [script in KubeVela](https://github.com/oam-dev/kubevela/tree/master/hack/docgen).")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
rootPath := "../kubevela.io/docs/cli/"
|
||||
if len(os.Args) > 1 {
|
||||
rootPath = os.Args[1]
|
||||
}
|
||||
fmt.Println("scanning rootPath of CLI docs for replace: ", rootPath)
|
||||
vela := cli.NewCommand()
|
||||
err := doc.GenMarkdownTree(vela, "./docs/en/cli/")
|
||||
err := doc.GenMarkdownTree(vela, rootPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = GenMarkdownTreeForIndex(vela, rootPath)
|
||||
if err != nil {
|
||||
log.Fatal("generate docs for vela index fail", err)
|
||||
}
|
||||
err = filepath.Walk(rootPath, func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lines := strings.Split(string(data), "\n")
|
||||
if len(lines) < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// check first line to make sure it's autogenerated docs
|
||||
firstL := lines[0]
|
||||
if !strings.HasPrefix(firstL, "## vela") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// find the last line and add some link.
|
||||
var lastIdx int
|
||||
for idx := len(lines) - 1; idx >= 0; idx-- {
|
||||
if strings.Contains(lines[idx], "Auto generated") {
|
||||
lastIdx = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
if lastIdx == 0 {
|
||||
return nil
|
||||
}
|
||||
lastL := lines[lastIdx]
|
||||
lines[lastIdx] = "#### Go Back to [CLI Commands](vela) Homepage.\n\n\n" + lastL + ", refer to [script in KubeVela](https://github.com/oam-dev/kubevela/tree/master/hack/docgen)."
|
||||
|
||||
// update the title format
|
||||
title := strings.TrimPrefix(firstL, "## ")
|
||||
|
||||
lines[0] = "---"
|
||||
newlines := []string{"---", "title: " + title}
|
||||
|
||||
for idx, line := range lines {
|
||||
if strings.Contains(line, "[vela](vela.md)") {
|
||||
lines[idx] = ""
|
||||
continue
|
||||
}
|
||||
if strings.Contains(line, ".md") && strings.Contains(line, "](") {
|
||||
lines[idx] = strings.Replace(line, ".md", "", -1)
|
||||
}
|
||||
}
|
||||
|
||||
newlines = append(newlines, lines...)
|
||||
newcontent := strings.Join(newlines, "\n")
|
||||
return ioutil.WriteFile(path, []byte(newcontent), info.Mode())
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -21,13 +21,28 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
"github.com/oam-dev/kubevela/references/plugins"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ref := &plugins.MarkdownReference{}
|
||||
ctx := context.Background()
|
||||
if err := ref.GenerateReferenceDocs(ctx, plugins.BaseRefPath); err != nil {
|
||||
path := plugins.BaseRefPath
|
||||
|
||||
if len(os.Args) == 2 {
|
||||
ref.DefinitionName = os.Args[1]
|
||||
path = plugins.KubeVelaIOTerraformPath
|
||||
}
|
||||
|
||||
c, err := common.InitBaseRestConfig()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := ref.GenerateReferenceDocs(ctx, c, path, types.DefaultKubeVelaNS); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -677,113 +677,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of
|
||||
AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of
|
||||
the app that we need to upgrade from. We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the
|
||||
Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time
|
||||
this condition transitioned from one status to
|
||||
another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about
|
||||
this condition's last transition from one status
|
||||
to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last
|
||||
transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently
|
||||
True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one
|
||||
of each condition type may apply to a resource
|
||||
at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working
|
||||
on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string
|
||||
that uniquely represent the last pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources We update this field
|
||||
only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the
|
||||
name of the app that we upgraded to We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that
|
||||
uniquely represent the new pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods
|
||||
upgraded by the rollout controller that have a Ready
|
||||
Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded
|
||||
by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application
|
||||
services
|
||||
@@ -2324,324 +2217,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout
|
||||
the resources The controller simply replace the old resources
|
||||
with the new one if there is no rollout plan involved
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition
|
||||
(included) will have the target resource specification
|
||||
while the rest still have the source resource This is
|
||||
designed for the operators to manually rollout Default
|
||||
is the the number of batches which will rollout all
|
||||
the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout
|
||||
process to automatically check certain metrics before
|
||||
complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics
|
||||
used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template
|
||||
object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an
|
||||
object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access
|
||||
statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to
|
||||
a container within a pod, this would take
|
||||
on a value like: "spec.containers{name}" (where
|
||||
"name" refers to the name of the container
|
||||
that triggered the event) or if no container
|
||||
name is specified "spec.containers[2]" (container
|
||||
with index 2 in this pod). This syntax is
|
||||
chosen only to have some well-defined way
|
||||
of referencing a part of an object. TODO:
|
||||
this design is not final and this field is
|
||||
subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which
|
||||
this reference is made, if any. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its
|
||||
size has to be exactly the same as the NumBatches (if
|
||||
set) The total number cannot exceed the targetSize or
|
||||
the size of the source resource We will IGNORE the last
|
||||
batch's replica field if it's a percentage since round
|
||||
errors can lead to inaccurate sum We highly recommend
|
||||
to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the
|
||||
each batch rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for
|
||||
the batch rollout to interact with an external
|
||||
process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference
|
||||
to external checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the
|
||||
expected http status code that we will accept
|
||||
as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for
|
||||
this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method,
|
||||
default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the
|
||||
batch rollout process to automatically check certain
|
||||
metrics before moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference
|
||||
to metrics used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows
|
||||
size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this
|
||||
metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric
|
||||
template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece
|
||||
of an object instead of an entire object,
|
||||
this string should contain a valid JSON/Go
|
||||
field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference
|
||||
is to a container within a pod, this
|
||||
would take on a value like: "spec.containers{name}"
|
||||
(where "name" refers to the name of
|
||||
the container that triggered the event)
|
||||
or if no container name is specified
|
||||
"spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is
|
||||
chosen only to have some well-defined
|
||||
way of referencing a part of an object.
|
||||
TODO: this design is not final and this
|
||||
field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More
|
||||
info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion
|
||||
to which this reference is made, if
|
||||
any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between
|
||||
instances upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number
|
||||
of pods that is unavailable during the upgrade.
|
||||
We will mark the batch as ready as long as there
|
||||
are less or equal number of pods unavailable than
|
||||
this number. default = 0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it
|
||||
is mutually exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to
|
||||
upgrade in this batch it can be an absolute number
|
||||
(ex: 5) or a percentage of total pods we will
|
||||
ignore the percentage of the last batch to just
|
||||
fill the gap it is mutually exclusive with the
|
||||
PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the
|
||||
rollout plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout
|
||||
to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected
|
||||
http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this
|
||||
webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default
|
||||
is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default
|
||||
is the same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
workflow:
|
||||
description: 'Workflow defines how to customize the control
|
||||
logic. If workflow is specified, Vela won''t apply any resource,
|
||||
@@ -2937,113 +2512,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of
|
||||
AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of
|
||||
the app that we need to upgrade from. We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the
|
||||
Status is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time
|
||||
this condition transitioned from one status to
|
||||
another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about
|
||||
this condition's last transition from one status
|
||||
to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last
|
||||
transition from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently
|
||||
True, False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one
|
||||
of each condition type may apply to a resource
|
||||
at any point in time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working
|
||||
on/blocked it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string
|
||||
that uniquely represent the last pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources We update this field
|
||||
only after a successful rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the
|
||||
name of the app that we upgraded to We will restart
|
||||
the rollout if this is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target
|
||||
resources. This is determined once the initial spec
|
||||
verification and does not change until the rollout is
|
||||
restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that
|
||||
uniquely represent the new pod template each workload
|
||||
type could use different ways to identify that so we
|
||||
cannot compare between resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods
|
||||
upgraded by the rollout controller that have a Ready
|
||||
Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded
|
||||
by the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application
|
||||
services
|
||||
|
||||
@@ -617,107 +617,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app
|
||||
that we need to upgrade from. We will restart the rollout if
|
||||
this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status
|
||||
is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition
|
||||
transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's
|
||||
last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition
|
||||
from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True,
|
||||
False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each
|
||||
condition type may apply to a resource at any point in
|
||||
time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked
|
||||
it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that
|
||||
uniquely represent the last pod template each workload type
|
||||
could use different ways to identify that so we cannot compare
|
||||
between resources We update this field only after a successful
|
||||
rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of
|
||||
the app that we upgraded to We will restart the rollout if this
|
||||
is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does
|
||||
not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does
|
||||
not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely
|
||||
represent the new pod template each workload type could use
|
||||
different ways to identify that so we cannot compare between
|
||||
resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded
|
||||
by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by
|
||||
the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application services
|
||||
items:
|
||||
@@ -1135,303 +1034,6 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
rolloutPlan:
|
||||
description: RolloutPlan is the details on how to rollout the resources
|
||||
The controller simply replace the old resources with the new one
|
||||
if there is no rollout plan involved
|
||||
properties:
|
||||
batchPartition:
|
||||
description: All pods in the batches up to the batchPartition
|
||||
(included) will have the target resource specification while
|
||||
the rest still have the source resource This is designed for
|
||||
the operators to manually rollout Default is the the number
|
||||
of batches which will rollout all the batches
|
||||
format: int32
|
||||
type: integer
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the rollout process
|
||||
to automatically check certain metrics before complete the process
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics used
|
||||
for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead
|
||||
of an entire object, this string should contain a
|
||||
valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container
|
||||
within a pod, this would take on a value like: "spec.containers{name}"
|
||||
(where "name" refers to the name of the container
|
||||
that triggered the event) or if no container name
|
||||
is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to
|
||||
have some well-defined way of referencing a part of
|
||||
an object. TODO: this design is not final and this
|
||||
field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this
|
||||
reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
numBatches:
|
||||
description: The number of batches, default = 1
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused the rollout, default is false
|
||||
type: boolean
|
||||
rolloutBatches:
|
||||
description: The exact distribution among batches. its size has
|
||||
to be exactly the same as the NumBatches (if set) The total
|
||||
number cannot exceed the targetSize or the size of the source
|
||||
resource We will IGNORE the last batch's replica field if it's
|
||||
a percentage since round errors can lead to inaccurate sum We
|
||||
highly recommend to leave the last batch's replica field empty
|
||||
items:
|
||||
description: RolloutBatch is used to describe how the each batch
|
||||
rollout should be
|
||||
properties:
|
||||
batchRolloutWebhooks:
|
||||
description: RolloutWebhooks provides a way for the batch
|
||||
rollout to interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected
|
||||
http status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default
|
||||
is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
canaryMetric:
|
||||
description: CanaryMetric provides a way for the batch rollout
|
||||
process to automatically check certain metrics before
|
||||
moving to the next batch
|
||||
items:
|
||||
description: CanaryMetric holds the reference to metrics
|
||||
used for canary analysis
|
||||
properties:
|
||||
interval:
|
||||
description: Interval represents the windows size
|
||||
type: string
|
||||
metricsRange:
|
||||
description: Range value accepted for this metric
|
||||
properties:
|
||||
max:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Maximum value
|
||||
x-kubernetes-int-or-string: true
|
||||
min:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Minimum value
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
name:
|
||||
description: Name of the metric
|
||||
type: string
|
||||
templateRef:
|
||||
description: TemplateRef references a metric template
|
||||
object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object
|
||||
instead of an entire object, this string should
|
||||
contain a valid JSON/Go field access statement,
|
||||
such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a
|
||||
container within a pod, this would take on a
|
||||
value like: "spec.containers{name}" (where "name"
|
||||
refers to the name of the container that triggered
|
||||
the event) or if no container name is specified
|
||||
"spec.containers[2]" (container with index 2
|
||||
in this pod). This syntax is chosen only to
|
||||
have some well-defined way of referencing a
|
||||
part of an object. TODO: this design is not
|
||||
final and this field is subject to change in
|
||||
the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info:
|
||||
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which
|
||||
this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info:
|
||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
instanceInterval:
|
||||
description: The wait time, in seconds, between instances
|
||||
upgrades, default = 0
|
||||
format: int32
|
||||
type: integer
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: MaxUnavailable is the max allowed number of
|
||||
pods that is unavailable during the upgrade. We will mark
|
||||
the batch as ready as long as there are less or equal
|
||||
number of pods unavailable than this number. default =
|
||||
0
|
||||
x-kubernetes-int-or-string: true
|
||||
podList:
|
||||
description: The list of Pods to get upgraded it is mutually
|
||||
exclusive with the Replicas field
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Replicas is the number of pods to upgrade
|
||||
in this batch it can be an absolute number (ex: 5) or
|
||||
a percentage of total pods we will ignore the percentage
|
||||
of the last batch to just fill the gap it is mutually
|
||||
exclusive with the PodList field'
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: array
|
||||
rolloutStrategy:
|
||||
description: RolloutStrategy defines strategies for the rollout
|
||||
plan The default is IncreaseFirstRolloutStrategyType
|
||||
type: string
|
||||
rolloutWebhooks:
|
||||
description: RolloutWebhooks provide a way for the rollout to
|
||||
interact with an external process
|
||||
items:
|
||||
description: RolloutWebhook holds the reference to external
|
||||
checks used for canary analysis
|
||||
properties:
|
||||
expectedStatus:
|
||||
description: ExpectedStatus contains all the expected http
|
||||
status code that we will accept as success
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
method:
|
||||
description: Method the HTTP call method, default is POST
|
||||
type: string
|
||||
name:
|
||||
description: Name of this webhook
|
||||
type: string
|
||||
type:
|
||||
description: Type of this webhook
|
||||
type: string
|
||||
url:
|
||||
description: URL address of this webhook
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- url
|
||||
type: object
|
||||
type: array
|
||||
targetSize:
|
||||
description: The size of the target resource. The default is the
|
||||
same as the size of the source resource.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
workflow:
|
||||
description: 'Workflow defines how to customize the control logic.
|
||||
If workflow is specified, Vela won''t apply any resource, but provide
|
||||
@@ -1710,107 +1312,6 @@ spec:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
rollout:
|
||||
description: AppRolloutStatus defines the observed state of AppRollout
|
||||
properties:
|
||||
LastSourceAppRevision:
|
||||
description: LastSourceAppRevision contains the name of the app
|
||||
that we need to upgrade from. We will restart the rollout if
|
||||
this is not the same as the spec
|
||||
type: string
|
||||
batchRollingState:
|
||||
description: BatchRollingState only meaningful when the Status
|
||||
is rolling
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions of the resource.
|
||||
items:
|
||||
description: A Condition that may apply to a resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time this condition
|
||||
transitioned from one status to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A Message containing details about this condition's
|
||||
last transition from one status to another, if any.
|
||||
type: string
|
||||
reason:
|
||||
description: A Reason for this condition's last transition
|
||||
from one status to another.
|
||||
type: string
|
||||
status:
|
||||
description: Status of this condition; is it currently True,
|
||||
False, or Unknown?
|
||||
type: string
|
||||
type:
|
||||
description: Type of this condition. At most one of each
|
||||
condition type may apply to a resource at any point in
|
||||
time.
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentBatch:
|
||||
description: The current batch the rollout is working on/blocked
|
||||
it starts from 0
|
||||
format: int32
|
||||
type: integer
|
||||
lastAppliedPodTemplateIdentifier:
|
||||
description: lastAppliedPodTemplateIdentifier is a string that
|
||||
uniquely represent the last pod template each workload type
|
||||
could use different ways to identify that so we cannot compare
|
||||
between resources We update this field only after a successful
|
||||
rollout
|
||||
type: string
|
||||
lastTargetAppRevision:
|
||||
description: LastUpgradedTargetAppRevision contains the name of
|
||||
the app that we upgraded to We will restart the rollout if this
|
||||
is not the same as the spec
|
||||
type: string
|
||||
rollingState:
|
||||
description: RollingState is the Rollout State
|
||||
type: string
|
||||
rolloutOriginalSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does
|
||||
not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
rolloutTargetSize:
|
||||
description: RolloutTargetSize is the size of the target resources.
|
||||
This is determined once the initial spec verification and does
|
||||
not change until the rollout is restarted
|
||||
format: int32
|
||||
type: integer
|
||||
targetGeneration:
|
||||
description: NewPodTemplateIdentifier is a string that uniquely
|
||||
represent the new pod template each workload type could use
|
||||
different ways to identify that so we cannot compare between
|
||||
resources
|
||||
type: string
|
||||
upgradedReadyReplicas:
|
||||
description: UpgradedReadyReplicas is the number of Pods upgraded
|
||||
by the rollout controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
upgradedReplicas:
|
||||
description: UpgradedReplicas is the number of Pods upgraded by
|
||||
the rollout controller
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentBatch
|
||||
- lastTargetAppRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
services:
|
||||
description: Services record the status of the application services
|
||||
items:
|
||||
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
k8syaml "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
|
||||
types2 "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
@@ -109,6 +110,8 @@ const (
|
||||
ObservabilityAddonEndpointComponent = "grafana"
|
||||
// ObservabilityAddonDomainArg is the domain argument name of the observability addon
|
||||
ObservabilityAddonDomainArg = "domain"
|
||||
// LocalAddonRegistryName is the addon-registry name for those installed by local dir
|
||||
LocalAddonRegistryName = "local"
|
||||
)
|
||||
|
||||
// ObservabilityEnvironment contains the Observability addon's domain for each cluster
|
||||
@@ -464,6 +467,10 @@ func RenderApp(ctx context.Context, addon *InstallPackage, config *rest.Config,
|
||||
}
|
||||
app.Labels = util.MergeMapOverrideWithDst(app.Labels, map[string]string{oam.LabelAddonName: addon.Name})
|
||||
for _, namespace := range addon.NeedNamespace {
|
||||
// vela-system must exist before rendering vela addon
|
||||
if namespace == types.DefaultKubeVelaNS {
|
||||
continue
|
||||
}
|
||||
comp := common2.ApplicationComponent{
|
||||
Type: "raw",
|
||||
Name: fmt.Sprintf("%s-namespace", namespace),
|
||||
@@ -505,20 +512,34 @@ func RenderApp(ctx context.Context, addon *InstallPackage, config *rest.Config,
|
||||
Type: "deploy2runtime",
|
||||
})
|
||||
case addon.Name == ObservabilityAddon:
|
||||
policies, err := preparePolicies4Observability(ctx, k8sClient)
|
||||
clusters, err := allocateDomainForAddon(ctx, k8sClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policies, err := preparePolicies4Observability(clusters)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fail to render the policies for Add-on Observability")
|
||||
}
|
||||
app.Spec.Policies = policies
|
||||
|
||||
app.Spec.Workflow = &v1beta1.Workflow{
|
||||
Steps: []v1beta1.WorkflowStep{{
|
||||
Name: "deploy-control-plane",
|
||||
Type: "apply-application-in-parallel",
|
||||
}},
|
||||
if len(clusters) > 0 {
|
||||
app.Spec.Workflow = &v1beta1.Workflow{
|
||||
Steps: []v1beta1.WorkflowStep{{
|
||||
Name: "deploy-control-plane",
|
||||
Type: "apply-application-in-parallel",
|
||||
}},
|
||||
}
|
||||
} else {
|
||||
app.Spec.Workflow = &v1beta1.Workflow{
|
||||
Steps: []v1beta1.WorkflowStep{{
|
||||
Name: "deploy-control-plane",
|
||||
Type: "apply-application",
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
workflowSteps, err := prepareWorkflow4Observability(ctx, k8sClient)
|
||||
workflowSteps, err := prepareWorkflow4Observability(clusters)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fail to prepare the workflow for Add-on Observability")
|
||||
}
|
||||
@@ -625,12 +646,10 @@ func allocateDomainForAddon(ctx context.Context, k8sClient client.Client) ([]Obs
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
func preparePolicies4Observability(ctx context.Context, k8sClient client.Client) ([]v1beta1.AppPolicy, error) {
|
||||
clusters, err := allocateDomainForAddon(ctx, k8sClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func preparePolicies4Observability(clusters []ObservabilityEnvironment) ([]v1beta1.AppPolicy, error) {
|
||||
if clusters == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
envProperties, err := render(clusters, ObservabilityEnvBindingEnvTmpl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -656,12 +675,7 @@ func preparePolicies4Observability(ctx context.Context, k8sClient client.Client)
|
||||
return policies, nil
|
||||
}
|
||||
|
||||
func prepareWorkflow4Observability(ctx context.Context, k8sClient client.Client) ([]v1beta1.WorkflowStep, error) {
|
||||
clusters, err := allocateDomainForAddon(ctx, k8sClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func prepareWorkflow4Observability(clusters []ObservabilityEnvironment) ([]v1beta1.WorkflowStep, error) {
|
||||
envBindingWorkflow, err := render(clusters, ObservabilityWorkflow4EnvBindingTmpl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -865,7 +879,7 @@ func (h *Installer) enableAddon(addon *InstallPackage) error {
|
||||
}
|
||||
// we shouldn't put continue func into dispatchAddonResource, because the re-apply app maybe already update app and
|
||||
// the suspend will set with false automatically
|
||||
if err := h.continueIfSuspend(); err != nil {
|
||||
if err := h.continueOrRestartWorkflow(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -943,6 +957,8 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
|
||||
}
|
||||
app.Name = appName
|
||||
|
||||
app.SetLabels(util.MergeMapOverrideWithDst(app.GetLabels(), map[string]string{oam.LabelAddonRegistry: h.r.Name}))
|
||||
|
||||
defs, err := RenderDefinitions(h.addon, h.config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "render addon definitions fail")
|
||||
@@ -986,17 +1002,39 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Installer) continueIfSuspend() error {
|
||||
// this func will handle such two case
|
||||
// 1. if last apply failed an workflow have suspend, this func will continue the workflow
|
||||
// 2. restart the workflow, if the new cluster have been added in KubeVela
|
||||
func (h *Installer) continueOrRestartWorkflow() error {
|
||||
app, err := FetchAddonRelatedApp(h.ctx, h.cli, h.addon.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if app.Status.Workflow != nil && app.Status.Workflow.Suspend {
|
||||
mergePatch := client.MergeFrom(app.DeepCopy())
|
||||
app.Status.Workflow.Suspend = false
|
||||
if err := h.cli.Status().Patch(h.ctx, app, mergePatch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
// this case means user add a new cluster and user want to restart workflow to dispatch addon resources to new cluster
|
||||
// re-apply app won't help app restart workflow
|
||||
case app.Status.Phase == common2.ApplicationRunning:
|
||||
// we can use retry on conflict here in CLI, because we want to update the status in this CLI operation.
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = h.cli.Get(h.ctx, client.ObjectKey{Namespace: app.Namespace, Name: app.Name}, app); err != nil {
|
||||
return
|
||||
}
|
||||
app.Status.Workflow = nil
|
||||
return h.cli.Status().Update(h.ctx, app)
|
||||
})
|
||||
// this case means addon last installation meet some error and workflow has been suspended by app controller
|
||||
// re-apply app won't help app workflow continue
|
||||
case app.Status.Workflow != nil && app.Status.Workflow.Suspend:
|
||||
// we can use retry on conflict here in CLI, because we want to update the status in this CLI operation.
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
|
||||
if err = h.cli.Get(h.ctx, client.ObjectKey{Namespace: app.Namespace, Name: app.Name}, app); err != nil {
|
||||
return
|
||||
}
|
||||
mergePatch := client.MergeFrom(app.DeepCopy())
|
||||
app.Status.Workflow.Suspend = false
|
||||
return h.cli.Status().Patch(h.ctx, app, mergePatch)
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ var _ = Describe("Addon test", func() {
|
||||
Expect(k8sClient.Delete(ctx, &app)).Should(BeNil())
|
||||
})
|
||||
|
||||
It("continueIfSuspend func test", func() {
|
||||
It("continueOrRestartWorkflow func test", func() {
|
||||
app = v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(appYaml), &app)).Should(BeNil())
|
||||
app.SetNamespace(testns)
|
||||
@@ -69,7 +69,7 @@ var _ = Describe("Addon test", func() {
|
||||
}
|
||||
|
||||
h := Installer{ctx: ctx, cli: k8sClient, addon: &InstallPackage{Meta: Meta{Name: "test-app"}}}
|
||||
if err := h.continueIfSuspend(); err != nil {
|
||||
if err := h.continueOrRestartWorkflow(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -87,6 +87,54 @@ var _ = Describe("Addon test", func() {
|
||||
}, 30*time.Second, 300*time.Millisecond).Should(BeNil())
|
||||
})
|
||||
|
||||
It("continueOrRestartWorkflow func test, test restart workflow", func() {
|
||||
app = v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(appYaml), &app)).Should(BeNil())
|
||||
app.SetNamespace(testns)
|
||||
Expect(k8sClient.Create(ctx, &app)).Should(BeNil())
|
||||
|
||||
Eventually(func() error {
|
||||
checkApp := &v1beta1.Application{}
|
||||
if err := k8sClient.Get(ctx, types2.NamespacedName{Namespace: app.Namespace, Name: app.Name}, checkApp); err != nil {
|
||||
return err
|
||||
}
|
||||
appPatch := client.MergeFrom(checkApp.DeepCopy())
|
||||
checkApp.Status.Workflow = &common.WorkflowStatus{Message: "someMessage", AppRevision: "test-revision"}
|
||||
checkApp.Status.Phase = common.ApplicationRunning
|
||||
if err := k8sClient.Status().Patch(ctx, checkApp, appPatch); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}, 30*time.Second, 300*time.Millisecond).Should(BeNil())
|
||||
|
||||
Eventually(func() error {
|
||||
checkApp := &v1beta1.Application{}
|
||||
if err := k8sClient.Get(ctx, types2.NamespacedName{Namespace: app.Namespace, Name: app.Name}, checkApp); err != nil {
|
||||
return err
|
||||
}
|
||||
if checkApp.Status.Phase != common.ApplicationRunning {
|
||||
return fmt.Errorf("app haven't not running")
|
||||
}
|
||||
|
||||
h := Installer{ctx: ctx, cli: k8sClient, addon: &InstallPackage{Meta: Meta{Name: "test-app"}}}
|
||||
if err := h.continueOrRestartWorkflow(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}, 30*time.Second, 300*time.Millisecond).Should(BeNil())
|
||||
|
||||
Eventually(func() error {
|
||||
checkApp := &v1beta1.Application{}
|
||||
if err := k8sClient.Get(ctx, types2.NamespacedName{Namespace: app.Namespace, Name: app.Name}, checkApp); err != nil {
|
||||
return err
|
||||
}
|
||||
if checkApp.Status.Workflow != nil {
|
||||
return fmt.Errorf("app workflow havenot been restart")
|
||||
}
|
||||
return nil
|
||||
}, 30*time.Second, 300*time.Millisecond).Should(BeNil())
|
||||
})
|
||||
|
||||
It(" FetchAddonRelatedApp func test", func() {
|
||||
app = v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(legacyAppYaml), &app)).Should(BeNil())
|
||||
|
||||
@@ -122,9 +122,11 @@ func testReaderFunc(t *testing.T, reader AsyncReader) {
|
||||
assert.True(t, len(uiData.Definitions) > 0)
|
||||
|
||||
// test get ui data
|
||||
uiDataList, err := ListAddonUIDataFromReader(reader, registryMeta, "KubeVela", UIMetaOptions)
|
||||
rName := "KubeVela"
|
||||
uiDataList, err := ListAddonUIDataFromReader(reader, registryMeta, rName, UIMetaOptions)
|
||||
assert.True(t, strings.Contains(err.Error(), "#parameter.example: preference mark not allowed at this position"))
|
||||
assert.Equal(t, len(uiDataList), 3)
|
||||
assert.Equal(t, uiDataList[0].RegistryName, rName)
|
||||
|
||||
// test get install package
|
||||
installPkg, err := GetInstallPackageFromReader(reader, &testAddonMeta, uiData)
|
||||
@@ -224,6 +226,17 @@ func TestRenderApp(t *testing.T) {
|
||||
assert.Equal(t, len(app.Spec.Components), 2)
|
||||
}
|
||||
|
||||
func TestRenderAppWithNeedNamespace(t *testing.T) {
|
||||
addon := baseAddon
|
||||
addon.NeedNamespace = append(addon.NeedNamespace, types.DefaultKubeVelaNS)
|
||||
app, err := RenderApp(ctx, &addon, nil, nil, map[string]interface{}{})
|
||||
assert.NoError(t, err, "render app fail")
|
||||
assert.Equal(t, len(app.Spec.Components), 2)
|
||||
for _, c := range app.Spec.Components {
|
||||
assert.NotEqual(t, types.DefaultKubeVelaNS+"-namespace", c.Name, "namespace vela-system should not be rendered")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderDeploy2RuntimeAddon(t *testing.T) {
|
||||
addonDeployToRuntime := baseAddon
|
||||
addonDeployToRuntime.Meta.DeployTo = &DeployTo{
|
||||
@@ -435,7 +448,7 @@ func TestRenderApp4Observability(t *testing.T) {
|
||||
},
|
||||
},
|
||||
args: map[string]interface{}{},
|
||||
application: `{"kind":"Application","apiVersion":"core.oam.dev/v1beta1","metadata":{"name":"addon-observability","namespace":"vela-system","creationTimestamp":null,"labels":{"addons.oam.dev/name":"observability"}},"spec":{"components":[],"policies":[{"name":"domain","type":"env-binding","properties":{"envs":null}}],"workflow":{"steps":[{"name":"deploy-control-plane","type":"apply-application-in-parallel"}]}},"status":{}}`,
|
||||
application: `{"kind":"Application","apiVersion":"core.oam.dev/v1beta1","metadata":{"name":"addon-observability","namespace":"vela-system","creationTimestamp":null,"labels":{"addons.oam.dev/name":"observability"}},"spec":{"components":[],"policies":[{"name":"domain","type":"env-binding","properties":{"envs":null}}],"workflow":{"steps":[{"name":"deploy-control-plane","type":"apply-application"}]}},"status":{}}`,
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
@@ -537,3 +550,8 @@ func TestGetPatternFromItem(t *testing.T) {
|
||||
assert.Equal(t, res, tc.meetPattern, tc.caseName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGitLabReaderNotPanic(t *testing.T) {
|
||||
_, err := NewAsyncReader("https://gitlab.com/test/catalog", "", "addons", "", gitType)
|
||||
assert.EqualError(t, err, "git type repository only support github for now")
|
||||
}
|
||||
|
||||
@@ -75,6 +75,30 @@ func DisableAddon(ctx context.Context, cli client.Client, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableAddonByLocalDir enable an addon from local dir
|
||||
func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli client.Client, applicator apply.Applicator, config *rest.Config, args map[string]interface{}) error {
|
||||
r := localReader{dir: dir, name: name}
|
||||
metas, err := r.ListAddonMeta()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
meta := metas[r.name]
|
||||
UIData, err := GetUIDataFromReader(r, &meta, UIMetaOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pkg, err := GetInstallPackageFromReader(r, &meta, UIData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h := NewAddonInstaller(ctx, cli, applicator, config, &Registry{Name: LocalAddonRegistryName}, args, nil)
|
||||
err = h.enableAddon(pkg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAddonStatus is genrall func for cli and apiServer get addon status
|
||||
func GetAddonStatus(ctx context.Context, cli client.Client, name string) (Status, error) {
|
||||
app, err := FetchAddonRelatedApp(ctx, cli, name)
|
||||
|
||||
@@ -48,6 +48,9 @@ func (g *gitReader) ListAddonMeta() (map[string]SourceMeta, error) {
|
||||
}
|
||||
for _, item := range items {
|
||||
// single addon
|
||||
if item.GetType() != DirType {
|
||||
continue
|
||||
}
|
||||
addonName := path.Base(item.GetPath())
|
||||
addonMeta, err := g.listAddonMeta(g.RelativePath(item))
|
||||
if err != nil {
|
||||
|
||||
67
pkg/addon/reader_local.go
Normal file
67
pkg/addon/reader_local.go
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package addon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type localReader struct {
|
||||
dir string
|
||||
name string
|
||||
}
|
||||
|
||||
func (l localReader) ListAddonMeta() (map[string]SourceMeta, error) {
|
||||
metas := SourceMeta{Name: l.name}
|
||||
if err := recursiveFetchFiles(l.dir, &metas); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]SourceMeta{l.name: metas}, nil
|
||||
}
|
||||
|
||||
func (l localReader) ReadFile(path string) (string, error) {
|
||||
file := strings.TrimPrefix(path, l.name+"/")
|
||||
b, err := ioutil.ReadFile(filepath.Clean(filepath.Join(l.dir, file)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
func (l localReader) RelativePath(item Item) string {
|
||||
return filepath.Join(l.name, strings.TrimPrefix(item.GetPath()+"/", l.dir))
|
||||
}
|
||||
|
||||
func recursiveFetchFiles(path string, metas *SourceMeta) error {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
if err := recursiveFetchFiles(fmt.Sprintf("%s/%s", path, file.Name()), metas); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
metas.Items = append(metas.Items, OSSItem{tp: "file", path: fmt.Sprintf("%s/%s", path, file.Name()), name: file.Name()})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
62
pkg/addon/reader_local_test.go
Normal file
62
pkg/addon/reader_local_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package addon
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLocalReader(t *testing.T) {
|
||||
r := localReader{name: "local", dir: "./testdata/local"}
|
||||
m, err := r.ListAddonMeta()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(m["local"].Items), 2)
|
||||
|
||||
file, err := r.ReadFile("metadata.yaml")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, file, metaFile)
|
||||
|
||||
file, err = r.ReadFile("resources/parameter.cue")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, strings.Contains(file, parameterFile))
|
||||
}
|
||||
|
||||
const (
|
||||
metaFile = `name: test-local-addon
|
||||
version: 1.0.0
|
||||
description: This is a addon for test when install addon from local
|
||||
icon: https://www.terraform.io/assets/images/logo-text-8c3ba8a6.svg
|
||||
url: https://terraform.io/
|
||||
|
||||
tags: []
|
||||
|
||||
deployTo:
|
||||
control_plane: true
|
||||
runtime_cluster: false
|
||||
|
||||
dependencies: []
|
||||
|
||||
invisible: false`
|
||||
|
||||
parameterFile = `parameter: {
|
||||
// test wrong parameter
|
||||
example: *"default"
|
||||
}`
|
||||
)
|
||||
@@ -127,8 +127,8 @@ func NewAsyncReader(baseURL, bucket, subPath, token string, rdType ReaderType) (
|
||||
return nil, errors.New("addon registry invalid")
|
||||
}
|
||||
u.Path = path.Join(u.Path, subPath)
|
||||
tp, content, err := utils.Parse(u.String())
|
||||
if err != nil || tp != utils.TypeGithub {
|
||||
_, content, err := utils.Parse(u.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gith := createGitHelper(content, token)
|
||||
|
||||
@@ -22,11 +22,11 @@ import (
|
||||
"time"
|
||||
|
||||
v12 "k8s.io/api/core/v1"
|
||||
crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
@@ -75,7 +75,7 @@ var _ = BeforeSuite(func(done Done) {
|
||||
scheme = runtime.NewScheme()
|
||||
Expect(coreoam.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
Expect(clientgoscheme.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
Expect(v1beta1.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
Expect(crdv1.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(k8sClient).ToNot(BeNil())
|
||||
|
||||
15
pkg/addon/testdata/local/metadata.yaml
vendored
Normal file
15
pkg/addon/testdata/local/metadata.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: test-local-addon
|
||||
version: 1.0.0
|
||||
description: This is a addon for test when install addon from local
|
||||
icon: https://www.terraform.io/assets/images/logo-text-8c3ba8a6.svg
|
||||
url: https://terraform.io/
|
||||
|
||||
tags: []
|
||||
|
||||
deployTo:
|
||||
control_plane: true
|
||||
runtime_cluster: false
|
||||
|
||||
dependencies: []
|
||||
|
||||
invisible: false
|
||||
4
pkg/addon/testdata/local/resources/parameter.cue
vendored
Normal file
4
pkg/addon/testdata/local/resources/parameter.cue
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
parameter: {
|
||||
// test wrong parameter
|
||||
example: *"default"
|
||||
}
|
||||
@@ -41,6 +41,9 @@ var (
|
||||
|
||||
// ErrIndexInvalid Error that entity index is invalid
|
||||
ErrIndexInvalid = NewDBError(fmt.Errorf("entity index is invalid"))
|
||||
|
||||
// ErrEntityInvalid Error that entity is invalid
|
||||
ErrEntityInvalid = NewDBError(fmt.Errorf("entity is invalid"))
|
||||
)
|
||||
|
||||
// DBError datastore error
|
||||
|
||||
@@ -37,6 +37,9 @@ type mongodb struct {
|
||||
database string
|
||||
}
|
||||
|
||||
// PrimaryKey primary key
|
||||
const PrimaryKey = "_name"
|
||||
|
||||
// New new mongodb datastore instance
|
||||
func New(ctx context.Context, cfg datastore.Config) (datastore.DataStore, error) {
|
||||
if !strings.HasPrefix(cfg.URL, "mongodb://") {
|
||||
@@ -67,8 +70,13 @@ func (m *mongodb) Add(ctx context.Context, entity datastore.Entity) error {
|
||||
if err := m.Get(ctx, entity); err == nil {
|
||||
return datastore.ErrRecordExist
|
||||
}
|
||||
model, err := convertToMap(entity)
|
||||
if err != nil {
|
||||
return datastore.ErrEntityInvalid
|
||||
}
|
||||
model[PrimaryKey] = entity.PrimaryKey()
|
||||
collection := m.client.Database(m.database).Collection(entity.TableName())
|
||||
_, err := collection.InsertOne(ctx, entity)
|
||||
_, err = collection.InsertOne(ctx, model)
|
||||
if err != nil {
|
||||
return datastore.NewDBError(err)
|
||||
}
|
||||
@@ -203,7 +211,7 @@ func (m *mongodb) List(ctx context.Context, entity datastore.Entity, op *datasto
|
||||
if entity.Index() != nil {
|
||||
for k, v := range entity.Index() {
|
||||
filter = append(filter, bson.E{
|
||||
Key: k,
|
||||
Key: strings.ToLower(k),
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
@@ -279,9 +287,21 @@ func (m *mongodb) Count(ctx context.Context, entity datastore.Entity, filterOpti
|
||||
}
|
||||
|
||||
func makeNameFilter(name string) bson.D {
|
||||
return bson.D{{Key: "name", Value: name}}
|
||||
return bson.D{{Key: PrimaryKey, Value: name}}
|
||||
}
|
||||
|
||||
func makeEntityUpdate(entity interface{}) bson.M {
|
||||
return bson.M{"$set": entity}
|
||||
}
|
||||
|
||||
func convertToMap(model interface{}) (bson.M, error) {
|
||||
b, err := bson.Marshal(model)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var re = make(bson.M)
|
||||
if err := bson.Unmarshal(b, &re); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return re, nil
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import (
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/model"
|
||||
@@ -35,7 +37,11 @@ var mongodbDriver datastore.DataStore
|
||||
var _ = BeforeSuite(func(done Done) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
By("bootstrapping mongodb test environment")
|
||||
var err error
|
||||
clientOpts := options.Client().ApplyURI("mongodb://localhost:27017")
|
||||
client, err := mongo.Connect(context.TODO(), clientOpts)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
client.Database("kubevela").Drop(context.TODO())
|
||||
|
||||
mongodbDriver, err = New(context.TODO(), datastore.Config{
|
||||
URL: "mongodb://localhost:27017",
|
||||
Database: "kubevela",
|
||||
@@ -65,6 +71,8 @@ var _ = Describe("Test mongodb datastore driver", func() {
|
||||
&model.Application{Name: "kubevela-app-2", Description: "this is demo 2"},
|
||||
&model.Application{Name: "kubevela-app-3", Description: "this is demo 3"},
|
||||
&model.Application{Name: "kubevela-app-4", Description: "this is demo 4"},
|
||||
&model.Workflow{Name: "kubevela-app-workflow", AppPrimaryKey: "kubevela-app-2", Description: "this is workflow"},
|
||||
&model.ApplicationTrigger{Name: "kubevela-app-trigger", AppPrimaryKey: "kubevela-app-2", Token: "token-test", Description: "this is demo 4"},
|
||||
}
|
||||
err := mongodbDriver.BatchAdd(context.TODO(), datas)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
@@ -84,6 +92,12 @@ var _ = Describe("Test mongodb datastore driver", func() {
|
||||
Expect(err).Should(BeNil())
|
||||
diff := cmp.Diff(app.Description, "default")
|
||||
Expect(diff).Should(BeEmpty())
|
||||
|
||||
workflow := &model.Workflow{Name: "kubevela-app-workflow", AppPrimaryKey: "kubevela-app-2"}
|
||||
err = mongodbDriver.Get(context.TODO(), workflow)
|
||||
Expect(err).Should(BeNil())
|
||||
diff = cmp.Diff(workflow.Description, "this is workflow")
|
||||
Expect(diff).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test put function", func() {
|
||||
@@ -111,6 +125,14 @@ var _ = Describe("Test mongodb datastore driver", func() {
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
diff = cmp.Diff(len(list), 4)
|
||||
Expect(diff).Should(BeEmpty())
|
||||
|
||||
var workflow = model.Workflow{
|
||||
AppPrimaryKey: "kubevela-app-2",
|
||||
}
|
||||
list, err = mongodbDriver.List(context.TODO(), &workflow, nil)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
diff = cmp.Diff(len(list), 1)
|
||||
Expect(diff).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test list clusters with sort and fuzzy query", func() {
|
||||
@@ -213,5 +235,13 @@ var _ = Describe("Test mongodb datastore driver", func() {
|
||||
err = mongodbDriver.Delete(context.TODO(), &app)
|
||||
equal := cmp.Equal(err, datastore.ErrRecordNotExist, cmpopts.EquateErrors())
|
||||
Expect(equal).Should(BeTrue())
|
||||
|
||||
workflow := model.Workflow{Name: "kubevela-app-workflow", AppPrimaryKey: "kubevela-app-2", Description: "this is workflow"}
|
||||
err = mongodbDriver.Delete(context.TODO(), &workflow)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
trigger := model.ApplicationTrigger{Name: "kubevela-app-trigger", AppPrimaryKey: "kubevela-app-2", Token: "token-test", Description: "this is demo 4"}
|
||||
err = mongodbDriver.Delete(context.TODO(), &trigger)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -213,6 +213,8 @@ type ApplicationRevision struct {
|
||||
EnvName string `json:"envName"`
|
||||
// CodeInfo is the code info of this application revision
|
||||
CodeInfo *CodeInfo `json:"codeInfo,omitempty"`
|
||||
// ImageInfo is the image info of this application revision
|
||||
ImageInfo *ImageInfo `json:"imageInfo,omitempty"`
|
||||
}
|
||||
|
||||
// CodeInfo is the code info for webhook request
|
||||
@@ -225,6 +227,44 @@ type CodeInfo struct {
|
||||
User string `json:"user,omitempty"`
|
||||
}
|
||||
|
||||
// ImageInfo is the image info for webhook request
|
||||
type ImageInfo struct {
|
||||
// Type is the image type, ACR or Harbor or DockerHub
|
||||
Type string `json:"type"`
|
||||
// Resource is the image resource
|
||||
Resource *ImageResource `json:"resource,omitempty"`
|
||||
// Repository is the image repository
|
||||
Repository *ImageRepository `json:"repository,omitempty"`
|
||||
}
|
||||
|
||||
// ImageResource is the image resource
|
||||
type ImageResource struct {
|
||||
// Digest is the image digest
|
||||
Digest string `json:"digest"`
|
||||
// Tag is the image tag
|
||||
Tag string `json:"tag"`
|
||||
// URL is the image url
|
||||
URL string `json:"url"`
|
||||
// CreateTime is the image create time
|
||||
CreateTime time.Time `json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
// ImageRepository is the image repository
|
||||
type ImageRepository struct {
|
||||
// Name is the image repository name
|
||||
Name string `json:"name"`
|
||||
// Namespace is the image repository namespace
|
||||
Namespace string `json:"namespace"`
|
||||
// FullName is the image repository full name
|
||||
FullName string `json:"fullName"`
|
||||
// Region is the image repository region
|
||||
Region string `json:"region,omitempty"`
|
||||
// Type is the image repository type, public or private
|
||||
Type string `json:"type"`
|
||||
// CreateTime is the image repository create time
|
||||
CreateTime time.Time `json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
// TableName return custom table name
|
||||
func (a *ApplicationRevision) TableName() string {
|
||||
return tableNamePrefix + "application_revision"
|
||||
@@ -280,6 +320,28 @@ const (
|
||||
PayloadTypeCustom = "custom"
|
||||
// PayloadTypeDockerhub is the payload type dockerhub
|
||||
PayloadTypeDockerhub = "dockerhub"
|
||||
// PayloadTypeACR is the payload type acr
|
||||
PayloadTypeACR = "acr"
|
||||
// PayloadTypeHarbor is the payload type harbor
|
||||
PayloadTypeHarbor = "harbor"
|
||||
// PayloadTypeJFrog is the payload type jfrog
|
||||
PayloadTypeJFrog = "jfrog"
|
||||
|
||||
// ComponentTypeWebservice is the component type webservice
|
||||
ComponentTypeWebservice = "webservice"
|
||||
// ComponentTypeWorker is the component type worker
|
||||
ComponentTypeWorker = "worker"
|
||||
// ComponentTypeTask is the component type task
|
||||
ComponentTypeTask = "task"
|
||||
)
|
||||
|
||||
const (
|
||||
// HarborEventTypePushArtifact is the event type PUSH_ARTIFACT
|
||||
HarborEventTypePushArtifact = "PUSH_ARTIFACT"
|
||||
// JFrogEventTypePush is push event type of jfrog webhook
|
||||
JFrogEventTypePush = "pushed"
|
||||
// JFrogDomainDocker is webhook domain of jfrog docker
|
||||
JFrogDomainDocker = "docker"
|
||||
)
|
||||
|
||||
// TableName return custom table name
|
||||
|
||||
47
pkg/apiserver/model/system_info.go
Normal file
47
pkg/apiserver/model/system_info.go
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package model
|
||||
|
||||
func init() {
|
||||
RegistModel(&SystemInfo{})
|
||||
}
|
||||
|
||||
// SystemInfo systemInfo model
|
||||
type SystemInfo struct {
|
||||
BaseModel
|
||||
InstallID string `json:"installID"`
|
||||
EnableCollection bool `json:"enableCollection"`
|
||||
}
|
||||
|
||||
// TableName return custom table name
|
||||
func (u *SystemInfo) TableName() string {
|
||||
return tableNamePrefix + "system_info"
|
||||
}
|
||||
|
||||
// PrimaryKey return custom primary key
|
||||
func (u *SystemInfo) PrimaryKey() string {
|
||||
return u.InstallID
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (u *SystemInfo) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
if u.InstallID != "" {
|
||||
index["installID"] = u.InstallID
|
||||
}
|
||||
return index
|
||||
}
|
||||
@@ -341,25 +341,27 @@ type UpdateApplicationRequest struct {
|
||||
|
||||
// CreateApplicationTriggerRequest create application trigger
|
||||
type CreateApplicationTriggerRequest struct {
|
||||
Name string `json:"name" validate:"checkname"`
|
||||
Alias string `json:"alias" validate:"checkalias" optional:"true"`
|
||||
Description string `json:"description" optional:"true"`
|
||||
WorkflowName string `json:"workflowName"`
|
||||
Type string `json:"type" validate:"oneof=webhook"`
|
||||
PayloadType string `json:"payloadType" validate:"oneof=custom"`
|
||||
Name string `json:"name" validate:"checkname"`
|
||||
Alias string `json:"alias" validate:"checkalias" optional:"true"`
|
||||
Description string `json:"description" optional:"true"`
|
||||
WorkflowName string `json:"workflowName"`
|
||||
Type string `json:"type" validate:"oneof=webhook"`
|
||||
PayloadType string `json:"payloadType" validate:"checkpayloadtype"`
|
||||
ComponentName string `json:"componentName,omitempty" optional:"true"`
|
||||
}
|
||||
|
||||
// ApplicationTriggerBase application trigger base model
|
||||
type ApplicationTriggerBase struct {
|
||||
Name string `json:"name"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
WorkflowName string `json:"workflowName"`
|
||||
Type string `json:"type"`
|
||||
PayloadType string `json:"payloadType"`
|
||||
Token string `json:"token"`
|
||||
CreateTime time.Time `json:"createTime"`
|
||||
UpdateTime time.Time `json:"updateTime"`
|
||||
Name string `json:"name"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
WorkflowName string `json:"workflowName"`
|
||||
Type string `json:"type"`
|
||||
PayloadType string `json:"payloadType"`
|
||||
Token string `json:"token"`
|
||||
ComponentName string `json:"componentName,omitempty"`
|
||||
CreateTime time.Time `json:"createTime"`
|
||||
UpdateTime time.Time `json:"updateTime"`
|
||||
}
|
||||
|
||||
// ListApplicationTriggerResponse list application triggers response body
|
||||
@@ -367,16 +369,123 @@ type ListApplicationTriggerResponse struct {
|
||||
Triggers []*ApplicationTriggerBase `json:"triggers"`
|
||||
}
|
||||
|
||||
// HandleApplicationWebhookRequest handles application webhook request
|
||||
type HandleApplicationWebhookRequest struct {
|
||||
// HandleApplicationTriggerWebhookRequest handles application trigger webhook request
|
||||
type HandleApplicationTriggerWebhookRequest struct {
|
||||
Upgrade map[string]*model.JSONStruct `json:"upgrade,omitempty"`
|
||||
CodeInfo *model.CodeInfo `json:"codeInfo,omitempty"`
|
||||
}
|
||||
|
||||
// HandleApplicationTriggerACRRequest handles application trigger ACR request
|
||||
type HandleApplicationTriggerACRRequest struct {
|
||||
PushData ACRPushData `json:"push_data"`
|
||||
Repository ACRRepository `json:"repository"`
|
||||
}
|
||||
|
||||
// ACRPushData is the push data of ACR
|
||||
type ACRPushData struct {
|
||||
Digest string `json:"digest"`
|
||||
PushedAt string `json:"pushed_at"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
|
||||
// ACRRepository is the repository of ACR
|
||||
type ACRRepository struct {
|
||||
DateCreated string `json:"date_created"`
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
Region string `json:"region"`
|
||||
RepoAuthenticationType string `json:"repo_authentication_type"`
|
||||
RepoFullName string `json:"repo_full_name"`
|
||||
RepoOriginType string `json:"repo_origin_type"`
|
||||
RepoType string `json:"repo_type"`
|
||||
}
|
||||
|
||||
// HandleApplicationHarborReq handles application trigger harbor request
|
||||
type HandleApplicationHarborReq struct {
|
||||
Type string `json:"type"`
|
||||
OccurAt int64 `json:"occur_at"`
|
||||
Operator string `json:"operator"`
|
||||
EventData EventData `json:"event_data"`
|
||||
}
|
||||
|
||||
// Resources is the image info of harbor
|
||||
type Resources struct {
|
||||
Digest string `json:"digest"`
|
||||
Tag string `json:"tag"`
|
||||
ResourceURL string `json:"resource_url"`
|
||||
}
|
||||
|
||||
// Repository is the repository of harbor
|
||||
type Repository struct {
|
||||
DateCreated int64 `json:"date_created"`
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
RepoFullName string `json:"repo_full_name"`
|
||||
RepoType string `json:"repo_type"`
|
||||
}
|
||||
|
||||
// EventData is the event info of harbor
|
||||
type EventData struct {
|
||||
Resources []Resources `json:"resources"`
|
||||
Repository Repository `json:"repository"`
|
||||
}
|
||||
|
||||
// HandleApplicationTriggerDockerHubRequest application trigger DockerHub webhook request
|
||||
type HandleApplicationTriggerDockerHubRequest struct {
|
||||
CallbackURL string `json:"callback_url"`
|
||||
PushData DockerHubData `json:"push_data"`
|
||||
Repository DockerHubRepository `json:"repository"`
|
||||
}
|
||||
|
||||
// DockerHubData is the push data of dockerhub
|
||||
type DockerHubData struct {
|
||||
Images []string `json:"images"`
|
||||
PushedAt int64 `json:"pushed_at"`
|
||||
Pusher string `json:"pusher"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
|
||||
// DockerHubRepository is the repository of dockerhub
|
||||
type DockerHubRepository struct {
|
||||
CommentCount int `json:"comment_count"`
|
||||
DateCreated int64 `json:"date_created"`
|
||||
Description string `json:"description"`
|
||||
Dockerfile string `json:"dockerfile"`
|
||||
FullDescription string `json:"full_description"`
|
||||
IsOfficial bool `json:"is_official"`
|
||||
IsPrivate bool `json:"is_private"`
|
||||
IsTrusted bool `json:"is_trusted"`
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
Owner string `json:"owner"`
|
||||
RepoName string `json:"repo_name"`
|
||||
RepoURL string `json:"repo_url"`
|
||||
StartCount int `json:"star_count"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// HandleApplicationTriggerJFrogRequest application trigger JFrog webhook request
|
||||
type HandleApplicationTriggerJFrogRequest struct {
|
||||
Domain string `json:"domain"`
|
||||
EventType string `json:"event_type"`
|
||||
Data JFrogWebhookData `json:"data"`
|
||||
}
|
||||
|
||||
// JFrogWebhookData is the data of JFrog webhook request
|
||||
type JFrogWebhookData struct {
|
||||
URL string
|
||||
ImageName string `json:"image_name"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
RepoKey string `json:"repo_key"`
|
||||
Digest string `json:"sha256"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
|
||||
// EnvBinding application env binding
|
||||
type EnvBinding struct {
|
||||
Name string `json:"name" validate:"checkname"`
|
||||
//TODO: support componentsPatch
|
||||
// TODO: support componentsPatch
|
||||
}
|
||||
|
||||
// EnvBindingTarget the target struct in the envbinding base struct
|
||||
@@ -761,7 +870,9 @@ type ApplicationDeployRequest struct {
|
||||
// Force set to True to ignore unfinished events.
|
||||
Force bool `json:"force"`
|
||||
// CodeInfo is the source code info of this deploy
|
||||
CodeInfo *model.CodeInfo `json:"gitInfo,omitempty"`
|
||||
CodeInfo *model.CodeInfo `json:"codeInfo,omitempty"`
|
||||
// ImageInfo is the image code info of this deploy
|
||||
ImageInfo *model.ImageInfo `json:"imageInfo,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationDeployResponse application deploy response body
|
||||
@@ -769,6 +880,14 @@ type ApplicationDeployResponse struct {
|
||||
ApplicationRevisionBase
|
||||
}
|
||||
|
||||
// ApplicationDockerhubWebhookResponse dockerhub webhook response body
|
||||
type ApplicationDockerhubWebhookResponse struct {
|
||||
State string `json:"state,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Context string `json:"context,omitempty"`
|
||||
TargetURL string `json:"target_url,omitempty"`
|
||||
}
|
||||
|
||||
// VelaQLViewResponse query response
|
||||
type VelaQLViewResponse map[string]interface{}
|
||||
|
||||
@@ -872,6 +991,8 @@ type ApplicationRevisionBase struct {
|
||||
TriggerType string `json:"triggerType"`
|
||||
// CodeInfo is the code info of this application revision
|
||||
CodeInfo *model.CodeInfo `json:"codeInfo,omitempty"`
|
||||
// ImageInfo is the image info of this application revision
|
||||
ImageInfo *model.ImageInfo `json:"imageInfo,omitempty"`
|
||||
}
|
||||
|
||||
// ListRevisionsResponse list application revisions
|
||||
@@ -884,3 +1005,20 @@ type ListRevisionsResponse struct {
|
||||
type DetailRevisionResponse struct {
|
||||
model.ApplicationRevision
|
||||
}
|
||||
|
||||
// SystemInfoResponse get SystemInfo
|
||||
type SystemInfoResponse struct {
|
||||
model.SystemInfo
|
||||
SystemVersion SystemVersion `json:"systemVersion"`
|
||||
}
|
||||
|
||||
// SystemInfoRequest request by update SystemInfo
|
||||
type SystemInfoRequest struct {
|
||||
EnableCollection bool
|
||||
}
|
||||
|
||||
// SystemVersion contains KubeVela version
|
||||
type SystemVersion struct {
|
||||
VelaVersion string `json:"velaVersion"`
|
||||
GitVersion string `json:"gitVersion"`
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/usecase"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/webservice"
|
||||
utils2 "github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
|
||||
var _ APIServer = &restServer{}
|
||||
@@ -214,8 +215,8 @@ func (s *restServer) requestLog(req *restful.Request, resp *restful.Response, ch
|
||||
chain.ProcessFilter(req, resp)
|
||||
takeTime := time.Since(start)
|
||||
log.Logger.With(
|
||||
"clientIP", utils.ClientIP(req.Request),
|
||||
"path", req.Request.URL.Path,
|
||||
"clientIP", utils2.Sanitize(utils.ClientIP(req.Request)),
|
||||
"path", utils2.Sanitize(req.Request.URL.Path),
|
||||
"method", req.Request.Method,
|
||||
"status", c.StatusCode(),
|
||||
"time", takeTime.String(),
|
||||
|
||||
@@ -18,6 +18,7 @@ package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
@@ -25,6 +26,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
k8stypes "k8s.io/apimachinery/pkg/types"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
errors2 "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
@@ -39,6 +42,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/clients"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/log"
|
||||
apis "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils/bcode"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/apply"
|
||||
@@ -155,7 +159,9 @@ func (u *defaultAddonHandler) GetAddon(ctx context.Context, name string, registr
|
||||
if addon == nil {
|
||||
return nil, bcode.ErrAddonNotExist
|
||||
}
|
||||
addon.UISchema = renderDefaultUISchema(addon.APISchema)
|
||||
|
||||
addon.UISchema = renderAddonCustomUISchema(ctx, u.kubeClient, name, renderDefaultUISchema(addon.APISchema))
|
||||
|
||||
a, err := AddonImpl2AddonRes(addon)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -455,6 +461,29 @@ func convertAppStateToAddonPhase(state common2.ApplicationPhase) apis.AddonPhase
|
||||
}
|
||||
}
|
||||
|
||||
func renderAddonCustomUISchema(ctx context.Context, cli client.Client, addonName string, defaultSchema []*utils.UIParameter) []*utils.UIParameter {
|
||||
var cm v1.ConfigMap
|
||||
if err := cli.Get(ctx, k8stypes.NamespacedName{
|
||||
Namespace: types.DefaultKubeVelaNS,
|
||||
Name: fmt.Sprintf("addon-uischema-%s", addonName),
|
||||
}, &cm); err != nil {
|
||||
if !errors2.IsNotFound(err) {
|
||||
log.Logger.Errorf("find uischema configmap from cluster failure %s", err.Error())
|
||||
}
|
||||
return defaultSchema
|
||||
}
|
||||
data, ok := cm.Data[types.UISchema]
|
||||
if !ok {
|
||||
return defaultSchema
|
||||
}
|
||||
schema := []*utils.UIParameter{}
|
||||
if err := json.Unmarshal([]byte(data), &schema); err != nil {
|
||||
log.Logger.Errorf("unmarshal ui schema failure %s", err.Error())
|
||||
return defaultSchema
|
||||
}
|
||||
return patchSchema(defaultSchema, schema)
|
||||
}
|
||||
|
||||
// ConvertAddonRegistryModel2AddonRegistryMeta will convert from model to AddonRegistry
|
||||
func ConvertAddonRegistryModel2AddonRegistryMeta(r pkgaddon.Registry) apis.AddonRegistry {
|
||||
return apis.AddonRegistry{
|
||||
|
||||
106
pkg/apiserver/rest/usecase/addon_test.go
Normal file
106
pkg/apiserver/rest/usecase/addon_test.go
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils"
|
||||
)
|
||||
|
||||
var _ = Describe("addon usecase test", func() {
|
||||
var ctx context.Context
|
||||
|
||||
BeforeEach(func() {
|
||||
ctx = context.Background()
|
||||
Expect(k8sClient.Create(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: types.DefaultKubeVelaNS}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
|
||||
})
|
||||
|
||||
It("Test render customize ui-schema", func() {
|
||||
schemaData, err := ioutil.ReadFile("testdata/addon-uischema-test.yaml")
|
||||
|
||||
addonName := "test"
|
||||
Expect(err).Should(BeNil())
|
||||
jsonData, err := yaml.YAMLToJSON(schemaData)
|
||||
Expect(err).Should(BeNil())
|
||||
cm := v1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: types.DefaultKubeVelaNS, Name: fmt.Sprintf("addon-uischema-%s", addonName)},
|
||||
Data: map[string]string{
|
||||
types.UISchema: string(jsonData),
|
||||
}}
|
||||
|
||||
Expect(k8sClient.Create(ctx, &cm)).Should(BeNil())
|
||||
defaultSchema := []*utils.UIParameter{
|
||||
{
|
||||
JSONKey: "version",
|
||||
Sort: 3,
|
||||
},
|
||||
{
|
||||
JSONKey: "domain",
|
||||
Sort: 8,
|
||||
},
|
||||
}
|
||||
res := renderAddonCustomUISchema(ctx, k8sClient, addonName, defaultSchema)
|
||||
Expect(len(res)).Should(BeEquivalentTo(2))
|
||||
for _, re := range res {
|
||||
if re.JSONKey == "version" {
|
||||
Expect(re.Validate.DefaultValue.(string)).Should(BeEquivalentTo("1.2.0-rc1"))
|
||||
Expect(re.Sort).Should(BeEquivalentTo(1))
|
||||
}
|
||||
if re.JSONKey == "domain" {
|
||||
Expect(re.Sort).Should(BeEquivalentTo(9))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
It("Test render without ui-schema", func() {
|
||||
addonName := "test-without-schema"
|
||||
defaultSchema := []*utils.UIParameter{
|
||||
{
|
||||
JSONKey: "version",
|
||||
Sort: 3,
|
||||
},
|
||||
{
|
||||
JSONKey: "domain",
|
||||
Sort: 8,
|
||||
},
|
||||
}
|
||||
res := renderAddonCustomUISchema(ctx, k8sClient, addonName, defaultSchema)
|
||||
Expect(len(res)).Should(BeEquivalentTo(2))
|
||||
for _, re := range res {
|
||||
if re.JSONKey == "version" {
|
||||
Expect(re.Validate).Should(BeNil())
|
||||
Expect(re.Sort).Should(BeEquivalentTo(3))
|
||||
}
|
||||
if re.JSONKey == "domain" {
|
||||
Expect(re.Sort).Should(BeEquivalentTo(8))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -93,6 +93,7 @@ type ApplicationUsecase interface {
|
||||
ListRecords(ctx context.Context, appName string) (*apisv1.ListWorkflowRecordsResponse, error)
|
||||
CreateApplicationTrigger(ctx context.Context, app *model.Application, req apisv1.CreateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error)
|
||||
ListApplicationTriggers(ctx context.Context, app *model.Application) ([]*apisv1.ApplicationTriggerBase, error)
|
||||
DeleteApplicationTrigger(ctx context.Context, app *model.Application, triggerName string) error
|
||||
}
|
||||
|
||||
type applicationUsecaseImpl struct {
|
||||
@@ -143,7 +144,7 @@ func listApp(ctx context.Context, ds datastore.DataStore, listOptions apisv1.Lis
|
||||
if listOptions.Env != "" || listOptions.TargetName != "" {
|
||||
envBinding, err = listFullEnvBinding(ctx, ds, envListOption{})
|
||||
if err != nil {
|
||||
log.Logger.Errorf("list envbinding for list application in env %s err %v", listOptions.Env, err)
|
||||
log.Logger.Errorf("list envbinding for list application in env %s err %v", utils2.Sanitize(listOptions.Env), err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -385,16 +386,35 @@ func (c *applicationUsecaseImpl) CreateApplicationTrigger(ctx context.Context, a
|
||||
}
|
||||
|
||||
return &apisv1.ApplicationTriggerBase{
|
||||
WorkflowName: req.WorkflowName,
|
||||
Name: req.Name,
|
||||
Alias: req.Alias,
|
||||
Description: req.Description,
|
||||
Type: req.Type,
|
||||
PayloadType: req.PayloadType,
|
||||
Token: trigger.Token,
|
||||
WorkflowName: req.WorkflowName,
|
||||
Name: req.Name,
|
||||
Alias: req.Alias,
|
||||
Description: req.Description,
|
||||
Type: req.Type,
|
||||
PayloadType: req.PayloadType,
|
||||
Token: trigger.Token,
|
||||
ComponentName: req.ComponentName,
|
||||
CreateTime: trigger.CreateTime,
|
||||
UpdateTime: trigger.UpdateTime,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteApplicationTrigger delete application trigger
|
||||
func (c *applicationUsecaseImpl) DeleteApplicationTrigger(ctx context.Context, app *model.Application, token string) error {
|
||||
trigger := model.ApplicationTrigger{
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
Token: token,
|
||||
}
|
||||
if err := c.ds.Delete(ctx, &trigger); err != nil {
|
||||
if errors.Is(err, datastore.ErrRecordNotExist) {
|
||||
return bcode.ErrApplicationTriggerNotExist
|
||||
}
|
||||
log.Logger.Warnf("delete app trigger failure %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListApplicationTrigger list application triggers
|
||||
func (c *applicationUsecaseImpl) ListApplicationTriggers(ctx context.Context, app *model.Application) ([]*apisv1.ApplicationTriggerBase, error) {
|
||||
trigger := &model.ApplicationTrigger{
|
||||
@@ -686,8 +706,8 @@ func (c *applicationUsecaseImpl) Deploy(ctx context.Context, app *model.Applicat
|
||||
WorkflowName: oamApp.Annotations[oam.AnnotationWorkflowName],
|
||||
EnvName: workflow.EnvName,
|
||||
CodeInfo: req.CodeInfo,
|
||||
ImageInfo: req.ImageInfo,
|
||||
}
|
||||
|
||||
if err := c.ds.Add(ctx, appRevision); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -903,6 +923,7 @@ func (c *applicationUsecaseImpl) converRevisionModelToBase(revision *model.Appli
|
||||
CreateTime: revision.CreateTime,
|
||||
EnvName: revision.EnvName,
|
||||
CodeInfo: revision.CodeInfo,
|
||||
ImageInfo: revision.ImageInfo,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -164,6 +164,34 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(len(triggers)).Should(Equal(2))
|
||||
})
|
||||
|
||||
It("Test DeleteTrigger function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), testApp)
|
||||
Expect(err).Should(BeNil())
|
||||
triggers, err := appUsecase.ListApplicationTriggers(context.TODO(), appModel)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(triggers)).Should(Equal(2))
|
||||
var trigger *v1.ApplicationTriggerBase
|
||||
for _, t := range triggers {
|
||||
if t.Name == "trigger-name" {
|
||||
trigger = t
|
||||
break
|
||||
}
|
||||
}
|
||||
Expect(trigger).ShouldNot(BeNil())
|
||||
Expect(appUsecase.DeleteApplicationTrigger(context.TODO(), appModel, trigger.Token)).Should(BeNil())
|
||||
triggers, err = appUsecase.ListApplicationTriggers(context.TODO(), appModel)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(triggers)).Should(Equal(1))
|
||||
trigger = nil
|
||||
for _, t := range triggers {
|
||||
if t.Name == "trigger-name" {
|
||||
trigger = t
|
||||
break
|
||||
}
|
||||
}
|
||||
Expect(trigger).Should(BeNil())
|
||||
})
|
||||
|
||||
It("Test ListComponents function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), testApp)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils/bcode"
|
||||
utils2 "github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -184,7 +185,7 @@ func (e *envBindingUsecaseImpl) BatchCreateEnvBinding(ctx context.Context, app *
|
||||
continue
|
||||
}
|
||||
if err := e.ds.Add(ctx, envBindingModel); err != nil {
|
||||
log.Logger.Errorf("add envbinding %s failure %s", envBindingModel.Name, err.Error())
|
||||
log.Logger.Errorf("add envbinding %s failure %s", utils2.Sanitize(envBindingModel.Name), err.Error())
|
||||
continue
|
||||
}
|
||||
err = e.createEnvWorkflow(ctx, app, env, i == 0)
|
||||
|
||||
93
pkg/apiserver/rest/usecase/system_info.go
Normal file
93
pkg/apiserver/rest/usecase/system_info.go
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/oam-dev/kubevela/version"
|
||||
|
||||
v1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/rand"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/model"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
|
||||
)
|
||||
|
||||
// SystemInfoUsecase is usecase for systemInfoCollection
|
||||
type SystemInfoUsecase interface {
|
||||
GetSystemInfo(ctx context.Context) (*v1.SystemInfoResponse, error)
|
||||
DeleteSystemInfo(ctx context.Context) error
|
||||
UpdateSystemInfo(ctx context.Context, sysInfo v1.SystemInfoRequest) (*v1.SystemInfoResponse, error)
|
||||
}
|
||||
|
||||
type systemInfoUsecaseImpl struct {
|
||||
ds datastore.DataStore
|
||||
}
|
||||
|
||||
// NewSystemInfoUsecase return a systemInfoCollectionUsecase
|
||||
func NewSystemInfoUsecase(ds datastore.DataStore) SystemInfoUsecase {
|
||||
return &systemInfoUsecaseImpl{ds: ds}
|
||||
}
|
||||
|
||||
func (u systemInfoUsecaseImpl) GetSystemInfo(ctx context.Context) (*v1.SystemInfoResponse, error) {
|
||||
// first get request will init systemInfoCollection{installId: {random}, enableCollection: true}
|
||||
info := &model.SystemInfo{}
|
||||
entities, err := u.ds.List(ctx, info, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(entities) != 0 {
|
||||
info := entities[0].(*model.SystemInfo)
|
||||
return &v1.SystemInfoResponse{SystemInfo: *info, SystemVersion: v1.SystemVersion{VelaVersion: version.VelaVersion, GitVersion: version.GitRevision}}, nil
|
||||
}
|
||||
installID := rand.String(16)
|
||||
info.InstallID = installID
|
||||
info.EnableCollection = true
|
||||
err = u.ds.Add(ctx, info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.SystemInfoResponse{SystemInfo: *info, SystemVersion: v1.SystemVersion{VelaVersion: version.VelaVersion, GitVersion: version.GitRevision}}, nil
|
||||
}
|
||||
|
||||
func (u systemInfoUsecaseImpl) UpdateSystemInfo(ctx context.Context, sysInfo v1.SystemInfoRequest) (*v1.SystemInfoResponse, error) {
|
||||
info, err := u.GetSystemInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
modifiedInfo := model.SystemInfo{InstallID: info.InstallID, EnableCollection: sysInfo.EnableCollection, BaseModel: model.BaseModel{CreateTime: info.CreateTime}}
|
||||
err = u.ds.Put(ctx, &modifiedInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.SystemInfoResponse{SystemInfo: modifiedInfo, SystemVersion: v1.SystemVersion{VelaVersion: version.VelaVersion, GitVersion: version.GitRevision}}, nil
|
||||
}
|
||||
|
||||
func (u systemInfoUsecaseImpl) DeleteSystemInfo(ctx context.Context) error {
|
||||
info, err := u.GetSystemInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = u.ds.Delete(ctx, info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
18
pkg/apiserver/rest/usecase/testdata/addon-uischema-test.yaml
vendored
Normal file
18
pkg/apiserver/rest/usecase/testdata/addon-uischema-test.yaml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
- jsonKey: version
|
||||
validate:
|
||||
defaultValue: 1.2.0-rc1
|
||||
sort: 1
|
||||
- jsonKey: dbType
|
||||
label: DBType
|
||||
validate:
|
||||
defaultValue: kubeapi
|
||||
sort: 3
|
||||
- jsonKey: dbURL
|
||||
label: DBURL
|
||||
sort: 5
|
||||
- jsonKey: database
|
||||
sort: 7
|
||||
validate:
|
||||
defaultValue: kubevela
|
||||
- jsonKey: domain
|
||||
sort: 9
|
||||
@@ -19,10 +19,14 @@ package usecase
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful/v3"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/log"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/model"
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils/bcode"
|
||||
@@ -31,7 +35,7 @@ import (
|
||||
|
||||
// WebhookUsecase webhook usecase
|
||||
type WebhookUsecase interface {
|
||||
HandleApplicationWebhook(ctx context.Context, token string, req *restful.Request) (*apisv1.ApplicationDeployResponse, error)
|
||||
HandleApplicationWebhook(ctx context.Context, token string, req *restful.Request) (interface{}, error)
|
||||
}
|
||||
|
||||
type webhookUsecaseImpl struct {
|
||||
@@ -39,17 +43,82 @@ type webhookUsecaseImpl struct {
|
||||
applicationUsecase ApplicationUsecase
|
||||
}
|
||||
|
||||
// WebhookHandlers is the webhook handlers
|
||||
var WebhookHandlers []string
|
||||
|
||||
// NewWebhookUsecase new webhook usecase
|
||||
func NewWebhookUsecase(ds datastore.DataStore,
|
||||
applicationUsecase ApplicationUsecase,
|
||||
) WebhookUsecase {
|
||||
registerHandlers()
|
||||
return &webhookUsecaseImpl{
|
||||
ds: ds,
|
||||
applicationUsecase: applicationUsecase,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) HandleApplicationWebhook(ctx context.Context, token string, req *restful.Request) (*apisv1.ApplicationDeployResponse, error) {
|
||||
func registerHandlers() {
|
||||
new(customHandlerImpl).install()
|
||||
new(acrHandlerImpl).install()
|
||||
new(dockerHubHandlerImpl).install()
|
||||
new(harborHandlerImpl).install()
|
||||
new(jfrogHandlerImpl).install()
|
||||
}
|
||||
|
||||
type webhookHandler interface {
|
||||
handle(ctx context.Context, trigger *model.ApplicationTrigger, app *model.Application) (interface{}, error)
|
||||
install()
|
||||
}
|
||||
|
||||
type customHandlerImpl struct {
|
||||
req apisv1.HandleApplicationTriggerWebhookRequest
|
||||
w *webhookUsecaseImpl
|
||||
}
|
||||
|
||||
type acrHandlerImpl struct {
|
||||
req apisv1.HandleApplicationTriggerACRRequest
|
||||
w *webhookUsecaseImpl
|
||||
}
|
||||
|
||||
type dockerHubHandlerImpl struct {
|
||||
req apisv1.HandleApplicationTriggerDockerHubRequest
|
||||
w *webhookUsecaseImpl
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) newCustomHandler(req *restful.Request) (webhookHandler, error) {
|
||||
var webhookReq apisv1.HandleApplicationTriggerWebhookRequest
|
||||
if err := req.ReadEntity(&webhookReq); err != nil {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
return &customHandlerImpl{
|
||||
req: webhookReq,
|
||||
w: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) newACRHandler(req *restful.Request) (webhookHandler, error) {
|
||||
var acrReq apisv1.HandleApplicationTriggerACRRequest
|
||||
if err := req.ReadEntity(&acrReq); err != nil {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
return &acrHandlerImpl{
|
||||
req: acrReq,
|
||||
w: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) newDockerHubHandler(req *restful.Request) (webhookHandler, error) {
|
||||
var dockerHubReq apisv1.HandleApplicationTriggerDockerHubRequest
|
||||
if err := req.ReadEntity(&dockerHubReq); err != nil {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
return &dockerHubHandlerImpl{
|
||||
req: dockerHubReq,
|
||||
w: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) HandleApplicationWebhook(ctx context.Context, token string, req *restful.Request) (interface{}, error) {
|
||||
webhookTrigger := &model.ApplicationTrigger{
|
||||
Token: token,
|
||||
}
|
||||
@@ -68,44 +137,366 @@ func (c *webhookUsecaseImpl) HandleApplicationWebhook(ctx context.Context, token
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var handler webhookHandler
|
||||
var err error
|
||||
switch webhookTrigger.PayloadType {
|
||||
case model.PayloadTypeCustom:
|
||||
var webhookReq apisv1.HandleApplicationWebhookRequest
|
||||
if err := req.ReadEntity(&webhookReq); err != nil {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
handler, err = c.newCustomHandler(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for comp, properties := range webhookReq.Upgrade {
|
||||
component := &model.ApplicationComponent{
|
||||
AppPrimaryKey: webhookTrigger.AppPrimaryKey,
|
||||
Name: comp,
|
||||
}
|
||||
if err := c.ds.Get(ctx, component); err != nil {
|
||||
if errors.Is(err, datastore.ErrRecordNotExist) {
|
||||
return nil, bcode.ErrApplicationComponetNotExist
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
merge, err := envbinding.MergeRawExtension(component.Properties.RawExtension(), properties.RawExtension())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prop, err := model.NewJSONStructByStruct(merge)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
component.Properties = prop
|
||||
if err := c.ds.Put(ctx, component); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case model.PayloadTypeACR:
|
||||
handler, err = c.newACRHandler(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case model.PayloadTypeHarbor:
|
||||
handler, err = c.newHarborHandler(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case model.PayloadTypeDockerhub:
|
||||
handler, err = c.newDockerHubHandler(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case model.PayloadTypeJFrog:
|
||||
handler, err = c.newJFrogHandler(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.applicationUsecase.Deploy(ctx, app, apisv1.ApplicationDeployRequest{
|
||||
WorkflowName: webhookTrigger.WorkflowName,
|
||||
Note: "triggered by webhook",
|
||||
TriggerType: apisv1.TriggerTypeWebhook,
|
||||
Force: true,
|
||||
CodeInfo: webhookReq.CodeInfo,
|
||||
})
|
||||
default:
|
||||
return nil, bcode.ErrInvalidWebhookPayloadType
|
||||
}
|
||||
|
||||
return handler.handle(ctx, webhookTrigger, app)
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) patchComponentProperties(ctx context.Context, component *model.ApplicationComponent, patch *runtime.RawExtension) error {
|
||||
merge, err := envbinding.MergeRawExtension(component.Properties.RawExtension(), patch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prop, err := model.NewJSONStructByStruct(merge)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
component.Properties = prop
|
||||
if err := c.ds.Put(ctx, component); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *customHandlerImpl) handle(ctx context.Context, webhookTrigger *model.ApplicationTrigger, app *model.Application) (interface{}, error) {
|
||||
for comp, properties := range c.req.Upgrade {
|
||||
component := &model.ApplicationComponent{
|
||||
AppPrimaryKey: webhookTrigger.AppPrimaryKey,
|
||||
Name: comp,
|
||||
}
|
||||
if err := c.w.ds.Get(ctx, component); err != nil {
|
||||
if errors.Is(err, datastore.ErrRecordNotExist) {
|
||||
return nil, bcode.ErrApplicationComponetNotExist
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if err := c.w.patchComponentProperties(ctx, component, properties.RawExtension()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c.w.applicationUsecase.Deploy(ctx, app, apisv1.ApplicationDeployRequest{
|
||||
WorkflowName: webhookTrigger.WorkflowName,
|
||||
Note: "triggered by webhook custom",
|
||||
TriggerType: apisv1.TriggerTypeWebhook,
|
||||
Force: true,
|
||||
CodeInfo: c.req.CodeInfo,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *customHandlerImpl) install() {
|
||||
WebhookHandlers = append(WebhookHandlers, model.PayloadTypeCustom)
|
||||
}
|
||||
|
||||
func (c *acrHandlerImpl) handle(ctx context.Context, webhookTrigger *model.ApplicationTrigger, app *model.Application) (interface{}, error) {
|
||||
comp := &model.ApplicationComponent{
|
||||
AppPrimaryKey: webhookTrigger.AppPrimaryKey,
|
||||
}
|
||||
comps, err := c.w.ds.List(ctx, comp, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(comps) == 0 {
|
||||
return nil, bcode.ErrApplicationComponetNotExist
|
||||
}
|
||||
|
||||
// use the first component as the target component
|
||||
component := comps[0].(*model.ApplicationComponent)
|
||||
acrReq := c.req
|
||||
image := fmt.Sprintf("registry.%s.aliyuncs.com/%s:%s", acrReq.Repository.Region, acrReq.Repository.RepoFullName, acrReq.PushData.Tag)
|
||||
if err := c.w.patchComponentProperties(ctx, component, &runtime.RawExtension{
|
||||
Raw: []byte(fmt.Sprintf(`{"image": "%s"}`, image)),
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.w.applicationUsecase.Deploy(ctx, app, apisv1.ApplicationDeployRequest{
|
||||
WorkflowName: webhookTrigger.WorkflowName,
|
||||
Note: "triggered by webhook acr",
|
||||
TriggerType: apisv1.TriggerTypeWebhook,
|
||||
Force: true,
|
||||
ImageInfo: &model.ImageInfo{
|
||||
Type: model.PayloadTypeACR,
|
||||
Resource: &model.ImageResource{
|
||||
Digest: acrReq.PushData.Digest,
|
||||
Tag: acrReq.PushData.Tag,
|
||||
URL: image,
|
||||
CreateTime: parseTimeString(acrReq.PushData.PushedAt),
|
||||
},
|
||||
Repository: &model.ImageRepository{
|
||||
Name: acrReq.Repository.Name,
|
||||
Namespace: acrReq.Repository.Namespace,
|
||||
FullName: acrReq.Repository.RepoFullName,
|
||||
Region: acrReq.Repository.Region,
|
||||
Type: acrReq.Repository.RepoType,
|
||||
CreateTime: parseTimeString(acrReq.Repository.DateCreated),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (c *acrHandlerImpl) install() {
|
||||
WebhookHandlers = append(WebhookHandlers, model.PayloadTypeACR)
|
||||
}
|
||||
|
||||
func (c dockerHubHandlerImpl) handle(ctx context.Context, trigger *model.ApplicationTrigger, app *model.Application) (interface{}, error) {
|
||||
dockerHubReq := c.req
|
||||
if dockerHubReq.Repository.Status != "Active" {
|
||||
log.Logger.Debugf("receive dockerhub webhook but not create event: %v", dockerHubReq)
|
||||
return &apisv1.ApplicationDockerhubWebhookResponse{
|
||||
State: "failed",
|
||||
Description: "not create event",
|
||||
}, nil
|
||||
}
|
||||
|
||||
comp := &model.ApplicationComponent{
|
||||
AppPrimaryKey: trigger.AppPrimaryKey,
|
||||
}
|
||||
comps, err := c.w.ds.List(ctx, comp, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(comps) == 0 {
|
||||
return nil, bcode.ErrApplicationComponetNotExist
|
||||
}
|
||||
|
||||
// use the first component as the target component
|
||||
component := comps[0].(*model.ApplicationComponent)
|
||||
image := fmt.Sprintf("docker.io/%s:%s", dockerHubReq.Repository.RepoName, dockerHubReq.PushData.Tag)
|
||||
if err := c.w.patchComponentProperties(ctx, component, &runtime.RawExtension{
|
||||
Raw: []byte(fmt.Sprintf(`{"image": "%s"}`, image)),
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repositoryType := "public"
|
||||
if dockerHubReq.Repository.IsPrivate {
|
||||
repositoryType = "private"
|
||||
}
|
||||
|
||||
if _, err = c.w.applicationUsecase.Deploy(ctx, app, apisv1.ApplicationDeployRequest{
|
||||
WorkflowName: trigger.WorkflowName,
|
||||
Note: "triggered by webhook dockerhub",
|
||||
TriggerType: apisv1.TriggerTypeWebhook,
|
||||
Force: true,
|
||||
ImageInfo: &model.ImageInfo{
|
||||
Type: model.PayloadTypeDockerhub,
|
||||
Resource: &model.ImageResource{
|
||||
Tag: dockerHubReq.PushData.Tag,
|
||||
URL: image,
|
||||
CreateTime: time.Unix(dockerHubReq.PushData.PushedAt, 0),
|
||||
},
|
||||
Repository: &model.ImageRepository{
|
||||
Name: dockerHubReq.Repository.Name,
|
||||
Namespace: dockerHubReq.Repository.Namespace,
|
||||
FullName: dockerHubReq.Repository.RepoName,
|
||||
Type: repositoryType,
|
||||
CreateTime: time.Unix(dockerHubReq.Repository.DateCreated, 0),
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &apisv1.ApplicationDockerhubWebhookResponse{
|
||||
State: "success",
|
||||
Description: fmt.Sprintf("update application %s/%s success", app.Name, component.Name),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c dockerHubHandlerImpl) install() {
|
||||
WebhookHandlers = append(WebhookHandlers, model.PayloadTypeDockerhub)
|
||||
}
|
||||
|
||||
func parseTimeString(t string) time.Time {
|
||||
if t == "" {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
l, err := time.LoadLocation("PRC")
|
||||
if err != nil {
|
||||
log.Logger.Errorf("failed to load location: %v", err)
|
||||
return time.Time{}
|
||||
}
|
||||
parsedTime, err := time.ParseInLocation("2006-01-02 15:04:05", t, l)
|
||||
if err != nil {
|
||||
log.Logger.Errorf("failed to parse time: %v", err)
|
||||
return time.Time{}
|
||||
}
|
||||
return parsedTime
|
||||
}
|
||||
|
||||
type harborHandlerImpl struct {
|
||||
req apisv1.HandleApplicationHarborReq
|
||||
w *webhookUsecaseImpl
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) newHarborHandler(req *restful.Request) (webhookHandler, error) {
|
||||
var harborReq apisv1.HandleApplicationHarborReq
|
||||
if err := req.ReadEntity(&harborReq); err != nil {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
if harborReq.Type != model.HarborEventTypePushArtifact {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
return &harborHandlerImpl{
|
||||
req: harborReq,
|
||||
w: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *harborHandlerImpl) install() {
|
||||
WebhookHandlers = append(WebhookHandlers, model.PayloadTypeHarbor)
|
||||
}
|
||||
|
||||
func (c *harborHandlerImpl) handle(ctx context.Context, webhookTrigger *model.ApplicationTrigger, app *model.Application) (interface{}, error) {
|
||||
resources := c.req.EventData.Resources
|
||||
if len(resources) < 1 {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
imageURL := resources[0].ResourceURL
|
||||
digest := resources[0].Digest
|
||||
tag := resources[0].Tag
|
||||
comp := &model.ApplicationComponent{
|
||||
AppPrimaryKey: webhookTrigger.AppPrimaryKey,
|
||||
}
|
||||
comps, err := c.w.ds.List(ctx, comp, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(comps) == 0 {
|
||||
return nil, bcode.ErrApplicationComponetNotExist
|
||||
}
|
||||
|
||||
// use the first component as the target component
|
||||
component := comps[0].(*model.ApplicationComponent)
|
||||
harborReq := c.req
|
||||
if err := c.w.patchComponentProperties(ctx, component, &runtime.RawExtension{
|
||||
Raw: []byte(fmt.Sprintf(`{"image": "%s"}`, imageURL)),
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.w.applicationUsecase.Deploy(ctx, app, apisv1.ApplicationDeployRequest{
|
||||
WorkflowName: webhookTrigger.WorkflowName,
|
||||
Note: "triggered by webhook harbor",
|
||||
TriggerType: apisv1.TriggerTypeWebhook,
|
||||
Force: true,
|
||||
ImageInfo: &model.ImageInfo{
|
||||
Type: model.PayloadTypeHarbor,
|
||||
Resource: &model.ImageResource{
|
||||
Digest: digest,
|
||||
Tag: tag,
|
||||
URL: imageURL,
|
||||
CreateTime: time.Unix(harborReq.OccurAt, 0),
|
||||
},
|
||||
Repository: &model.ImageRepository{
|
||||
Name: harborReq.EventData.Repository.Name,
|
||||
Namespace: harborReq.EventData.Repository.Namespace,
|
||||
FullName: harborReq.EventData.Repository.RepoFullName,
|
||||
Type: harborReq.EventData.Repository.RepoType,
|
||||
CreateTime: time.Unix(harborReq.EventData.Repository.DateCreated, 0),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type jfrogHandlerImpl struct {
|
||||
req apisv1.HandleApplicationTriggerJFrogRequest
|
||||
w *webhookUsecaseImpl
|
||||
}
|
||||
|
||||
func (c *webhookUsecaseImpl) newJFrogHandler(req *restful.Request) (webhookHandler, error) {
|
||||
var jfrogReq apisv1.HandleApplicationTriggerJFrogRequest
|
||||
if err := req.ReadEntity(&jfrogReq); err != nil {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
if jfrogReq.Domain != model.JFrogDomainDocker || jfrogReq.EventType != model.JFrogEventTypePush {
|
||||
return nil, bcode.ErrInvalidWebhookPayloadBody
|
||||
}
|
||||
// jfrog should use request header to give URL, it is not exist in request body
|
||||
jfrogReq.Data.URL = req.HeaderParameter("X-JFrogURL")
|
||||
return &jfrogHandlerImpl{
|
||||
req: jfrogReq,
|
||||
w: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (j *jfrogHandlerImpl) handle(ctx context.Context, webhookTrigger *model.ApplicationTrigger, app *model.Application) (interface{}, error) {
|
||||
jfrogReq := j.req
|
||||
comp := &model.ApplicationComponent{
|
||||
AppPrimaryKey: webhookTrigger.AppPrimaryKey,
|
||||
}
|
||||
comps, err := j.w.ds.List(ctx, comp, &datastore.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(comps) == 0 {
|
||||
return nil, bcode.ErrApplicationComponetNotExist
|
||||
}
|
||||
|
||||
// use the first component as the target component
|
||||
component := comps[0].(*model.ApplicationComponent)
|
||||
image := fmt.Sprintf("%s/%s:%s", jfrogReq.Data.RepoKey, jfrogReq.Data.ImageName, jfrogReq.Data.Tag)
|
||||
if jfrogReq.Data.URL != "" {
|
||||
image = fmt.Sprintf("%s/%s", jfrogReq.Data.URL, image)
|
||||
}
|
||||
if err := j.w.patchComponentProperties(ctx, component, &runtime.RawExtension{
|
||||
Raw: []byte(fmt.Sprintf(`{"image": "%s"}`, image)),
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return j.w.applicationUsecase.Deploy(ctx, app, apisv1.ApplicationDeployRequest{
|
||||
WorkflowName: webhookTrigger.WorkflowName,
|
||||
Note: "triggered by webhook jfrog",
|
||||
TriggerType: apisv1.TriggerTypeWebhook,
|
||||
Force: true,
|
||||
ImageInfo: &model.ImageInfo{
|
||||
Type: model.PayloadTypeHarbor,
|
||||
Resource: &model.ImageResource{
|
||||
Digest: jfrogReq.Data.Digest,
|
||||
Tag: jfrogReq.Data.Tag,
|
||||
URL: image,
|
||||
},
|
||||
Repository: &model.ImageRepository{
|
||||
Name: jfrogReq.Data.ImageName,
|
||||
Namespace: jfrogReq.Data.RepoKey,
|
||||
FullName: fmt.Sprintf("%s/%s", jfrogReq.Data.RepoKey, jfrogReq.Data.ImageName),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (j *jfrogHandlerImpl) install() {
|
||||
WebhookHandlers = append(WebhookHandlers, model.PayloadTypeJFrog)
|
||||
}
|
||||
|
||||
@@ -106,7 +106,15 @@ var _ = Describe("Test application usecase function", func() {
|
||||
|
||||
triggers, err := appUsecase.ListApplicationTriggers(context.TODO(), appModel)
|
||||
Expect(err).Should(BeNil())
|
||||
reqBody := apisv1.HandleApplicationWebhookRequest{
|
||||
|
||||
invalidReq, err := http.NewRequest("post", "/", bytes.NewBuffer([]byte(`{"upgrade": "test"}`)))
|
||||
invalidReq.Header.Add(restful.HEADER_ContentType, "application/json")
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = webhookUsecase.HandleApplicationWebhook(context.TODO(), triggers[0].Token, restful.NewRequest(invalidReq))
|
||||
Expect(err).Should(Equal(bcode.ErrInvalidWebhookPayloadBody))
|
||||
|
||||
By("Test HandleApplicationWebhook function with custom payload")
|
||||
reqBody := apisv1.HandleApplicationTriggerWebhookRequest{
|
||||
Upgrade: map[string]*model.JSONStruct{
|
||||
"component-name-webhook": {
|
||||
"image": "test-image",
|
||||
@@ -128,6 +136,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(err).Should(BeNil())
|
||||
res, err := webhookUsecase.HandleApplicationWebhook(context.TODO(), triggers[0].Token, restful.NewRequest(httpreq))
|
||||
Expect(err).Should(BeNil())
|
||||
appDeployRes := res.(*apisv1.ApplicationDeployResponse)
|
||||
comp, err := appUsecase.GetApplicationComponent(context.TODO(), appModel, "component-name-webhook")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect((*comp.Properties)["image"]).Should(Equal("test-image"))
|
||||
@@ -137,12 +146,155 @@ var _ = Describe("Test application usecase function", func() {
|
||||
|
||||
revision := &model.ApplicationRevision{
|
||||
AppPrimaryKey: "test-app-webhook",
|
||||
Version: res.Version,
|
||||
Version: appDeployRes.Version,
|
||||
}
|
||||
err = webhookUsecase.ds.Get(context.TODO(), revision)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(revision.CodeInfo.Commit).Should(Equal("test-commit"))
|
||||
Expect(revision.CodeInfo.Branch).Should(Equal("test-branch"))
|
||||
Expect(revision.CodeInfo.User).Should(Equal("test-user"))
|
||||
|
||||
By("Test HandleApplicationWebhook function with ACR payload")
|
||||
acrTrigger, err := appUsecase.CreateApplicationTrigger(context.TODO(), appModel, apisv1.CreateApplicationTriggerRequest{
|
||||
Name: "test-acr",
|
||||
PayloadType: "acr",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
acrBody := apisv1.HandleApplicationTriggerACRRequest{
|
||||
PushData: apisv1.ACRPushData{
|
||||
Digest: "test-digest",
|
||||
Tag: "test-tag",
|
||||
},
|
||||
Repository: apisv1.ACRRepository{
|
||||
Name: "test-repo",
|
||||
Namespace: "test-namespace",
|
||||
Region: "test-region",
|
||||
RepoFullName: "test-namespace/test-repo",
|
||||
RepoType: "public",
|
||||
},
|
||||
}
|
||||
body, err = json.Marshal(acrBody)
|
||||
Expect(err).Should(BeNil())
|
||||
httpreq, err = http.NewRequest("post", "/", bytes.NewBuffer(body))
|
||||
httpreq.Header.Add(restful.HEADER_ContentType, "application/json")
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = webhookUsecase.HandleApplicationWebhook(context.TODO(), acrTrigger.Token, restful.NewRequest(httpreq))
|
||||
Expect(err).Should(BeNil())
|
||||
comp, err = appUsecase.GetApplicationComponent(context.TODO(), appModel, "component-name-webhook")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect((*comp.Properties)["image"]).Should(Equal("registry.test-region.aliyuncs.com/test-namespace/test-repo:test-tag"))
|
||||
|
||||
By("Test HandleApplicationWebhook function with harbor payload")
|
||||
harborTrigger, err := appUsecase.CreateApplicationTrigger(context.TODO(), appModel, apisv1.CreateApplicationTriggerRequest{
|
||||
Name: "test-harbor",
|
||||
PayloadType: "harbor",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
harborBody := apisv1.HandleApplicationHarborReq{
|
||||
Type: model.HarborEventTypePushArtifact,
|
||||
EventData: apisv1.EventData{
|
||||
Resources: []apisv1.Resources{
|
||||
{
|
||||
Digest: "test-digest",
|
||||
Tag: "test-tag",
|
||||
ResourceURL: "harbor.server/test-pro/test-repo:test-tag",
|
||||
},
|
||||
},
|
||||
Repository: apisv1.Repository{
|
||||
Name: "test-repo",
|
||||
Namespace: "test-namespace",
|
||||
RepoFullName: "test-pro/test-repo",
|
||||
RepoType: "public",
|
||||
},
|
||||
},
|
||||
}
|
||||
body, err = json.Marshal(harborBody)
|
||||
Expect(err).Should(BeNil())
|
||||
httpreq, err = http.NewRequest("post", "/", bytes.NewBuffer(body))
|
||||
httpreq.Header.Add(restful.HEADER_ContentType, "application/json")
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = webhookUsecase.HandleApplicationWebhook(context.TODO(), harborTrigger.Token, restful.NewRequest(httpreq))
|
||||
Expect(err).Should(BeNil())
|
||||
comp, err = appUsecase.GetApplicationComponent(context.TODO(), appModel, "component-name-webhook")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect((*comp.Properties)["image"]).Should(Equal("harbor.server/test-pro/test-repo:test-tag"))
|
||||
|
||||
By("Test HandleApplicationWebhook function with dockerhub payload")
|
||||
dockerhubTrigger, err := appUsecase.CreateApplicationTrigger(context.TODO(), appModel, apisv1.CreateApplicationTriggerRequest{
|
||||
Name: "test-dockerhub",
|
||||
PayloadType: "dockerhub",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
dockerhubBody := apisv1.HandleApplicationTriggerDockerHubRequest{
|
||||
PushData: apisv1.DockerHubData{
|
||||
Tag: "test-tag",
|
||||
},
|
||||
Repository: apisv1.DockerHubRepository{
|
||||
IsPrivate: true,
|
||||
Name: "test-repo",
|
||||
Namespace: "test-namespace",
|
||||
RepoName: "test-namespace/test-repo",
|
||||
Status: "Active",
|
||||
},
|
||||
}
|
||||
body, err = json.Marshal(dockerhubBody)
|
||||
Expect(err).Should(BeNil())
|
||||
httpreq, err = http.NewRequest("post", "/", bytes.NewBuffer(body))
|
||||
httpreq.Header.Add(restful.HEADER_ContentType, "application/json")
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = webhookUsecase.HandleApplicationWebhook(context.TODO(), dockerhubTrigger.Token, restful.NewRequest(httpreq))
|
||||
Expect(err).Should(BeNil())
|
||||
comp, err = appUsecase.GetApplicationComponent(context.TODO(), appModel, "component-name-webhook")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect((*comp.Properties)["image"]).Should(Equal("docker.io/test-namespace/test-repo:test-tag"))
|
||||
|
||||
By("Test HandleApplicationWebhook function with jfrog payload without header of X-JFrogURL")
|
||||
jfrogTrigger, err := appUsecase.CreateApplicationTrigger(context.TODO(), appModel, apisv1.CreateApplicationTriggerRequest{
|
||||
Name: "test-jfrog",
|
||||
PayloadType: "jfrog",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
jfrogBody := apisv1.HandleApplicationTriggerJFrogRequest{
|
||||
Domain: "docker",
|
||||
EventType: "pushed",
|
||||
Data: apisv1.JFrogWebhookData{
|
||||
ImageName: "test-image",
|
||||
RepoKey: "test-repo",
|
||||
Digest: "test-digest",
|
||||
Tag: "test-tag",
|
||||
},
|
||||
}
|
||||
body, err = json.Marshal(jfrogBody)
|
||||
Expect(err).Should(BeNil())
|
||||
httpreq, err = http.NewRequest("post", "/", bytes.NewBuffer(body))
|
||||
httpreq.Header.Add(restful.HEADER_ContentType, "application/json")
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = webhookUsecase.HandleApplicationWebhook(context.TODO(), jfrogTrigger.Token, restful.NewRequest(httpreq))
|
||||
Expect(err).Should(BeNil())
|
||||
comp, err = appUsecase.GetApplicationComponent(context.TODO(), appModel, "component-name-webhook")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect((*comp.Properties)["image"]).Should(Equal("test-repo/test-image:test-tag"))
|
||||
|
||||
By("Test HandleApplicationWebhook function with jfrog payload with header of X-JFrogURL")
|
||||
httpreq, err = http.NewRequest("post", "/", bytes.NewBuffer(body))
|
||||
Expect(err).Should(BeNil())
|
||||
httpreq.Header.Add(restful.HEADER_ContentType, "application/json")
|
||||
httpreq.Header.Add("X-JFrogURL", "test-addr")
|
||||
_, err = webhookUsecase.HandleApplicationWebhook(context.TODO(), jfrogTrigger.Token, restful.NewRequest(httpreq))
|
||||
Expect(err).Should(BeNil())
|
||||
comp, err = appUsecase.GetApplicationComponent(context.TODO(), appModel, "component-name-webhook")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect((*comp.Properties)["image"]).Should(Equal("test-addr/test-repo/test-image:test-tag"))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -546,6 +546,11 @@ func resetRevisionsAndRecords(ctx context.Context, ds datastore.DataStore, appNa
|
||||
}
|
||||
record.Status = model.RevisionStatusTerminated
|
||||
record.Finished = "true"
|
||||
for i, step := range record.Steps {
|
||||
if step.Phase == common.WorkflowStepPhaseRunning {
|
||||
record.Steps[i].Phase = common.WorkflowStepPhaseStopped
|
||||
}
|
||||
}
|
||||
if err := ds.Put(ctx, record); err != nil {
|
||||
klog.Info("failed to set rest records' status to terminate", "app name", appName, "workflow name", record.WorkflowName, "record name", record.Name, "error", err)
|
||||
}
|
||||
|
||||
@@ -510,6 +510,40 @@ var _ = Describe("Test workflow usecase functions", func() {
|
||||
Expect(originalRevision.Status).Should(Equal(model.RevisionStatusRollback))
|
||||
Expect(originalRevision.RollbackVersion).Should(Equal("revision-rollback0"))
|
||||
})
|
||||
|
||||
It("Test resetRevisionsAndRecords function", func() {
|
||||
ctx := context.TODO()
|
||||
|
||||
err := workflowUsecase.ds.Add(ctx, &model.WorkflowRecord{
|
||||
AppPrimaryKey: "reset-app",
|
||||
WorkflowName: "reset-workflow",
|
||||
Name: "reset-record",
|
||||
Finished: "false",
|
||||
Steps: []model.WorkflowStepStatus{
|
||||
{
|
||||
Phase: common.WorkflowStepPhaseSucceeded,
|
||||
},
|
||||
{
|
||||
Phase: common.WorkflowStepPhaseRunning,
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
err = resetRevisionsAndRecords(ctx, workflowUsecase.ds, "reset-app", "reset-workflow", "", "")
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
record := &model.WorkflowRecord{
|
||||
AppPrimaryKey: "reset-app",
|
||||
WorkflowName: "reset-workflow",
|
||||
Name: "reset-record",
|
||||
}
|
||||
err = workflowUsecase.ds.Get(ctx, record)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(record.Status).Should(Equal(model.RevisionStatusTerminated))
|
||||
Expect(record.Finished).Should(Equal("true"))
|
||||
Expect(record.Steps[1].Phase).Should(Equal(common.WorkflowStepPhaseStopped))
|
||||
})
|
||||
})
|
||||
|
||||
var yamlStr = `apiVersion: core.oam.dev/v1beta1
|
||||
|
||||
@@ -87,3 +87,6 @@ var ErrInvalidWebhookPayloadType = NewBcode(400, 10022, "Invalid webhook payload
|
||||
|
||||
// ErrInvalidWebhookPayloadBody means the webhook payload body is invalid
|
||||
var ErrInvalidWebhookPayloadBody = NewBcode(400, 10023, "Invalid webhook payload body")
|
||||
|
||||
// ErrApplicationTriggerNotExist means application trigger is not exist
|
||||
var ErrApplicationTriggerNotExist = NewBcode(404, 10024, "application trigger is not exist")
|
||||
|
||||
@@ -133,6 +133,16 @@ func (c *applicationWebService) GetWebService() *restful.WebService {
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes(apis.ApplicationTriggerBase{}))
|
||||
|
||||
ws.Route(ws.DELETE("/{name}/triggers/{token}").To(c.deleteApplicationTrigger).
|
||||
Doc("delete one application trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Filter(c.appCheckFilter).
|
||||
Param(ws.PathParameter("name", "identifier of the application ").DataType("string")).
|
||||
Param(ws.PathParameter("token", "identifier of the trigger").DataType("string")).
|
||||
Returns(200, "", apis.EmptyResponse{}).
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes([]*apis.EmptyResponse{}))
|
||||
|
||||
ws.Route(ws.GET("/{name}/triggers").To(c.listApplicationTriggers).
|
||||
Doc("list application triggers").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
@@ -494,6 +504,7 @@ func (c *applicationWebService) GetWebService() *restful.WebService {
|
||||
Returns(200, "", nil).
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes(apis.ListWorkflowRecordsResponse{}))
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
@@ -584,6 +595,18 @@ func (c *applicationWebService) listApplicationTriggers(req *restful.Request, re
|
||||
}
|
||||
}
|
||||
|
||||
func (c *applicationWebService) deleteApplicationTrigger(req *restful.Request, res *restful.Response) {
|
||||
app := req.Request.Context().Value(&apis.CtxKeyApplication).(*model.Application)
|
||||
if err := c.applicationUsecase.DeleteApplicationTrigger(req.Request.Context(), app, req.PathParameter("token")); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
if err := res.WriteEntity(apis.EmptyResponse{}); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *applicationWebService) publishApplicationTemplate(req *restful.Request, res *restful.Response) {
|
||||
app := req.Request.Context().Value(&apis.CtxKeyApplication).(*model.Application)
|
||||
base, err := c.applicationUsecase.PublishApplicationTemplate(req.Request.Context(), app)
|
||||
|
||||
54
pkg/apiserver/rest/webservice/payload_types.go
Normal file
54
pkg/apiserver/rest/webservice/payload_types.go
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package webservice
|
||||
|
||||
import (
|
||||
restfulspec "github.com/emicklei/go-restful-openapi/v2"
|
||||
restful "github.com/emicklei/go-restful/v3"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/usecase"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils/bcode"
|
||||
)
|
||||
|
||||
type payloadTypesWebservice struct {
|
||||
}
|
||||
|
||||
func (c *payloadTypesWebservice) GetWebService() *restful.WebService {
|
||||
ws := new(restful.WebService)
|
||||
ws.Path(versionPrefix+"/payload_types").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML).
|
||||
Doc("api for payload types manage")
|
||||
|
||||
tags := []string{"payload_types"}
|
||||
|
||||
ws.Route(ws.GET("/").To(c.ListPayloadTypes).
|
||||
Doc("list application trigger payload types").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Returns(200, "", nil).
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes([]string{}))
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
func (c *payloadTypesWebservice) ListPayloadTypes(req *restful.Request, res *restful.Response) {
|
||||
if err := res.WriteEntity(usecase.WebhookHandlers); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
116
pkg/apiserver/rest/webservice/system_info.go
Normal file
116
pkg/apiserver/rest/webservice/system_info.go
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package webservice
|
||||
|
||||
import (
|
||||
restfulspec "github.com/emicklei/go-restful-openapi/v2"
|
||||
"github.com/emicklei/go-restful/v3"
|
||||
|
||||
apis "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/usecase"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils/bcode"
|
||||
)
|
||||
|
||||
type systemInfoWebService struct {
|
||||
useCase usecase.SystemInfoUsecase
|
||||
}
|
||||
|
||||
// NewSystemInfoWebService return systemInfo webservice
|
||||
func NewSystemInfoWebService(systemInfoUseCase usecase.SystemInfoUsecase) WebService {
|
||||
return &systemInfoWebService{useCase: systemInfoUseCase}
|
||||
}
|
||||
|
||||
// GetWebService return systemInfo webservice
|
||||
func (u systemInfoWebService) GetWebService() *restful.WebService {
|
||||
ws := new(restful.WebService)
|
||||
ws.Path(versionPrefix+"/system_info").Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML).
|
||||
Doc("api for systemInfo management")
|
||||
|
||||
tags := []string{"systemInfo"}
|
||||
|
||||
// Get
|
||||
ws.Route(ws.GET("/").To(u.getSystemInfo).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Returns(200, "", apis.SystemInfoResponse{}).
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes(apis.SystemInfoResponse{}))
|
||||
|
||||
// Delete
|
||||
ws.Route(ws.DELETE("/").To(u.deleteSystemInfo).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Returns(200, "", apis.SystemInfoResponse{}).
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes(apis.SystemInfoResponse{}))
|
||||
|
||||
// Post
|
||||
ws.Route(ws.PUT("/").To(u.updateSystemInfo).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Reads(apis.SystemInfoRequest{}).
|
||||
Returns(200, "", apis.SystemInfoResponse{}).
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes(apis.SystemInfoResponse{}))
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
func (u systemInfoWebService) getSystemInfo(req *restful.Request, res *restful.Response) {
|
||||
info, err := u.useCase.GetSystemInfo(req.Request.Context())
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
if err := res.WriteEntity(info); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (u systemInfoWebService) updateSystemInfo(req *restful.Request, res *restful.Response) {
|
||||
var systemInfoReq apis.SystemInfoRequest
|
||||
var args []byte
|
||||
_, err := req.Request.Body.Read(args)
|
||||
if err == nil {
|
||||
err := req.ReadEntity(&systemInfoReq)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
if err = validate.Struct(&systemInfoReq); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
info, err := u.useCase.UpdateSystemInfo(req.Request.Context(), systemInfoReq)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
if err := res.WriteEntity(info); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (u systemInfoWebService) deleteSystemInfo(req *restful.Request, res *restful.Response) {
|
||||
err := u.useCase.DeleteSystemInfo(req.Request.Context())
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"regexp"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/usecase"
|
||||
)
|
||||
|
||||
var validate = validator.New()
|
||||
@@ -38,6 +40,20 @@ func init() {
|
||||
if err := validate.RegisterValidation("checkalias", ValidateAlias); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := validate.RegisterValidation("checkpayloadtype", ValidatePayloadType); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// ValidatePayloadType check PayloadType
|
||||
func ValidatePayloadType(fl validator.FieldLevel) bool {
|
||||
value := fl.Field().String()
|
||||
for _, v := range usecase.WebhookHandlers {
|
||||
if v == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidateName custom check name field
|
||||
|
||||
@@ -51,7 +51,7 @@ func (c *webhookWebService) GetWebService() *restful.WebService {
|
||||
Doc("handle application webhook request").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.PathParameter("name", "identifier of the application ").DataType("string")).
|
||||
Reads(apis.HandleApplicationWebhookRequest{}).
|
||||
Reads(apis.HandleApplicationTriggerWebhookRequest{}).
|
||||
Returns(200, "", apis.ApplicationDeployResponse{}).
|
||||
Returns(400, "", bcode.Bcode{}).
|
||||
Writes(apis.ApplicationDeployResponse{}))
|
||||
|
||||
@@ -71,6 +71,7 @@ func Init(ds datastore.DataStore, addonCacheTime time.Duration) {
|
||||
envBindingUsecase := usecase.NewEnvBindingUsecase(ds, workflowUsecase, definitionUsecase, envUsecase)
|
||||
applicationUsecase := usecase.NewApplicationUsecase(ds, workflowUsecase, envBindingUsecase, envUsecase, targetUsecase, definitionUsecase, projectUsecase)
|
||||
webhookUsecase := usecase.NewWebhookUsecase(ds, applicationUsecase)
|
||||
systemInfoUsecase := usecase.NewSystemInfoUsecase(ds)
|
||||
|
||||
// init for default values
|
||||
|
||||
@@ -89,7 +90,10 @@ func Init(ds datastore.DataStore, addonCacheTime time.Duration) {
|
||||
RegisterWebService(NewClusterWebService(clusterUsecase))
|
||||
RegisterWebService(NewOAMApplication(oamApplicationUsecase))
|
||||
RegisterWebService(&policyDefinitionWebservice{})
|
||||
RegisterWebService(&payloadTypesWebservice{})
|
||||
RegisterWebService(NewTargetWebService(targetUsecase, applicationUsecase))
|
||||
RegisterWebService(NewVelaQLWebService(velaQLUsecase))
|
||||
RegisterWebService(NewWebhookWebService(webhookUsecase, applicationUsecase))
|
||||
|
||||
RegisterWebService(NewSystemInfoWebService(systemInfoUsecase))
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/cue/model"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/model/value"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/process"
|
||||
monitorContext "github.com/oam-dev/kubevela/pkg/monitor/context"
|
||||
"github.com/oam-dev/kubevela/pkg/monitor/metrics"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/step"
|
||||
@@ -81,6 +83,7 @@ type Workload struct {
|
||||
Ctx process.Context
|
||||
Patch *value.Value
|
||||
engine definition.AbstractEngine
|
||||
SkipApplyWorkload bool
|
||||
}
|
||||
|
||||
// EvalContext eval workload template and set result to context
|
||||
@@ -90,12 +93,17 @@ func (wl *Workload) EvalContext(ctx process.Context) error {
|
||||
|
||||
// EvalStatus eval workload status
|
||||
func (wl *Workload) EvalStatus(ctx process.Context, cli client.Client, ns string) (string, error) {
|
||||
// if the standard workload is managed by trait always return empty message
|
||||
if wl.SkipApplyWorkload {
|
||||
return "", nil
|
||||
}
|
||||
return wl.engine.Status(ctx, cli, ns, wl.FullTemplate.CustomStatus, wl.Params)
|
||||
}
|
||||
|
||||
// EvalHealth eval workload health check
|
||||
func (wl *Workload) EvalHealth(ctx process.Context, client client.Client, namespace string) (bool, error) {
|
||||
if wl.FullTemplate.Health == "" {
|
||||
// if health of template is not set or standard workload is managed by trait always return true
|
||||
if wl.FullTemplate.Health == "" || wl.SkipApplyWorkload {
|
||||
return true, nil
|
||||
}
|
||||
return wl.engine.HealthCheck(ctx, client, namespace, wl.FullTemplate.Health)
|
||||
@@ -176,7 +184,14 @@ type Handler interface {
|
||||
}
|
||||
|
||||
// PrepareWorkflowAndPolicy generates workflow steps and policies from an appFile
|
||||
func (af *Appfile) PrepareWorkflowAndPolicy() ([]*unstructured.Unstructured, error) {
|
||||
func (af *Appfile) PrepareWorkflowAndPolicy(ctx context.Context) ([]*unstructured.Unstructured, error) {
|
||||
if ctx, ok := ctx.(monitorContext.Context); ok {
|
||||
subCtx := ctx.Fork("prepare-workflow-and-policy", monitorContext.DurationMetric(func(v float64) {
|
||||
metrics.PrepareWorkflowAndPolicyDurationHistogram.WithLabelValues("application").Observe(v)
|
||||
}))
|
||||
defer subCtx.Commit("finish prepare workflow and policy")
|
||||
}
|
||||
|
||||
var externalPolicies []*unstructured.Unstructured
|
||||
var err error
|
||||
|
||||
@@ -704,7 +719,14 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
|
||||
}
|
||||
if spec.ProviderReference != nil && !reflect.DeepEqual(configuration.Spec.ProviderReference, spec.ProviderReference) {
|
||||
configuration.Spec.ProviderReference = spec.ProviderReference
|
||||
} else if wl.FullTemplate != nil && wl.FullTemplate.ComponentDefinition != nil &&
|
||||
wl.FullTemplate.ComponentDefinition.Spec.Schematic != nil &&
|
||||
wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform != nil &&
|
||||
wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.ProviderReference != nil {
|
||||
// Check whether the provider reference is set in ComponentDefinition
|
||||
configuration.Spec.ProviderReference = wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.ProviderReference
|
||||
}
|
||||
|
||||
if spec.Region != "" && configuration.Spec.Region != spec.Region {
|
||||
configuration.Spec.Region = spec.Region
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ spec:
|
||||
}
|
||||
_, err := testAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(BeNil())
|
||||
gotPolicies, err := testAppfile.PrepareWorkflowAndPolicy()
|
||||
gotPolicies, err := testAppfile.PrepareWorkflowAndPolicy(context.Background())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(gotPolicies)).ShouldNot(Equal(0))
|
||||
|
||||
@@ -944,7 +944,6 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
},
|
||||
|
||||
"workload's params is bad": {
|
||||
|
||||
args: args{
|
||||
params: badParam,
|
||||
hcl: "abc",
|
||||
@@ -952,8 +951,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)},
|
||||
},
|
||||
|
||||
"terraform workload has a provider reference": {
|
||||
|
||||
"terraform workload has a provider reference, but parameters are bad": {
|
||||
args: args{
|
||||
params: badParam,
|
||||
hcl: "abc",
|
||||
@@ -961,6 +959,14 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
},
|
||||
want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)},
|
||||
},
|
||||
"terraform workload has a provider reference": {
|
||||
args: args{
|
||||
params: variable,
|
||||
hcl: "variable \"name\" {\n description = \"Name to be used on all resources as prefix. Default to 'TF-Module-EIP'.\"\n default = \"TF-Module-EIP\"\n type = string\n }",
|
||||
providerRef: &terraformtypes.Reference{Name: "aws", Namespace: "default"},
|
||||
},
|
||||
want: want{err: nil},
|
||||
},
|
||||
}
|
||||
|
||||
for tcName, tc := range testcases {
|
||||
@@ -1021,7 +1027,16 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
configSpec.WriteConnectionSecretToReference = tc.args.writeConnectionSecretToRef
|
||||
}
|
||||
if tc.args.providerRef != nil {
|
||||
template.Terraform.ProviderReference = tc.args.providerRef
|
||||
tf := &common.Terraform{}
|
||||
tf.ProviderReference = tc.args.providerRef
|
||||
template.ComponentDefinition = &v1beta1.ComponentDefinition{
|
||||
Spec: v1beta1.ComponentDefinitionSpec{
|
||||
Schematic: &common.Schematic{
|
||||
Terraform: tf,
|
||||
},
|
||||
},
|
||||
}
|
||||
configSpec.ProviderReference = tc.args.providerRef
|
||||
}
|
||||
|
||||
wl := &Workload{
|
||||
|
||||
@@ -32,6 +32,8 @@ import (
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/definition"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/packages"
|
||||
monitorContext "github.com/oam-dev/kubevela/pkg/monitor/context"
|
||||
"github.com/oam-dev/kubevela/pkg/monitor/metrics"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
@@ -75,6 +77,12 @@ func NewDryRunApplicationParser(cli client.Client, dm discoverymapper.DiscoveryM
|
||||
|
||||
// GenerateAppFile converts an application to an Appfile
|
||||
func (p *Parser) GenerateAppFile(ctx context.Context, app *v1beta1.Application) (*Appfile, error) {
|
||||
if ctx, ok := ctx.(monitorContext.Context); ok {
|
||||
subCtx := ctx.Fork("generate-app-file", monitorContext.DurationMetric(func(v float64) {
|
||||
metrics.ParseAppFileDurationHistogram.WithLabelValues("application").Observe(v)
|
||||
}))
|
||||
defer subCtx.Commit("finish generate appFile")
|
||||
}
|
||||
ns := app.Namespace
|
||||
appName := app.Name
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
@@ -71,7 +71,7 @@ var _ = BeforeSuite(func(done Done) {
|
||||
scheme = runtime.NewScheme()
|
||||
Expect(coreoam.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
Expect(clientgoscheme.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
Expect(v1beta1.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
Expect(v1.AddToScheme(scheme)).NotTo(HaveOccurred())
|
||||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(k8sClient).ToNot(BeNil())
|
||||
|
||||
@@ -35,7 +35,7 @@ func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
|
||||
}
|
||||
pCtx, err := newValidationProcessContext(wl, a.Name, a.AppRevisionName, a.Namespace)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "cannot create validationg process context")
|
||||
return errors.WithMessagef(err, "cannot create the validation process context of app=%s in namespace=%s", a.Name, a.Namespace)
|
||||
}
|
||||
for _, tr := range wl.Traits {
|
||||
if tr.CapabilityCategory != types.CUECategory {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user