mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-14 18:10:21 +00:00
Chore: remove outdated apis(v1alppha2 ApplicationConfiguration Component, and HealthScope, Rollout) (#6041)
* remove outdated api Signed-off-by: Somefive <yd219913@alibaba-inc.com> * fix rt test: no component rt Signed-off-by: Somefive <yd219913@alibaba-inc.com> * recover context.revision to component hash Signed-off-by: Somefive <yd219913@alibaba-inc.com> --------- Signed-off-by: Somefive <yd219913@alibaba-inc.com>
This commit is contained in:
124
.github/workflows/e2e-rollout-test.yml
vendored
124
.github/workflows/e2e-rollout-test.yml
vendored
@@ -1,124 +0,0 @@
|
||||
name: E2E Rollout Test
|
||||
|
||||
on:
|
||||
# push:
|
||||
# branches:
|
||||
# - master
|
||||
# - release-*
|
||||
# tags:
|
||||
# - v*
|
||||
workflow_dispatch: {}
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - master
|
||||
# - release-*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
|
||||
jobs:
|
||||
|
||||
detect-noop:
|
||||
permissions:
|
||||
actions: write
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
noop: ${{ steps.noop.outputs.should_skip }}
|
||||
steps:
|
||||
- name: Detect No-op Changes
|
||||
id: noop
|
||||
uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
|
||||
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
|
||||
continue-on-error: true
|
||||
|
||||
e2e-rollout-tests:
|
||||
runs-on: self-hosted
|
||||
needs: [ detect-noop ]
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
k8s-version: ["v1.26"]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
|
||||
- name: Get Ginkgo
|
||||
run: |
|
||||
go install github.com/onsi/ginkgo/v2/ginkgo
|
||||
go get github.com/onsi/gomega/...
|
||||
|
||||
- name: Tear down K3d if exist
|
||||
run: |
|
||||
k3d cluster delete || true
|
||||
k3d cluster delete worker || true
|
||||
|
||||
- name: Calculate K3d args
|
||||
run: |
|
||||
EGRESS_ARG=""
|
||||
if [[ "${{ matrix.k8s-version }}" == v1.26 ]]; then
|
||||
EGRESS_ARG="--k3s-arg --egress-selector-mode=disabled@server:0"
|
||||
fi
|
||||
echo "EGRESS_ARG=${EGRESS_ARG}" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup K3d
|
||||
uses: nolar/setup-k3d-k3s@293b8e5822a20bc0d5bcdd4826f1a665e72aba96
|
||||
with:
|
||||
version: ${{ matrix.k8s-version }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
k3d-args: ${{ env.EGRESS_ARG }}
|
||||
|
||||
- name: Load image to k3d cluster
|
||||
run: make image-load image-load-runtime-cluster
|
||||
|
||||
- name: Prepare for e2e tests
|
||||
run: |
|
||||
make vela-cli
|
||||
make e2e-cleanup
|
||||
make e2e-setup-core
|
||||
make setup-runtime-e2e-cluster
|
||||
helm test -n vela-system kubevela --timeout 5m
|
||||
|
||||
- name: Run e2e tests
|
||||
run: make e2e-rollout-test
|
||||
|
||||
- name: Stop kubevela, get profile
|
||||
run: make end-e2e
|
||||
|
||||
- name: Upload coverage report
|
||||
uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: /tmp/e2e-profile.out
|
||||
flags: e2e-rollout-tests
|
||||
name: codecov-umbrella
|
||||
|
||||
- name: Clean e2e profile
|
||||
run: rm /tmp/e2e-profile.out
|
||||
|
||||
- name: Cleanup image
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
make image-cleanup
|
||||
docker image prune -a -f --filter "until=24h"
|
||||
|
||||
@@ -21,13 +21,12 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register the types with the Scheme so the resources can map objects to GroupVersionKinds and back
|
||||
AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme, v1alpha2.SchemeBuilder.AddToScheme, v1beta1.SchemeBuilder.AddToScheme)
|
||||
AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme, v1beta1.SchemeBuilder.AddToScheme)
|
||||
}
|
||||
|
||||
// AddToSchemes may be used to add all resources defined in the project to a Scheme
|
||||
|
||||
@@ -1,123 +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 (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"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"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// AppStatus defines the observed state of Application
|
||||
type AppStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
v1alpha1.RolloutStatus `json:",inline"`
|
||||
|
||||
Phase common.ApplicationPhase `json:"status,omitempty"`
|
||||
|
||||
// Components record the related Components created by Application Controller
|
||||
Components []corev1.ObjectReference `json:"components,omitempty"`
|
||||
|
||||
// Services record the status of the application services
|
||||
Services []common.ApplicationComponentStatus `json:"services,omitempty"`
|
||||
|
||||
// ResourceTracker record the status of the ResourceTracker
|
||||
ResourceTracker *corev1.ObjectReference `json:"resourceTracker,omitempty"`
|
||||
|
||||
// LatestRevision of the application configuration it generates
|
||||
// +optional
|
||||
LatestRevision *common.Revision `json:"latestRevision,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationTrait defines the trait of application
|
||||
type ApplicationTrait struct {
|
||||
Name string `json:"name"`
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationComponent describe the component of application
|
||||
type ApplicationComponent struct {
|
||||
Name string `json:"name"`
|
||||
WorkloadType string `json:"type"`
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Settings runtime.RawExtension `json:"settings,omitempty"`
|
||||
|
||||
// Traits define the trait of one component, the type must be array to keep the order.
|
||||
Traits []ApplicationTrait `json:"traits,omitempty"`
|
||||
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
// scopes in ApplicationComponent defines the component-level scopes
|
||||
// the format is <scope-type:scope-instance-name> pairs, the key represents type of `ScopeDefinition` while the value represent the name of scope instance.
|
||||
Scopes map[string]string `json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationSpec is the spec of Application
|
||||
type ApplicationSpec struct {
|
||||
Components []ApplicationComponent `json:"components"`
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// Application is the Schema for the applications API
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories={oam},shortName={app,velaapp}
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="COMPONENT",type=string,JSONPath=`.spec.components[*].name`
|
||||
// +kubebuilder:printcolumn:name="TYPE",type=string,JSONPath=`.spec.components[*].type`
|
||||
// +kubebuilder:printcolumn:name="PHASE",type=string,JSONPath=`.status.status`
|
||||
// +kubebuilder:printcolumn:name="HEALTHY",type=boolean,JSONPath=`.status.services[*].healthy`
|
||||
// +kubebuilder:printcolumn:name="STATUS",type=string,JSONPath=`.status.services[*].message`
|
||||
// +kubebuilder:printcolumn:name="AGE",type=date,JSONPath=".metadata.creationTimestamp"
|
||||
type Application struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ApplicationSpec `json:"spec,omitempty"`
|
||||
Status common.AppStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ApplicationList contains a list of Application
|
||||
type ApplicationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Application `json:"items"`
|
||||
}
|
||||
|
||||
// GetComponent get the component from the application based on its workload type
|
||||
func (app *Application) GetComponent(workloadType string) *ApplicationComponent {
|
||||
for _, c := range app.Spec.Components {
|
||||
if c.WorkloadType == workloadType {
|
||||
return &c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,68 +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 (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestApplicationGetComponent(t *testing.T) {
|
||||
ac1 := ApplicationComponent{
|
||||
Name: "ac1",
|
||||
WorkloadType: "type1",
|
||||
}
|
||||
ac2 := ApplicationComponent{
|
||||
Name: "ac2",
|
||||
WorkloadType: "type2",
|
||||
}
|
||||
tests := map[string]struct {
|
||||
app *Application
|
||||
componentName string
|
||||
want *ApplicationComponent
|
||||
}{
|
||||
"test get one": {
|
||||
app: &Application{
|
||||
Spec: ApplicationSpec{
|
||||
Components: []ApplicationComponent{
|
||||
ac1, ac2,
|
||||
},
|
||||
},
|
||||
},
|
||||
componentName: ac1.WorkloadType,
|
||||
want: &ac1,
|
||||
},
|
||||
"test get none": {
|
||||
app: &Application{
|
||||
Spec: ApplicationSpec{
|
||||
Components: []ApplicationComponent{
|
||||
ac2,
|
||||
},
|
||||
},
|
||||
},
|
||||
componentName: ac1.WorkloadType,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for name, tt := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if got := tt.app.GetComponent(tt.componentName); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("GetComponent() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,73 +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"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
)
|
||||
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// ApplicationRevisionSpec is the spec of ApplicationRevision
|
||||
type ApplicationRevisionSpec struct {
|
||||
// Application records the snapshot of the created/modified Application
|
||||
Application Application `json:"application"`
|
||||
|
||||
// ComponentDefinitions records the snapshot of the componentDefinitions related with the created/modified Application
|
||||
ComponentDefinitions map[string]ComponentDefinition `json:"componentDefinitions,omitempty"`
|
||||
|
||||
// WorkloadDefinitions records the snapshot of the workloadDefinitions related with the created/modified Application
|
||||
WorkloadDefinitions map[string]WorkloadDefinition `json:"workloadDefinitions,omitempty"`
|
||||
|
||||
// TraitDefinitions records the snapshot of the traitDefinitions related with the created/modified Application
|
||||
TraitDefinitions map[string]TraitDefinition `json:"traitDefinitions,omitempty"`
|
||||
|
||||
// ScopeDefinitions records the snapshot of the scopeDefinitions related with the created/modified Application
|
||||
ScopeDefinitions map[string]ScopeDefinition `json:"scopeDefinitions,omitempty"`
|
||||
|
||||
// Components records the rendered components from Application, it will contains the whole K8s CR of workload in it.
|
||||
|
||||
Components []common.RawComponent `json:"components,omitempty"`
|
||||
|
||||
// ApplicationConfiguration records the rendered applicationConfiguration from Application,
|
||||
// it will contains the whole K8s CR of trait and the reference component in it.
|
||||
// +kubebuilder:validation:EmbeddedResource
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
ApplicationConfiguration runtime.RawExtension `json:"applicationConfiguration"`
|
||||
}
|
||||
|
||||
// ApplicationRevision is the Schema for the ApplicationRevision API
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories={oam},shortName=apprev
|
||||
// +kubebuilder:printcolumn:name="AGE",type=date,JSONPath=".metadata.creationTimestamp"
|
||||
type ApplicationRevision struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ApplicationRevisionSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationRevisionList contains a list of ApplicationRevision
|
||||
// +kubebuilder:object:root=true
|
||||
type ApplicationRevisionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ApplicationRevision `json:"items"`
|
||||
}
|
||||
@@ -1,103 +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"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
)
|
||||
|
||||
// ComponentDefinitionSpec defines the desired state of ComponentDefinition
|
||||
type ComponentDefinitionSpec struct {
|
||||
// Workload is a workload type descriptor
|
||||
Workload common.WorkloadTypeDescriptor `json:"workload"`
|
||||
|
||||
// ChildResourceKinds are the list of GVK of the child resources this workload generates
|
||||
ChildResourceKinds []common.ChildResourceKind `json:"childResourceKinds,omitempty"`
|
||||
|
||||
// RevisionLabel indicates which label for underlying resources(e.g. pods) of this workload
|
||||
// can be used by trait to create resource selectors(e.g. label selector for pods).
|
||||
// +optional
|
||||
RevisionLabel string `json:"revisionLabel,omitempty"`
|
||||
|
||||
// PodSpecPath indicates where/if this workload has K8s podSpec field
|
||||
// if one workload has podSpec, trait can do lot's of assumption such as port, env, volume fields.
|
||||
// +optional
|
||||
PodSpecPath string `json:"podSpecPath,omitempty"`
|
||||
|
||||
// Status defines the custom health policy and status message for workload
|
||||
// +optional
|
||||
Status *common.Status `json:"status,omitempty"`
|
||||
|
||||
// Schematic defines the data format and template of the encapsulation of the workload
|
||||
// +optional
|
||||
Schematic *common.Schematic `json:"schematic,omitempty"`
|
||||
|
||||
// Extension is used for extension needs by OAM platform builders
|
||||
// +optional
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Extension *runtime.RawExtension `json:"extension,omitempty"`
|
||||
}
|
||||
|
||||
// ComponentDefinitionStatus is the status of ComponentDefinition
|
||||
type ComponentDefinitionStatus struct {
|
||||
// ConditionedStatus reflects the observed status of a resource
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
// ConfigMapRef refer to a ConfigMap which contains OpenAPI V3 JSON schema of Component parameters.
|
||||
ConfigMapRef string `json:"configMapRef,omitempty"`
|
||||
// LatestRevision of the component definition
|
||||
// +optional
|
||||
LatestRevision *common.Revision `json:"latestRevision,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ComponentDefinition is the Schema for the componentdefinitions API
|
||||
// +kubebuilder:resource:scope=Namespaced,categories={oam},shortName=comp
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="WORKLOAD-KIND",type=string,JSONPath=".spec.workload.definition.kind"
|
||||
// +kubebuilder:printcolumn:name="DESCRIPTION",type=string,JSONPath=".metadata.annotations.definition\\.oam\\.dev/description"
|
||||
type ComponentDefinition struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ComponentDefinitionSpec `json:"spec,omitempty"`
|
||||
Status ComponentDefinitionStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// SetConditions set condition for WorkloadDefinition
|
||||
func (cd *ComponentDefinition) SetConditions(c ...condition.Condition) {
|
||||
cd.Status.SetConditions(c...)
|
||||
}
|
||||
|
||||
// GetCondition gets condition from WorkloadDefinition
|
||||
func (cd *ComponentDefinition) GetCondition(conditionType condition.ConditionType) condition.Condition {
|
||||
return cd.Status.GetCondition(conditionType)
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ComponentDefinitionList contains a list of ComponentDefinition
|
||||
type ComponentDefinitionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ComponentDefinition `json:"items"`
|
||||
}
|
||||
@@ -1,139 +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 (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/conversion"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
)
|
||||
|
||||
// ApplicationV1alpha2ToV1beta1 will convert v1alpha2 to v1beta1
|
||||
func ApplicationV1alpha2ToV1beta1(v1a2 *Application, v1b1 *v1beta1.Application) {
|
||||
// 1) convert metav1.TypeMeta
|
||||
// apiVersion and Kind automatically converted
|
||||
|
||||
// 2) convert metav1.ObjectMeta
|
||||
v1b1.ObjectMeta = *v1a2.ObjectMeta.DeepCopy()
|
||||
|
||||
// 3) convert Spec ApplicationSpec
|
||||
// 3.1) convert Spec.Components
|
||||
for _, comp := range v1a2.Spec.Components {
|
||||
|
||||
// convert trait, especially for `.name` -> `.type`
|
||||
var traits = make([]common.ApplicationTrait, len(comp.Traits))
|
||||
for j, trait := range comp.Traits {
|
||||
traits[j] = common.ApplicationTrait{
|
||||
Type: trait.Name,
|
||||
Properties: trait.Properties.DeepCopy(),
|
||||
}
|
||||
}
|
||||
|
||||
// deep copy scopes
|
||||
scopes := make(map[string]string)
|
||||
for k, v := range comp.Scopes {
|
||||
scopes[k] = v
|
||||
}
|
||||
// convert component
|
||||
// `.settings` -> `.properties`
|
||||
v1b1.Spec.Components = append(v1b1.Spec.Components, common.ApplicationComponent{
|
||||
Name: comp.Name,
|
||||
Type: comp.WorkloadType,
|
||||
Properties: comp.Settings.DeepCopy(),
|
||||
Traits: traits,
|
||||
Scopes: scopes,
|
||||
})
|
||||
}
|
||||
|
||||
// 4) convert Status common.AppStatus
|
||||
v1b1.Status = *v1a2.Status.DeepCopy()
|
||||
}
|
||||
|
||||
// ConvertTo converts this Application to the Hub version (v1beta1 only for now).
|
||||
func (app *Application) ConvertTo(dst conversion.Hub) error {
|
||||
switch convertedApp := dst.(type) {
|
||||
case *v1beta1.Application:
|
||||
klog.Infof("convert *v1alpha2.Application [%s] to *v1beta1.Application", app.Name)
|
||||
ApplicationV1alpha2ToV1beta1(app, convertedApp)
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
return fmt.Errorf("unsupported convertTo object %v", reflect.TypeOf(dst))
|
||||
}
|
||||
|
||||
// ConvertFrom converts from the Hub version (v1beta1) to this version (v1alpha2).
|
||||
func (app *Application) ConvertFrom(src conversion.Hub) error {
|
||||
switch sourceApp := src.(type) {
|
||||
case *v1beta1.Application:
|
||||
|
||||
klog.Infof("convert *v1alpha2.Application from *v1beta1.Application [%s]", sourceApp.Name)
|
||||
|
||||
// 1) convert metav1.TypeMeta
|
||||
// apiVersion and Kind automatically converted
|
||||
|
||||
// 2) convert metav1.ObjectMeta
|
||||
app.ObjectMeta = *sourceApp.ObjectMeta.DeepCopy()
|
||||
|
||||
// 3) convert Spec ApplicationSpec
|
||||
// 3.1) convert Spec.Components
|
||||
for _, comp := range sourceApp.Spec.Components {
|
||||
|
||||
// convert trait, especially for `.type` -> `.name`
|
||||
var traits = make([]ApplicationTrait, len(comp.Traits))
|
||||
for j, trait := range comp.Traits {
|
||||
traits[j] = ApplicationTrait{
|
||||
Name: trait.Type,
|
||||
Properties: trait.Properties.DeepCopy(),
|
||||
}
|
||||
}
|
||||
|
||||
// deep copy scopes
|
||||
scopes := make(map[string]string)
|
||||
for k, v := range comp.Scopes {
|
||||
scopes[k] = v
|
||||
}
|
||||
// convert component
|
||||
// `.properties` -> `.settings`
|
||||
|
||||
var compProperties runtime.RawExtension
|
||||
|
||||
if comp.Properties != nil {
|
||||
compProperties = *comp.Properties.DeepCopy()
|
||||
}
|
||||
|
||||
app.Spec.Components = append(app.Spec.Components, ApplicationComponent{
|
||||
Name: comp.Name,
|
||||
WorkloadType: comp.Type,
|
||||
Settings: compProperties,
|
||||
Traits: traits,
|
||||
Scopes: scopes,
|
||||
})
|
||||
}
|
||||
|
||||
// 4) convert Status common.AppStatus
|
||||
app.Status = *sourceApp.Status.DeepCopy()
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
return fmt.Errorf("unsupported ConvertFrom object %v", reflect.TypeOf(src))
|
||||
}
|
||||
@@ -1,117 +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 (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
)
|
||||
|
||||
var app = Application{
|
||||
Spec: ApplicationSpec{
|
||||
Components: []ApplicationComponent{{
|
||||
Name: "test-component",
|
||||
WorkloadType: "worker",
|
||||
Traits: []ApplicationTrait{},
|
||||
Scopes: map[string]string{},
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
type errType struct {
|
||||
}
|
||||
|
||||
func (*errType) Hub() {}
|
||||
|
||||
func (*errType) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*errType) GetObjectKind() schema.ObjectKind {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestApplicationV1alpha2ToV1beta1(t *testing.T) {
|
||||
r := require.New(t)
|
||||
expected := &v1beta1.Application{}
|
||||
ApplicationV1alpha2ToV1beta1(&app, expected)
|
||||
|
||||
r.Equal(expected, &v1beta1.Application{
|
||||
Spec: v1beta1.ApplicationSpec{
|
||||
Components: []common.ApplicationComponent{{
|
||||
Name: "test-component",
|
||||
Type: "worker",
|
||||
Properties: &runtime.RawExtension{},
|
||||
Traits: []common.ApplicationTrait{},
|
||||
Scopes: map[string]string{},
|
||||
}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestConvertTo(t *testing.T) {
|
||||
r := require.New(t)
|
||||
expected := &v1beta1.Application{}
|
||||
err := app.ConvertTo(expected)
|
||||
r.NoError(err)
|
||||
r.Equal(expected, &v1beta1.Application{
|
||||
Spec: v1beta1.ApplicationSpec{
|
||||
Components: []common.ApplicationComponent{{
|
||||
Name: "test-component",
|
||||
Type: "worker",
|
||||
Properties: &runtime.RawExtension{},
|
||||
Traits: []common.ApplicationTrait{},
|
||||
Scopes: map[string]string{},
|
||||
}},
|
||||
},
|
||||
})
|
||||
|
||||
errCase := &errType{}
|
||||
err = app.ConvertTo(errCase)
|
||||
r.Equal(err, fmt.Errorf("unsupported convertTo object *v1alpha2.errType"))
|
||||
}
|
||||
|
||||
func TestConvertFrom(t *testing.T) {
|
||||
r := require.New(t)
|
||||
to := &Application{}
|
||||
from := &v1beta1.Application{
|
||||
Spec: v1beta1.ApplicationSpec{
|
||||
Components: []common.ApplicationComponent{{
|
||||
Name: "test-component",
|
||||
Type: "worker",
|
||||
Properties: &runtime.RawExtension{},
|
||||
Traits: []common.ApplicationTrait{},
|
||||
Scopes: map[string]string{},
|
||||
}},
|
||||
},
|
||||
}
|
||||
err := to.ConvertFrom(from)
|
||||
r.NoError(err)
|
||||
r.Equal(to.Spec, app.Spec)
|
||||
|
||||
errCase := &errType{}
|
||||
err = app.ConvertFrom(errCase)
|
||||
r.Equal(err, fmt.Errorf("unsupported ConvertFrom object *v1alpha2.errType"))
|
||||
}
|
||||
@@ -1,146 +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 (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
// HealthStatus represents health status strings.
|
||||
type HealthStatus string
|
||||
|
||||
const (
|
||||
// StatusHealthy represents healthy status.
|
||||
StatusHealthy HealthStatus = "HEALTHY"
|
||||
// StatusUnhealthy represents unhealthy status.
|
||||
StatusUnhealthy = "UNHEALTHY"
|
||||
// StatusUnknown represents unknown status.
|
||||
StatusUnknown = "UNKNOWN"
|
||||
)
|
||||
|
||||
var _ oam.Scope = &HealthScope{}
|
||||
|
||||
// A HealthScopeSpec defines the desired state of a HealthScope.
|
||||
type HealthScopeSpec struct {
|
||||
// ProbeTimeout is the amount of time in seconds to wait when receiving a response before marked failure.
|
||||
ProbeTimeout *int32 `json:"probe-timeout,omitempty"`
|
||||
|
||||
// ProbeInterval is the amount of time in seconds between probing tries.
|
||||
ProbeInterval *int32 `json:"probe-interval,omitempty"`
|
||||
|
||||
// AppRefs records references of applications' components
|
||||
AppRefs []AppReference `json:"appReferences,omitempty"`
|
||||
|
||||
// WorkloadReferences to the workloads that are in this scope.
|
||||
// +deprecated
|
||||
WorkloadReferences []corev1.ObjectReference `json:"workloadRefs"`
|
||||
}
|
||||
|
||||
// AppReference records references of an application's components
|
||||
type AppReference struct {
|
||||
AppName string `json:"appName,omitempty"`
|
||||
CompReferences []CompReference `json:"compReferences,omitempty"`
|
||||
}
|
||||
|
||||
// CompReference records references of a component's resources
|
||||
type CompReference struct {
|
||||
CompName string `json:"compName,omitempty"`
|
||||
Workload corev1.ObjectReference `json:"workload,omitempty"`
|
||||
Traits []corev1.ObjectReference `json:"traits,omitempty"`
|
||||
}
|
||||
|
||||
// A HealthScopeStatus represents the observed state of a HealthScope.
|
||||
type HealthScopeStatus struct {
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
|
||||
// ScopeHealthCondition represents health condition summary of the scope
|
||||
ScopeHealthCondition ScopeHealthCondition `json:"scopeHealthCondition"`
|
||||
|
||||
// AppHealthConditions represents health condition of applications in the scope
|
||||
AppHealthConditions []*AppHealthCondition `json:"appHealthConditions,omitempty"`
|
||||
|
||||
// WorkloadHealthConditions represents health condition of workloads in the scope
|
||||
// Use AppHealthConditions to provide app level status
|
||||
// +deprecated
|
||||
WorkloadHealthConditions []*WorkloadHealthCondition `json:"healthConditions,omitempty"`
|
||||
}
|
||||
|
||||
// AppHealthCondition represents health condition of an application
|
||||
type AppHealthCondition struct {
|
||||
AppName string `json:"appName"`
|
||||
EnvName string `json:"envName,omitempty"`
|
||||
Components []*WorkloadHealthCondition `json:"components,omitempty"`
|
||||
}
|
||||
|
||||
// ScopeHealthCondition represents health condition summary of a scope.
|
||||
type ScopeHealthCondition struct {
|
||||
HealthStatus HealthStatus `json:"healthStatus"`
|
||||
Total int64 `json:"total,omitempty"`
|
||||
HealthyWorkloads int64 `json:"healthyWorkloads,omitempty"`
|
||||
UnhealthyWorkloads int64 `json:"unhealthyWorkloads,omitempty"`
|
||||
UnknownWorkloads int64 `json:"unknownWorkloads,omitempty"`
|
||||
}
|
||||
|
||||
// WorkloadHealthCondition represents informative health condition of a workload.
|
||||
type WorkloadHealthCondition struct {
|
||||
// ComponentName represents the component name if target is a workload
|
||||
ComponentName string `json:"componentName,omitempty"`
|
||||
TargetWorkload corev1.ObjectReference `json:"targetWorkload,omitempty"`
|
||||
HealthStatus HealthStatus `json:"healthStatus"`
|
||||
Diagnosis string `json:"diagnosis,omitempty"`
|
||||
// WorkloadStatus represents status of workloads whose HealthStatus is UNKNOWN.
|
||||
WorkloadStatus string `json:"workloadStatus,omitempty"`
|
||||
CustomStatusMsg string `json:"customStatusMsg,omitempty"`
|
||||
Traits []*TraitHealthCondition `json:"traits,omitempty"`
|
||||
}
|
||||
|
||||
// TraitHealthCondition represents informative health condition of a trait.
|
||||
type TraitHealthCondition struct {
|
||||
Type string `json:"type"`
|
||||
Resource string `json:"resource"`
|
||||
HealthStatus HealthStatus `json:"healthStatus"`
|
||||
Diagnosis string `json:"diagnosis,omitempty"`
|
||||
CustomStatusMsg string `json:"customStatusMsg,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// A HealthScope determines an aggregate health status based of the health of components.
|
||||
// +kubebuilder:resource:categories={oam}
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:JSONPath=".status.health",name=HEALTH,type=string
|
||||
type HealthScope struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec HealthScopeSpec `json:"spec,omitempty"`
|
||||
Status HealthScopeStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// HealthScopeList contains a list of HealthScope.
|
||||
type HealthScopeList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []HealthScope `json:"items"`
|
||||
}
|
||||
@@ -1,673 +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 (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
)
|
||||
|
||||
// A WorkloadDefinitionSpec defines the desired state of a WorkloadDefinition.
|
||||
type WorkloadDefinitionSpec struct {
|
||||
// Reference to the CustomResourceDefinition that defines this workload kind.
|
||||
Reference common.DefinitionReference `json:"definitionRef"`
|
||||
|
||||
// ChildResourceKinds are the list of GVK of the child resources this workload generates
|
||||
ChildResourceKinds []common.ChildResourceKind `json:"childResourceKinds,omitempty"`
|
||||
|
||||
// RevisionLabel indicates which label for underlying resources(e.g. pods) of this workload
|
||||
// can be used by trait to create resource selectors(e.g. label selector for pods).
|
||||
// +optional
|
||||
RevisionLabel string `json:"revisionLabel,omitempty"`
|
||||
|
||||
// PodSpecPath indicates where/if this workload has K8s podSpec field
|
||||
// if one workload has podSpec, trait can do lot's of assumption such as port, env, volume fields.
|
||||
// +optional
|
||||
PodSpecPath string `json:"podSpecPath,omitempty"`
|
||||
|
||||
// Status defines the custom health policy and status message for workload
|
||||
// +optional
|
||||
Status *common.Status `json:"status,omitempty"`
|
||||
|
||||
// Schematic defines the data format and template of the encapsulation of the workload
|
||||
// +optional
|
||||
Schematic *common.Schematic `json:"schematic,omitempty"`
|
||||
|
||||
// Extension is used for extension needs by OAM platform builders
|
||||
// +optional
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Extension *runtime.RawExtension `json:"extension,omitempty"`
|
||||
}
|
||||
|
||||
// WorkloadDefinitionStatus is the status of WorkloadDefinition
|
||||
type WorkloadDefinitionStatus struct {
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// A WorkloadDefinition registers a kind of Kubernetes custom resource as a
|
||||
// valid OAM workload kind by referencing its CustomResourceDefinition. The CRD
|
||||
// is used to validate the schema of the workload when it is embedded in an OAM
|
||||
// Component.
|
||||
// +kubebuilder:resource:scope=Namespaced,categories={oam},shortName=workload
|
||||
// +kubebuilder:printcolumn:name="DEFINITION-NAME",type=string,JSONPath=".spec.definitionRef.name"
|
||||
type WorkloadDefinition struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec WorkloadDefinitionSpec `json:"spec,omitempty"`
|
||||
Status WorkloadDefinitionStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// SetConditions set condition for WorkloadDefinition
|
||||
func (wd *WorkloadDefinition) SetConditions(c ...condition.Condition) {
|
||||
wd.Status.SetConditions(c...)
|
||||
}
|
||||
|
||||
// GetCondition gets condition from WorkloadDefinition
|
||||
func (wd *WorkloadDefinition) GetCondition(conditionType condition.ConditionType) condition.Condition {
|
||||
return wd.Status.GetCondition(conditionType)
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// WorkloadDefinitionList contains a list of WorkloadDefinition.
|
||||
type WorkloadDefinitionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []WorkloadDefinition `json:"items"`
|
||||
}
|
||||
|
||||
// A TraitDefinitionSpec defines the desired state of a TraitDefinition.
|
||||
type TraitDefinitionSpec struct {
|
||||
// Reference to the CustomResourceDefinition that defines this trait kind.
|
||||
Reference common.DefinitionReference `json:"definitionRef,omitempty"`
|
||||
|
||||
// Revision indicates whether a trait is aware of component revision
|
||||
// +optional
|
||||
RevisionEnabled bool `json:"revisionEnabled,omitempty"`
|
||||
|
||||
// WorkloadRefPath indicates where/if a trait accepts a workloadRef object
|
||||
// +optional
|
||||
WorkloadRefPath string `json:"workloadRefPath,omitempty"`
|
||||
|
||||
// PodDisruptive specifies whether using the trait will cause the pod to restart or not.
|
||||
// +optional
|
||||
PodDisruptive bool `json:"podDisruptive,omitempty"`
|
||||
|
||||
// AppliesToWorkloads specifies the list of workload kinds this trait
|
||||
// applies to. Workload kinds are specified in kind.group/version format,
|
||||
// e.g. server.core.oam.dev/v1alpha2. Traits that omit this field apply to
|
||||
// all workload kinds.
|
||||
// +optional
|
||||
AppliesToWorkloads []string `json:"appliesToWorkloads,omitempty"`
|
||||
|
||||
// ConflictsWith specifies the list of traits(CRD name, Definition name, CRD group)
|
||||
// which could not apply to the same workloads with this trait.
|
||||
// Traits that omit this field can work with any other traits.
|
||||
// Example rules:
|
||||
// "service" # Trait definition name
|
||||
// "services.k8s.io" # API resource/crd name
|
||||
// "*.networking.k8s.io" # API group
|
||||
// "labelSelector:foo=bar" # label selector
|
||||
// labelSelector format: https://pkg.go.dev/k8s.io/apimachinery/pkg/labels#Parse
|
||||
// +optional
|
||||
ConflictsWith []string `json:"conflictsWith,omitempty"`
|
||||
|
||||
// Schematic defines the data format and template of the encapsulation of the trait
|
||||
// +optional
|
||||
Schematic *common.Schematic `json:"schematic,omitempty"`
|
||||
|
||||
// Status defines the custom health policy and status message for trait
|
||||
// +optional
|
||||
Status *common.Status `json:"status,omitempty"`
|
||||
|
||||
// Extension is used for extension needs by OAM platform builders
|
||||
// +optional
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Extension *runtime.RawExtension `json:"extension,omitempty"`
|
||||
}
|
||||
|
||||
// TraitDefinitionStatus is the status of TraitDefinition
|
||||
type TraitDefinitionStatus struct {
|
||||
// ConditionedStatus reflects the observed status of a resource
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
// ConfigMapRef refer to a ConfigMap which contains OpenAPI V3 JSON schema of Component parameters.
|
||||
ConfigMapRef string `json:"configMapRef,omitempty"`
|
||||
// LatestRevision of the trait definition
|
||||
// +optional
|
||||
LatestRevision *common.Revision `json:"latestRevision,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// A TraitDefinition registers a kind of Kubernetes custom resource as a valid
|
||||
// OAM trait kind by referencing its CustomResourceDefinition. The CRD is used
|
||||
// to validate the schema of the trait when it is embedded in an OAM
|
||||
// ApplicationConfiguration.
|
||||
// +kubebuilder:resource:scope=Namespaced,categories={oam},shortName=trait
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="APPLIES-TO",type=string,JSONPath=".spec.appliesToWorkloads"
|
||||
// +kubebuilder:printcolumn:name="DESCRIPTION",type=string,JSONPath=".metadata.annotations.definition\\.oam\\.dev/description"
|
||||
type TraitDefinition struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec TraitDefinitionSpec `json:"spec,omitempty"`
|
||||
Status TraitDefinitionStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// SetConditions set condition for TraitDefinition
|
||||
func (td *TraitDefinition) SetConditions(c ...condition.Condition) {
|
||||
td.Status.SetConditions(c...)
|
||||
}
|
||||
|
||||
// GetCondition gets condition from TraitDefinition
|
||||
func (td *TraitDefinition) GetCondition(conditionType condition.ConditionType) condition.Condition {
|
||||
return td.Status.GetCondition(conditionType)
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// TraitDefinitionList contains a list of TraitDefinition.
|
||||
type TraitDefinitionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []TraitDefinition `json:"items"`
|
||||
}
|
||||
|
||||
// A ScopeDefinitionSpec defines the desired state of a ScopeDefinition.
|
||||
type ScopeDefinitionSpec struct {
|
||||
// Reference to the CustomResourceDefinition that defines this scope kind.
|
||||
Reference common.DefinitionReference `json:"definitionRef"`
|
||||
|
||||
// WorkloadRefsPath indicates if/where a scope accepts workloadRef objects
|
||||
WorkloadRefsPath string `json:"workloadRefsPath,omitempty"`
|
||||
|
||||
// AllowComponentOverlap specifies whether an OAM component may exist in
|
||||
// multiple instances of this kind of scope.
|
||||
AllowComponentOverlap bool `json:"allowComponentOverlap"`
|
||||
|
||||
// Extension is used for extension needs by OAM platform builders
|
||||
// +optional
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Extension *runtime.RawExtension `json:"extension,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// A ScopeDefinition registers a kind of Kubernetes custom resource as a valid
|
||||
// OAM scope kind by referencing its CustomResourceDefinition. The CRD is used
|
||||
// to validate the schema of the scope when it is embedded in an OAM
|
||||
// ApplicationConfiguration.
|
||||
// +kubebuilder:printcolumn:JSONPath=".spec.definitionRef.name",name=DEFINITION-NAME,type=string
|
||||
// +kubebuilder:resource:scope=Namespaced,categories={oam},shortName=scope
|
||||
type ScopeDefinition struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ScopeDefinitionSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ScopeDefinitionList contains a list of ScopeDefinition.
|
||||
type ScopeDefinitionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ScopeDefinition `json:"items"`
|
||||
}
|
||||
|
||||
// A ComponentParameter defines a configurable parameter of a component.
|
||||
type ComponentParameter struct {
|
||||
// Name of this parameter. OAM ApplicationConfigurations will specify
|
||||
// parameter values using this name.
|
||||
Name string `json:"name"`
|
||||
|
||||
// FieldPaths specifies an array of fields within this Component's workload
|
||||
// that will be overwritten by the value of this parameter. The type of the
|
||||
// parameter (e.g. int, string) is inferred from the type of these fields;
|
||||
// All fields must be of the same type. Fields are specified as JSON field
|
||||
// paths without a leading dot, for example 'spec.replicas'.
|
||||
FieldPaths []string `json:"fieldPaths"`
|
||||
|
||||
// +kubebuilder:default:=false
|
||||
// Required specifies whether or not a value for this parameter must be
|
||||
// supplied when authoring an ApplicationConfiguration.
|
||||
// +optional
|
||||
Required *bool `json:"required,omitempty"`
|
||||
|
||||
// Description of this parameter.
|
||||
// +optional
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// A ComponentSpec defines the desired state of a Component.
|
||||
type ComponentSpec struct {
|
||||
// A Workload that will be created for each ApplicationConfiguration that
|
||||
// includes this Component. Workload is an instance of a workloadDefinition.
|
||||
// We either use the GVK info or a special "type" field in the workload to associate
|
||||
// the content of the workload with its workloadDefinition
|
||||
// +kubebuilder:validation:EmbeddedResource
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Workload runtime.RawExtension `json:"workload"`
|
||||
|
||||
// HelmRelease records a Helm release used by a Helm module workload.
|
||||
// +optional
|
||||
Helm *common.Helm `json:"helm,omitempty"`
|
||||
|
||||
// Parameters exposed by this component. ApplicationConfigurations that
|
||||
// reference this component may specify values for these parameters, which
|
||||
// will in turn be injected into the embedded workload.
|
||||
// +optional
|
||||
Parameters []ComponentParameter `json:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
// A ComponentStatus represents the observed state of a Component.
|
||||
type ComponentStatus struct {
|
||||
// The generation observed by the component controller.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration"`
|
||||
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
|
||||
// LatestRevision of component
|
||||
// +optional
|
||||
LatestRevision *common.Revision `json:"latestRevision,omitempty"`
|
||||
|
||||
// One Component should only be used by one AppConfig
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// A Component describes how an OAM workload kind may be instantiated.
|
||||
// +kubebuilder:resource:categories={oam}
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:JSONPath=".spec.workload.kind",name=WORKLOAD-KIND,type=string
|
||||
// +kubebuilder:printcolumn:name="age",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
type Component struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ComponentSpec `json:"spec,omitempty"`
|
||||
Status ComponentStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ComponentList contains a list of Component.
|
||||
type ComponentList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Component `json:"items"`
|
||||
}
|
||||
|
||||
// A ComponentParameterValue specifies a value for a named parameter. The
|
||||
// associated component must publish a parameter with this name.
|
||||
type ComponentParameterValue struct {
|
||||
// Name of the component parameter to set.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Value to set.
|
||||
Value intstr.IntOrString `json:"value"`
|
||||
}
|
||||
|
||||
// A ComponentTrait specifies a trait that should be applied to a component.
|
||||
type ComponentTrait struct {
|
||||
// A Trait that will be created for the component
|
||||
// +kubebuilder:validation:EmbeddedResource
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Trait runtime.RawExtension `json:"trait"`
|
||||
|
||||
// DataOutputs specify the data output sources from this trait.
|
||||
// +optional
|
||||
DataOutputs []DataOutput `json:"dataOutputs,omitempty"`
|
||||
|
||||
// DataInputs specify the data input sinks into this trait.
|
||||
// +optional
|
||||
DataInputs []DataInput `json:"dataInputs,omitempty"`
|
||||
}
|
||||
|
||||
// A ComponentScope specifies a scope in which a component should exist.
|
||||
type ComponentScope struct {
|
||||
// A ScopeReference must refer to an OAM scope resource.
|
||||
ScopeReference corev1.ObjectReference `json:"scopeRef"`
|
||||
}
|
||||
|
||||
// An ApplicationConfigurationComponent specifies a component of an
|
||||
// ApplicationConfiguration. Each component is used to instantiate a workload.
|
||||
type ApplicationConfigurationComponent struct {
|
||||
// ComponentName specifies a component whose latest revision will be bind
|
||||
// with ApplicationConfiguration. When the spec of the referenced component
|
||||
// changes, ApplicationConfiguration will automatically migrate all trait
|
||||
// affect from the prior revision to the new one. This is mutually exclusive
|
||||
// with RevisionName.
|
||||
// +optional
|
||||
ComponentName string `json:"componentName,omitempty"`
|
||||
|
||||
// RevisionName of a specific component revision to which to bind
|
||||
// ApplicationConfiguration. This is mutually exclusive with componentName.
|
||||
// +optional
|
||||
RevisionName string `json:"revisionName,omitempty"`
|
||||
|
||||
// DataOutputs specify the data output sources from this component.
|
||||
DataOutputs []DataOutput `json:"dataOutputs,omitempty"`
|
||||
|
||||
// DataInputs specify the data input sinks into this component.
|
||||
DataInputs []DataInput `json:"dataInputs,omitempty"`
|
||||
|
||||
// ParameterValues specify values for the the specified component's
|
||||
// parameters. Any parameter required by the component must be specified.
|
||||
// +optional
|
||||
ParameterValues []ComponentParameterValue `json:"parameterValues,omitempty"`
|
||||
|
||||
// Traits of the specified component.
|
||||
// +optional
|
||||
Traits []ComponentTrait `json:"traits,omitempty"`
|
||||
|
||||
// Scopes in which the specified component should exist.
|
||||
// +optional
|
||||
Scopes []ComponentScope `json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// An ApplicationConfigurationSpec defines the desired state of a
|
||||
// ApplicationConfiguration.
|
||||
type ApplicationConfigurationSpec struct {
|
||||
// Components of which this ApplicationConfiguration consists. Each
|
||||
// component will be used to instantiate a workload.
|
||||
Components []ApplicationConfigurationComponent `json:"components"`
|
||||
}
|
||||
|
||||
// A TraitStatus represents the state of a trait.
|
||||
type TraitStatus string
|
||||
|
||||
// A WorkloadTrait represents a trait associated with a workload and its status
|
||||
type WorkloadTrait struct {
|
||||
// Status is a place holder for a customized controller to fill
|
||||
// if it needs a single place to summarize the status of the trait
|
||||
Status TraitStatus `json:"status,omitempty"`
|
||||
|
||||
// Reference to a trait created by an ApplicationConfiguration.
|
||||
Reference corev1.ObjectReference `json:"traitRef"`
|
||||
|
||||
// Message will allow controller to leave some additional information for this trait
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// AppliedGeneration indicates the generation observed by the appConfig controller.
|
||||
// The same field is also recorded in the annotations of traits.
|
||||
// A trait is possible to be deleted from cluster after created.
|
||||
// This field is useful to track the observed generation of traits after they are
|
||||
// deleted.
|
||||
AppliedGeneration int64 `json:"appliedGeneration,omitempty"`
|
||||
|
||||
// DependencyUnsatisfied notify does the trait has dependency unsatisfied
|
||||
DependencyUnsatisfied bool `json:"dependencyUnsatisfied,omitempty"`
|
||||
}
|
||||
|
||||
// A ScopeStatus represents the state of a scope.
|
||||
type ScopeStatus string
|
||||
|
||||
// A WorkloadScope represents a scope associated with a workload and its status
|
||||
type WorkloadScope struct {
|
||||
// Status is a place holder for a customized controller to fill
|
||||
// if it needs a single place to summarize the status of the scope
|
||||
Status ScopeStatus `json:"status,omitempty"`
|
||||
|
||||
// Reference to a scope created by an ApplicationConfiguration.
|
||||
Reference corev1.ObjectReference `json:"scopeRef"`
|
||||
}
|
||||
|
||||
// A WorkloadStatus represents the status of a workload.
|
||||
type WorkloadStatus struct {
|
||||
// Status is a place holder for a customized controller to fill
|
||||
// if it needs a single place to summarize the entire status of the workload
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
// ComponentName that produced this workload.
|
||||
ComponentName string `json:"componentName,omitempty"`
|
||||
|
||||
// ComponentRevisionName of current component
|
||||
ComponentRevisionName string `json:"componentRevisionName,omitempty"`
|
||||
|
||||
// DependencyUnsatisfied notify does the workload has dependency unsatisfied
|
||||
DependencyUnsatisfied bool `json:"dependencyUnsatisfied,omitempty"`
|
||||
|
||||
// AppliedComponentRevision indicates the applied component revision name of this workload
|
||||
AppliedComponentRevision string `json:"appliedComponentRevision,omitempty"`
|
||||
|
||||
// Reference to a workload created by an ApplicationConfiguration.
|
||||
Reference corev1.ObjectReference `json:"workloadRef,omitempty"`
|
||||
|
||||
// Traits associated with this workload.
|
||||
Traits []WorkloadTrait `json:"traits,omitempty"`
|
||||
|
||||
// Scopes associated with this workload.
|
||||
Scopes []WorkloadScope `json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// HistoryWorkload contain the old component revision that are still running
|
||||
type HistoryWorkload struct {
|
||||
// Revision of this workload
|
||||
Revision string `json:"revision,omitempty"`
|
||||
|
||||
// Reference to running workload.
|
||||
Reference corev1.ObjectReference `json:"workloadRef,omitempty"`
|
||||
}
|
||||
|
||||
// A ApplicationStatus represents the state of the entire application.
|
||||
type ApplicationStatus string
|
||||
|
||||
// An ApplicationConfigurationStatus represents the observed state of a
|
||||
// ApplicationConfiguration.
|
||||
type ApplicationConfigurationStatus struct {
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
|
||||
// Status is a place holder for a customized controller to fill
|
||||
// if it needs a single place to summarize the status of the entire application
|
||||
Status ApplicationStatus `json:"status,omitempty"`
|
||||
|
||||
Dependency DependencyStatus `json:"dependency,omitempty"`
|
||||
|
||||
// RollingStatus indicates what phase are we in the rollout phase
|
||||
RollingStatus types.RollingStatus `json:"rollingStatus,omitempty"`
|
||||
|
||||
// Workloads created by this ApplicationConfiguration.
|
||||
Workloads []WorkloadStatus `json:"workloads,omitempty"`
|
||||
|
||||
// The generation observed by the appConfig controller.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration"`
|
||||
|
||||
// HistoryWorkloads will record history but still working revision workloads.
|
||||
HistoryWorkloads []HistoryWorkload `json:"historyWorkloads,omitempty"`
|
||||
}
|
||||
|
||||
// DependencyStatus represents the observed state of the dependency of
|
||||
// an ApplicationConfiguration.
|
||||
type DependencyStatus struct {
|
||||
Unsatisfied []UnstaifiedDependency `json:"unsatisfied,omitempty"`
|
||||
}
|
||||
|
||||
// UnstaifiedDependency describes unsatisfied dependency flow between
|
||||
// one pair of objects.
|
||||
type UnstaifiedDependency struct {
|
||||
Reason string `json:"reason"`
|
||||
From DependencyFromObject `json:"from"`
|
||||
To DependencyToObject `json:"to"`
|
||||
}
|
||||
|
||||
// DependencyFromObject represents the object that dependency data comes from.
|
||||
type DependencyFromObject struct {
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
FieldPath string `json:"fieldPath,omitempty"`
|
||||
}
|
||||
|
||||
// DependencyToObject represents the object that dependency data goes to.
|
||||
type DependencyToObject struct {
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
FieldPaths []string `json:"fieldPaths,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// An ApplicationConfiguration represents an OAM application.
|
||||
// +kubebuilder:resource:shortName=appconfig,categories={oam}
|
||||
// +kubebuilder:subresource:status
|
||||
type ApplicationConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ApplicationConfigurationSpec `json:"spec,omitempty"`
|
||||
Status ApplicationConfigurationStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ApplicationConfigurationList contains a list of ApplicationConfiguration.
|
||||
type ApplicationConfigurationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ApplicationConfiguration `json:"items"`
|
||||
}
|
||||
|
||||
// DataOutput specifies a data output source from an object.
|
||||
type DataOutput struct {
|
||||
// Name is the unique name of a DataOutput in an ApplicationConfiguration.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// FieldPath refers to the value of an object's field.
|
||||
FieldPath string `json:"fieldPath,omitempty"`
|
||||
|
||||
// Conditions specify the conditions that should be satisfied before emitting a data output.
|
||||
// Different conditions are AND-ed together.
|
||||
// If no conditions is specified, it is by default to check output value not empty.
|
||||
// +optional
|
||||
Conditions []ConditionRequirement `json:"conditions,omitempty"`
|
||||
// OutputStore specifies the object used to store intermediate data generated by Operations
|
||||
OutputStore StoreReference `json:"outputStore,omitempty"`
|
||||
}
|
||||
|
||||
// StoreReference specifies the referenced object in DataOutput or DataInput
|
||||
type StoreReference struct {
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
// Operations specify the data processing operations
|
||||
Operations []DataOperation `json:"operations,omitempty"`
|
||||
}
|
||||
|
||||
// DataOperation defines the specific operation for data
|
||||
type DataOperation struct {
|
||||
// Type specifies the type of DataOperation
|
||||
Type string `json:"type"`
|
||||
// Operator specifies the operation under this DataOperation type
|
||||
Operator DataOperator `json:"op"`
|
||||
// ToFieldPath refers to the value of an object's field
|
||||
ToFieldPath string `json:"toFieldPath"`
|
||||
// ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
|
||||
ToDataPath string `json:"toDataPath,omitempty"`
|
||||
// +optional
|
||||
// Value specifies an expected value
|
||||
// This is mutually exclusive with ValueFrom
|
||||
Value string `json:"value,omitempty"`
|
||||
// +optional
|
||||
// ValueFrom specifies expected value from object such as workload and trait
|
||||
// This is mutually exclusive with Value
|
||||
ValueFrom ValueFrom `json:"valueFrom,omitempty"`
|
||||
Conditions []ConditionRequirement `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// DataOperator defines the type of Operator in DataOperation
|
||||
type DataOperator string
|
||||
|
||||
const (
|
||||
// AddOperator specifies the add operation for data passing
|
||||
AddOperator DataOperator = "add"
|
||||
// DeleteOperator specifies the delete operation for data passing
|
||||
DeleteOperator DataOperator = "delete"
|
||||
// ReplaceOperator specifies the replace operation for data passing
|
||||
ReplaceOperator DataOperator = "replace"
|
||||
)
|
||||
|
||||
// DataInput specifies a data input sink to an object.
|
||||
// If input is array, it will be appended to the target field paths.
|
||||
type DataInput struct {
|
||||
// ValueFrom specifies the value source.
|
||||
ValueFrom DataInputValueFrom `json:"valueFrom,omitempty"`
|
||||
|
||||
// ToFieldPaths specifies the field paths of an object to fill passed value.
|
||||
ToFieldPaths []string `json:"toFieldPaths,omitempty"`
|
||||
|
||||
// StrategyMergeKeys specifies the merge key if the toFieldPaths target is an array.
|
||||
// The StrategyMergeKeys is optional, by default, if the toFieldPaths target is an array, we will append.
|
||||
// If StrategyMergeKeys specified, we will check the key in the target array.
|
||||
// If any key exist, do update; if no key exist, append.
|
||||
StrategyMergeKeys []string `json:"strategyMergeKeys,omitempty"`
|
||||
|
||||
// When the Conditions is satified, ToFieldPaths will be filled with passed value
|
||||
Conditions []ConditionRequirement `json:"conditions,omitempty"`
|
||||
|
||||
// InputStore specifies the object used to read intermediate data genereted by DataOutput
|
||||
InputStore StoreReference `json:"inputStore,omitempty"`
|
||||
}
|
||||
|
||||
// DataInputValueFrom specifies the value source for a data input.
|
||||
type DataInputValueFrom struct {
|
||||
// DataOutputName matches a name of a DataOutput in the same AppConfig.
|
||||
DataOutputName string `json:"dataOutputName"`
|
||||
}
|
||||
|
||||
// ConditionRequirement specifies the requirement to match a value.
|
||||
type ConditionRequirement struct {
|
||||
Operator ConditionOperator `json:"op"`
|
||||
|
||||
// +optional
|
||||
// Value specifies an expected value
|
||||
// This is mutually exclusive with ValueFrom
|
||||
Value string `json:"value,omitempty"`
|
||||
// +optional
|
||||
// ValueFrom specifies expected value from AppConfig
|
||||
// This is mutually exclusive with Value
|
||||
ValueFrom ValueFrom `json:"valueFrom,omitempty"`
|
||||
|
||||
// +optional
|
||||
// FieldPath specifies got value from workload/trait object
|
||||
FieldPath string `json:"fieldPath,omitempty"`
|
||||
}
|
||||
|
||||
// ValueFrom gets value from AppConfig object by specifying a path
|
||||
type ValueFrom struct {
|
||||
FieldPath string `json:"fieldPath"`
|
||||
}
|
||||
|
||||
// ConditionOperator specifies the operator to match a value.
|
||||
type ConditionOperator string
|
||||
|
||||
const (
|
||||
// ConditionEqual indicates equal to given value
|
||||
ConditionEqual ConditionOperator = "eq"
|
||||
// ConditionNotEqual indicates not equal to given value
|
||||
ConditionNotEqual ConditionOperator = "notEq"
|
||||
// ConditionNotEmpty indicates given value not empty
|
||||
ConditionNotEmpty ConditionOperator = "notEmpty"
|
||||
)
|
||||
@@ -1,355 +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
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
// An OperatingSystem required by a containerised workload.
|
||||
type OperatingSystem string
|
||||
|
||||
// Supported operating system types.
|
||||
const (
|
||||
OperatingSystemLinux OperatingSystem = "linux"
|
||||
OperatingSystemWindows OperatingSystem = "windows"
|
||||
)
|
||||
|
||||
// A CPUArchitecture required by a containerised workload.
|
||||
type CPUArchitecture string
|
||||
|
||||
// Supported architectures
|
||||
const (
|
||||
CPUArchitectureI386 CPUArchitecture = "i386"
|
||||
CPUArchitectureAMD64 CPUArchitecture = "amd64"
|
||||
CPUArchitectureARM CPUArchitecture = "arm"
|
||||
CPUArchitectureARM64 CPUArchitecture = "arm64"
|
||||
)
|
||||
|
||||
// A SecretKeySelector is a reference to a secret key in an arbitrary namespace.
|
||||
type SecretKeySelector struct {
|
||||
// The name of the secret.
|
||||
Name string `json:"name"`
|
||||
|
||||
// The key to select.
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// TODO(negz): The OAM spec calls for float64 quantities in some cases, but this
|
||||
// is incompatible with controller-gen and Kubernetes API conventions. We should
|
||||
// reassess whether resource.Quantity is appropriate after resolving
|
||||
// https://github.com/oam-dev/spec/issues/313
|
||||
|
||||
// CPUResources required by a container.
|
||||
type CPUResources struct {
|
||||
// Required CPU count. 1.0 represents one CPU core.
|
||||
Required resource.Quantity `json:"required"`
|
||||
}
|
||||
|
||||
// MemoryResources required by a container.
|
||||
type MemoryResources struct {
|
||||
// Required memory.
|
||||
Required resource.Quantity `json:"required"`
|
||||
}
|
||||
|
||||
// GPUResources required by a container.
|
||||
type GPUResources struct {
|
||||
// Required GPU count.
|
||||
Required resource.Quantity `json:"required"`
|
||||
}
|
||||
|
||||
// DiskResource required by a container.
|
||||
type DiskResource struct {
|
||||
// Required disk space.
|
||||
Required resource.Quantity `json:"required"`
|
||||
|
||||
// Ephemeral specifies whether an external disk needs to be mounted.
|
||||
// +optional
|
||||
Ephemeral *bool `json:"ephemeral,omitempty"`
|
||||
}
|
||||
|
||||
// A VolumeAccessMode determines how a volume may be accessed.
|
||||
type VolumeAccessMode string
|
||||
|
||||
// Volume access modes.
|
||||
const (
|
||||
VolumeAccessModeRO VolumeAccessMode = "RO"
|
||||
VolumeAccessModeRW VolumeAccessMode = "RW"
|
||||
)
|
||||
|
||||
// A VolumeSharingPolicy determines how a volume may be shared.
|
||||
type VolumeSharingPolicy string
|
||||
|
||||
// Volume sharing policies.
|
||||
const (
|
||||
VolumeSharingPolicyExclusive VolumeSharingPolicy = "Exclusive"
|
||||
VolumeSharingPolicyShared VolumeSharingPolicy = "Shared"
|
||||
)
|
||||
|
||||
// VolumeResource required by a container.
|
||||
type VolumeResource struct {
|
||||
// Name of this volume. Must be unique within its container.
|
||||
Name string `json:"name"`
|
||||
|
||||
// MountPath at which this volume will be mounted within its container.
|
||||
MountPath string `json:"mountPath"`
|
||||
|
||||
// TODO(negz): Use +kubebuilder:default marker to default AccessMode to RW
|
||||
// and SharingPolicy to Exclusive once we're generating v1 CRDs.
|
||||
|
||||
// AccessMode of this volume; RO (read only) or RW (read and write).
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=RO;RW
|
||||
AccessMode *VolumeAccessMode `json:"accessMode,omitempty"`
|
||||
|
||||
// SharingPolicy of this volume; Exclusive or Shared.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Exclusive;Shared
|
||||
SharingPolicy *VolumeSharingPolicy `json:"sharingPolicy,omitempty"`
|
||||
|
||||
// Disk requirements of this volume.
|
||||
// +optional
|
||||
Disk *DiskResource `json:"disk,omitempty"`
|
||||
}
|
||||
|
||||
// ExtendedResource required by a container.
|
||||
type ExtendedResource struct {
|
||||
// Name of the external resource. Resource names are specified in
|
||||
// kind.group/version format, e.g. motionsensor.ext.example.com/v1.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Required extended resource(s), e.g. 8 or "very-cool-widget"
|
||||
Required intstr.IntOrString `json:"required"`
|
||||
}
|
||||
|
||||
// ContainerResources specifies a container's required compute resources.
|
||||
type ContainerResources struct {
|
||||
// CPU required by this container.
|
||||
CPU CPUResources `json:"cpu"`
|
||||
|
||||
// Memory required by this container.
|
||||
Memory MemoryResources `json:"memory"`
|
||||
|
||||
// GPU required by this container.
|
||||
// +optional
|
||||
GPU *GPUResources `json:"gpu,omitempty"`
|
||||
|
||||
// Volumes required by this container.
|
||||
// +optional
|
||||
Volumes []VolumeResource `json:"volumes,omitempty"`
|
||||
|
||||
// Extended resources required by this container.
|
||||
// +optional
|
||||
Extended []ExtendedResource `json:"extended,omitempty"`
|
||||
}
|
||||
|
||||
// A ContainerEnvVar specifies an environment variable that should be set within
|
||||
// a container.
|
||||
type ContainerEnvVar struct {
|
||||
// Name of the environment variable. Must be composed of valid Unicode
|
||||
// letter and number characters, as well as _ and -.
|
||||
// +kubebuilder:validation:Pattern=^[-_a-zA-Z0-9]+$
|
||||
Name string `json:"name"`
|
||||
|
||||
// Value of the environment variable.
|
||||
// +optional
|
||||
Value *string `json:"value,omitempty"`
|
||||
|
||||
// FromSecret is a secret key reference which can be used to assign a value
|
||||
// to the environment variable.
|
||||
// +optional
|
||||
FromSecret *SecretKeySelector `json:"fromSecret,omitempty"`
|
||||
}
|
||||
|
||||
// A ContainerConfigFile specifies a configuration file that should be written
|
||||
// within a container.
|
||||
type ContainerConfigFile struct {
|
||||
// Path within the container at which the configuration file should be
|
||||
// written.
|
||||
Path string `json:"path"`
|
||||
|
||||
// Value that should be written to the configuration file.
|
||||
// +optional
|
||||
Value *string `json:"value,omitempty"`
|
||||
|
||||
// FromSecret is a secret key reference which can be used to assign a value
|
||||
// to be written to the configuration file at the given path in the
|
||||
// container.
|
||||
// +optional
|
||||
FromSecret *SecretKeySelector `json:"fromSecret,omitempty"`
|
||||
}
|
||||
|
||||
// A TransportProtocol represents a transport layer protocol.
|
||||
type TransportProtocol string
|
||||
|
||||
// Transport protocols.
|
||||
const (
|
||||
TransportProtocolTCP TransportProtocol = "TCP"
|
||||
TransportProtocolUDP TransportProtocol = "UDP"
|
||||
)
|
||||
|
||||
// A ContainerPort specifies a port that is exposed by a container.
|
||||
type ContainerPort struct {
|
||||
// Name of this port. Must be unique within its container. Must be lowercase
|
||||
// alphabetical characters.
|
||||
// +kubebuilder:validation:Pattern=^[a-z]+$
|
||||
Name string `json:"name"`
|
||||
|
||||
// Port number. Must be unique within its container.
|
||||
Port int32 `json:"containerPort"`
|
||||
|
||||
// TODO(negz): Use +kubebuilder:default marker to default Protocol to TCP
|
||||
// once we're generating v1 CRDs.
|
||||
|
||||
// Protocol used by the server listening on this port.
|
||||
// +kubebuilder:validation:Enum=TCP;UDP
|
||||
// +optional
|
||||
Protocol *TransportProtocol `json:"protocol,omitempty"`
|
||||
}
|
||||
|
||||
// An ExecProbe probes a container's health by executing a command.
|
||||
type ExecProbe struct {
|
||||
// Command to be run by this probe.
|
||||
Command []string `json:"command"`
|
||||
}
|
||||
|
||||
// A HTTPHeader to be passed when probing a container.
|
||||
type HTTPHeader struct {
|
||||
// Name of this HTTP header. Must be unique per probe.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Value of this HTTP header.
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// A HTTPGetProbe probes a container's health by sending an HTTP GET request.
|
||||
type HTTPGetProbe struct {
|
||||
// Path to probe, e.g. '/healthz'.
|
||||
Path string `json:"path"`
|
||||
|
||||
// Port to probe.
|
||||
Port int32 `json:"port"`
|
||||
|
||||
// HTTPHeaders to send with the GET request.
|
||||
// +optional
|
||||
HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty"`
|
||||
}
|
||||
|
||||
// A TCPSocketProbe probes a container's health by connecting to a TCP socket.
|
||||
type TCPSocketProbe struct {
|
||||
// Port this probe should connect to.
|
||||
Port int32 `json:"port"`
|
||||
}
|
||||
|
||||
// A ContainerHealthProbe specifies how to probe the health of a container.
|
||||
// Exactly one of Exec, HTTPGet, or TCPSocket must be specified.
|
||||
type ContainerHealthProbe struct {
|
||||
// Exec probes a container's health by executing a command.
|
||||
// +optional
|
||||
Exec *ExecProbe `json:"exec,omitempty"`
|
||||
|
||||
// HTTPGet probes a container's health by sending an HTTP GET request.
|
||||
// +optional
|
||||
HTTPGet *HTTPGetProbe `json:"httpGet,omitempty"`
|
||||
|
||||
// TCPSocketProbe probes a container's health by connecting to a TCP socket.
|
||||
// +optional
|
||||
TCPSocket *TCPSocketProbe `json:"tcpSocket,omitempty"`
|
||||
|
||||
// InitialDelaySeconds after a container starts before the first probe.
|
||||
// +optional
|
||||
InitialDelaySeconds *int32 `json:"initialDelaySeconds,omitempty"`
|
||||
|
||||
// TODO(negz): Use +kubebuilder:default marker to default PeriodSeconds,
|
||||
// TimeoutSeconds, SuccessThreshold, and FailureThreshold to 10, 1, 1, and 3
|
||||
// respectively once we're generating v1 CRDs.
|
||||
|
||||
// PeriodSeconds between probes.
|
||||
// +optional
|
||||
PeriodSeconds *int32 `json:"periodSeconds,omitempty"`
|
||||
|
||||
// TimeoutSeconds after which the probe times out.
|
||||
// +optional
|
||||
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"`
|
||||
|
||||
// SuccessThreshold specifies how many consecutive probes must success in
|
||||
// order for the container to be considered healthy.
|
||||
// +optional
|
||||
SuccessThreshold *int32 `json:"successThreshold,omitempty"`
|
||||
|
||||
// FailureThreshold specifies how many consecutive probes must fail in order
|
||||
// for the container to be considered healthy.
|
||||
// +optional
|
||||
FailureThreshold *int32 `json:"failureThreshold,omitempty"`
|
||||
}
|
||||
|
||||
// A Container represents an Open Containers Initiative (OCI) container.
|
||||
type Container struct {
|
||||
// Name of this container. Must be unique within its workload.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Image this container should run. Must be a path-like or URI-like
|
||||
// representation of an OCI image. May be prefixed with a registry address
|
||||
// and should be suffixed with a tag.
|
||||
Image string `json:"image"`
|
||||
|
||||
// Resources required by this container
|
||||
// +optional
|
||||
Resources *ContainerResources `json:"resources,omitempty"`
|
||||
|
||||
// Command to be run by this container.
|
||||
// +optional
|
||||
Command []string `json:"command,omitempty"`
|
||||
|
||||
// Arguments to be passed to the command run by this container.
|
||||
// +optional
|
||||
Arguments []string `json:"args,omitempty"`
|
||||
|
||||
// Environment variables that should be set within this container.
|
||||
// +optional
|
||||
Environment []ContainerEnvVar `json:"env,omitempty"`
|
||||
|
||||
// ConfigFiles that should be written within this container.
|
||||
// +optional
|
||||
ConfigFiles []ContainerConfigFile `json:"config,omitempty"`
|
||||
|
||||
// Ports exposed by this container.
|
||||
// +optional
|
||||
Ports []ContainerPort `json:"ports,omitempty"`
|
||||
|
||||
// A LivenessProbe assesses whether this container is alive. Containers that
|
||||
// fail liveness probes will be restarted.
|
||||
// +optional
|
||||
LivenessProbe *ContainerHealthProbe `json:"livenessProbe,omitempty"`
|
||||
|
||||
// A ReadinessProbe assesses whether this container is ready to serve
|
||||
// requests. Containers that fail readiness probes will be withdrawn from
|
||||
// service.
|
||||
// +optional
|
||||
ReadinessProbe *ContainerHealthProbe `json:"readinessProbe,omitempty"`
|
||||
|
||||
// TODO(negz): Ideally the key within this secret would be configurable, but
|
||||
// the current OAM spec allows only a secret name.
|
||||
|
||||
// ImagePullSecret specifies the name of a Secret from which the
|
||||
// credentials required to pull this container's image can be loaded.
|
||||
// +optional
|
||||
ImagePullSecret *string `json:"imagePullSecret,omitempty"`
|
||||
}
|
||||
@@ -1,22 +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 contains resources relating to the Open Application Model.
|
||||
// See https://github.com/oam-dev/spec for more details.
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=core.oam.dev
|
||||
// +versionName=v1alpha2
|
||||
package v1alpha2
|
||||
@@ -1,65 +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.
|
||||
*/
|
||||
|
||||
// This code is manually implemented, but should be generated in the future.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
)
|
||||
|
||||
// GetCondition of this ApplicationConfiguration.
|
||||
func (ac *ApplicationConfiguration) GetCondition(ct condition.ConditionType) condition.Condition {
|
||||
return ac.Status.GetCondition(ct)
|
||||
}
|
||||
|
||||
// SetConditions of this ApplicationConfiguration.
|
||||
func (ac *ApplicationConfiguration) SetConditions(c ...condition.Condition) {
|
||||
ac.Status.SetConditions(c...)
|
||||
}
|
||||
|
||||
// GetCondition of this Component.
|
||||
func (cm *Component) GetCondition(ct condition.ConditionType) condition.Condition {
|
||||
return cm.Status.GetCondition(ct)
|
||||
}
|
||||
|
||||
// SetConditions of this Component.
|
||||
func (cm *Component) SetConditions(c ...condition.Condition) {
|
||||
cm.Status.SetConditions(c...)
|
||||
}
|
||||
|
||||
// GetCondition of this HealthScope.
|
||||
func (hs *HealthScope) GetCondition(ct condition.ConditionType) condition.Condition {
|
||||
return hs.Status.GetCondition(ct)
|
||||
}
|
||||
|
||||
// SetConditions of this HealthScope.
|
||||
func (hs *HealthScope) SetConditions(c ...condition.Condition) {
|
||||
hs.Status.SetConditions(c...)
|
||||
}
|
||||
|
||||
// GetWorkloadReferences to get all workload references for scope.
|
||||
func (hs *HealthScope) GetWorkloadReferences() []corev1.ObjectReference {
|
||||
return hs.Spec.WorkloadReferences
|
||||
}
|
||||
|
||||
// AddWorkloadReference to add a workload reference to this scope.
|
||||
func (hs *HealthScope) AddWorkloadReference(r corev1.ObjectReference) {
|
||||
hs.Spec.WorkloadReferences = append(hs.Spec.WorkloadReferences, r)
|
||||
}
|
||||
@@ -1,124 +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 (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
)
|
||||
|
||||
// Package type metadata.
|
||||
const (
|
||||
Group = common.Group
|
||||
Version = "v1alpha2"
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
|
||||
)
|
||||
|
||||
// ComponentDefinition type metadata.
|
||||
var (
|
||||
ComponentDefinitionKind = reflect.TypeOf(ComponentDefinition{}).Name()
|
||||
ComponentDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: ComponentDefinitionKind}.String()
|
||||
ComponentDefinitionKindAPIVersion = ComponentDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
ComponentDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(ComponentDefinitionKind)
|
||||
)
|
||||
|
||||
// WorkloadDefinition type metadata.
|
||||
var (
|
||||
WorkloadDefinitionKind = reflect.TypeOf(WorkloadDefinition{}).Name()
|
||||
WorkloadDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: WorkloadDefinitionKind}.String()
|
||||
WorkloadDefinitionKindAPIVersion = WorkloadDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
WorkloadDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(WorkloadDefinitionKind)
|
||||
)
|
||||
|
||||
// TraitDefinition type metadata.
|
||||
var (
|
||||
TraitDefinitionKind = reflect.TypeOf(TraitDefinition{}).Name()
|
||||
TraitDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: TraitDefinitionKind}.String()
|
||||
TraitDefinitionKindAPIVersion = TraitDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
TraitDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(TraitDefinitionKind)
|
||||
)
|
||||
|
||||
// ScopeDefinition type metadata.
|
||||
var (
|
||||
ScopeDefinitionKind = reflect.TypeOf(ScopeDefinition{}).Name()
|
||||
ScopeDefinitionGroupKind = schema.GroupKind{Group: Group, Kind: ScopeDefinitionKind}.String()
|
||||
ScopeDefinitionKindAPIVersion = ScopeDefinitionKind + "." + SchemeGroupVersion.String()
|
||||
ScopeDefinitionGroupVersionKind = SchemeGroupVersion.WithKind(ScopeDefinitionKind)
|
||||
)
|
||||
|
||||
// Component type metadata.
|
||||
var (
|
||||
ComponentKind = reflect.TypeOf(Component{}).Name()
|
||||
ComponentGroupKind = schema.GroupKind{Group: Group, Kind: ComponentKind}.String()
|
||||
ComponentKindAPIVersion = ComponentKind + "." + SchemeGroupVersion.String()
|
||||
ComponentGroupVersionKind = SchemeGroupVersion.WithKind(ComponentKind)
|
||||
)
|
||||
|
||||
// ApplicationConfiguration type metadata.
|
||||
var (
|
||||
ApplicationConfigurationKind = reflect.TypeOf(ApplicationConfiguration{}).Name()
|
||||
ApplicationConfigurationGroupKind = schema.GroupKind{Group: Group, Kind: ApplicationConfigurationKind}.String()
|
||||
ApplicationConfigurationKindAPIVersion = ApplicationConfigurationKind + "." + SchemeGroupVersion.String()
|
||||
ApplicationConfigurationGroupVersionKind = SchemeGroupVersion.WithKind(ApplicationConfigurationKind)
|
||||
)
|
||||
|
||||
// HealthScope type metadata.
|
||||
var (
|
||||
HealthScopeKind = reflect.TypeOf(HealthScope{}).Name()
|
||||
HealthScopeGroupKind = schema.GroupKind{Group: Group, Kind: HealthScopeKind}.String()
|
||||
HealthScopeKindAPIVersion = HealthScopeKind + "." + SchemeGroupVersion.String()
|
||||
HealthScopeGroupVersionKind = SchemeGroupVersion.WithKind(HealthScopeKind)
|
||||
)
|
||||
|
||||
// Application type metadata.
|
||||
var (
|
||||
ApplicationKind = reflect.TypeOf(Application{}).Name()
|
||||
ApplicationGroupKind = schema.GroupKind{Group: Group, Kind: ApplicationKind}.String()
|
||||
ApplicationKindAPIVersion = ApplicationKind + "." + SchemeGroupVersion.String()
|
||||
ApplicationKindVersionKind = SchemeGroupVersion.WithKind(ApplicationKind)
|
||||
)
|
||||
|
||||
// ApplicationRevision type metadata
|
||||
var (
|
||||
ApplicationRevisionKind = reflect.TypeOf(ApplicationRevision{}).Name()
|
||||
ApplicationRevisionGroupKind = schema.GroupKind{Group: Group, Kind: ApplicationRevisionKind}.String()
|
||||
ApplicationRevisionKindAPIVersion = ApplicationRevisionKind + "." + SchemeGroupVersion.String()
|
||||
ApplicationRevisionGroupVersionKind = SchemeGroupVersion.WithKind(ApplicationRevisionKind)
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ComponentDefinition{}, &ComponentDefinitionList{})
|
||||
SchemeBuilder.Register(&WorkloadDefinition{}, &WorkloadDefinitionList{})
|
||||
SchemeBuilder.Register(&TraitDefinition{}, &TraitDefinitionList{})
|
||||
SchemeBuilder.Register(&ScopeDefinition{}, &ScopeDefinitionList{})
|
||||
SchemeBuilder.Register(&Component{}, &ComponentList{})
|
||||
SchemeBuilder.Register(&ApplicationConfiguration{}, &ApplicationConfigurationList{})
|
||||
SchemeBuilder.Register(&HealthScope{}, &HealthScopeList{})
|
||||
SchemeBuilder.Register(&Application{}, &ApplicationList{})
|
||||
SchemeBuilder.Register(&ApplicationRevision{}, &ApplicationRevisionList{})
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -205,7 +205,6 @@ func TestResourceTrackerCompression(t *testing.T) {
|
||||
"../../../charts/vela-core/templates/kubevela-controller.yaml",
|
||||
"../../../charts/vela-core/README.md",
|
||||
"../../../pkg/velaql/providers/query/testdata/machinelearning.seldon.io_seldondeployments.yaml",
|
||||
"../../../legacy/charts/vela-core-legacy/crds/standard.oam.dev_podspecworkloads.yaml",
|
||||
}
|
||||
for _, p := range paths {
|
||||
b, err := os.ReadFile(p)
|
||||
|
||||
@@ -25,10 +25,6 @@ limitations under the License.
|
||||
// Generate deepcopy methodsets and CRD manifests
|
||||
//go:generate go run -tags generate sigs.k8s.io/controller-tools/cmd/controller-gen object:headerFile=../hack/boilerplate.go.txt paths=./... crd:crdVersions=v1,generateEmbeddedObjectMeta=true output:artifacts:config=../config/crd/base
|
||||
|
||||
// Generate legacy_support for K8s 1.12~1.15 versions CRD manifests
|
||||
//go:generate go run -tags generate sigs.k8s.io/controller-tools/cmd/controller-gen object:headerFile=../hack/boilerplate.go.txt paths=./... crd:generateEmbeddedObjectMeta=true output:artifacts:config=../legacy/charts/vela-core-legacy/crds
|
||||
//go:generate go run ../legacy/convert/main.go ../legacy/charts/vela-core-legacy/crds
|
||||
|
||||
package apis
|
||||
|
||||
import (
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,868 +19,6 @@ spec:
|
||||
singular: application
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.components[*].name
|
||||
name: COMPONENT
|
||||
type: string
|
||||
- jsonPath: .spec.components[*].type
|
||||
name: TYPE
|
||||
type: string
|
||||
- jsonPath: .status.status
|
||||
name: PHASE
|
||||
type: string
|
||||
- jsonPath: .status.services[*].healthy
|
||||
name: HEALTHY
|
||||
type: boolean
|
||||
- jsonPath: .status.services[*].message
|
||||
name: STATUS
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: AGE
|
||||
type: date
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Application is the Schema for the applications 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: ApplicationSpec is the spec of Application
|
||||
properties:
|
||||
components:
|
||||
items:
|
||||
description: ApplicationComponent describe the component of application
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
scopes:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: scopes in ApplicationComponent defines the component-level
|
||||
scopes the format is <scope-type:scope-instance-name> pairs,
|
||||
the key represents type of `ScopeDefinition` while the value
|
||||
represent the name of scope instance.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
settings:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
traits:
|
||||
description: Traits define the trait of one component, the type
|
||||
must be array to keep the order.
|
||||
items:
|
||||
description: ApplicationTrait defines the trait of application
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
properties:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- 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
|
||||
x-kubernetes-map-type: atomic
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
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
|
||||
required:
|
||||
- components
|
||||
type: object
|
||||
status:
|
||||
description: AppStatus defines the observed state of Application
|
||||
properties:
|
||||
appliedResources:
|
||||
description: AppliedResources record the resources that the workflow
|
||||
step apply.
|
||||
items:
|
||||
description: ClusterObjectReference defines the object reference
|
||||
with cluster.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
cluster:
|
||||
type: string
|
||||
creator:
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
components:
|
||||
description: Components record the related Components created by Application
|
||||
Controller
|
||||
items:
|
||||
description: "ObjectReference contains enough information to let
|
||||
you inspect or modify the referred object. --- New uses of this
|
||||
type are discouraged because of difficulty describing its usage
|
||||
when embedded in APIs. 1. Ignored fields. It includes many fields
|
||||
which are not generally honored. For instance, ResourceVersion
|
||||
and FieldPath are both very rarely valid in actual usage. 2. Invalid
|
||||
usage help. It is impossible to add specific help for individual
|
||||
usage. In most embedded usages, there are particular restrictions
|
||||
like, \"must refer only to types A and B\" or \"UID not honored\"
|
||||
or \"name must be restricted\". Those cannot be well described
|
||||
when embedded. 3. Inconsistent validation. Because the usages
|
||||
are different, the validation rules are different by usage, which
|
||||
makes it hard for users to predict what will happen. 4. The fields
|
||||
are both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during interpretation
|
||||
and require a REST mapping. In most cases, the dependency is
|
||||
on the group,resource tuple and the version of the actual struct
|
||||
is irrelevant. 5. We cannot easily change it. Because this type
|
||||
is embedded in many locations, updates to this type will affect
|
||||
numerous schemas. Don't make new APIs embed an underspecified
|
||||
API type they do not control. \n Instead of using this type, create
|
||||
a locally provided and used type that is well-focused on your
|
||||
reference. For example, ServiceReferences for admission registration:
|
||||
https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
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
|
||||
latestRevision:
|
||||
description: LatestRevision of the application configuration it generates
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
observedGeneration:
|
||||
description: The generation observed by the application controller.
|
||||
format: int64
|
||||
type: integer
|
||||
policy:
|
||||
description: PolicyStatus records the status of policy Deprecated
|
||||
This field is only used by EnvBinding Policy which is deprecated.
|
||||
items:
|
||||
description: PolicyStatus records the status of policy Deprecated
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
status:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
services:
|
||||
description: Services record the status of the application services
|
||||
items:
|
||||
description: ApplicationComponentStatus record the health status
|
||||
of App component
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
env:
|
||||
type: string
|
||||
healthy:
|
||||
type: boolean
|
||||
message:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
scopes:
|
||||
items:
|
||||
description: "ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object. --- New
|
||||
uses of this type are discouraged because of difficulty
|
||||
describing its usage when embedded in APIs. 1. Ignored fields.
|
||||
\ It includes many fields which are not generally honored.
|
||||
\ For instance, ResourceVersion and FieldPath are both very
|
||||
rarely valid in actual usage. 2. Invalid usage help. It
|
||||
is impossible to add specific help for individual usage.
|
||||
\ In most embedded usages, there are particular restrictions
|
||||
like, \"must refer only to types A and B\" or \"UID not
|
||||
honored\" or \"name must be restricted\". Those cannot be
|
||||
well described when embedded. 3. Inconsistent validation.
|
||||
\ Because the usages are different, the validation rules
|
||||
are different by usage, which makes it hard for users to
|
||||
predict what will happen. 4. The fields are both imprecise
|
||||
and overly precise. Kind is not a precise mapping to a
|
||||
URL. This can produce ambiguity during interpretation and
|
||||
require a REST mapping. In most cases, the dependency is
|
||||
on the group,resource tuple and the version of the actual
|
||||
struct is irrelevant. 5. We cannot easily change it. Because
|
||||
this type is embedded in many locations, updates to this
|
||||
type will affect numerous schemas. Don't make new APIs
|
||||
embed an underspecified API type they do not control. \n
|
||||
Instead of using this type, create a locally provided and
|
||||
used type that is well-focused on your reference. For example,
|
||||
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
traits:
|
||||
items:
|
||||
description: ApplicationTraitStatus records the trait health
|
||||
status
|
||||
properties:
|
||||
healthy:
|
||||
type: boolean
|
||||
message:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- healthy
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
workloadDefinition:
|
||||
description: WorkloadDefinition is the definition of a WorkloadDefinition,
|
||||
such as deployments/apps.v1
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
required:
|
||||
- healthy
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
status:
|
||||
description: ApplicationPhase is a label for the condition of an application
|
||||
at the current time
|
||||
type: string
|
||||
workflow:
|
||||
description: Workflow record the status of workflow
|
||||
properties:
|
||||
appRevision:
|
||||
type: string
|
||||
contextBackend:
|
||||
description: "ObjectReference contains enough information to let
|
||||
you inspect or modify the referred object. --- New uses of this
|
||||
type are discouraged because of difficulty describing its usage
|
||||
when embedded in APIs. 1. Ignored fields. It includes many
|
||||
fields which are not generally honored. For instance, ResourceVersion
|
||||
and FieldPath are both very rarely valid in actual usage. 2.
|
||||
Invalid usage help. It is impossible to add specific help for
|
||||
individual usage. In most embedded usages, there are particular
|
||||
restrictions like, \"must refer only to types A and B\" or \"UID
|
||||
not honored\" or \"name must be restricted\". Those cannot be
|
||||
well described when embedded. 3. Inconsistent validation. Because
|
||||
the usages are different, the validation rules are different
|
||||
by usage, which makes it hard for users to predict what will
|
||||
happen. 4. The fields are both imprecise and overly precise.
|
||||
\ Kind is not a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping. In most cases,
|
||||
the dependency is on the group,resource tuple and the version
|
||||
of the actual struct is irrelevant. 5. We cannot easily change
|
||||
it. Because this type is embedded in many locations, updates
|
||||
to this type will affect numerous schemas. Don't make new APIs
|
||||
embed an underspecified API type they do not control. \n Instead
|
||||
of using this type, create a locally provided and used type
|
||||
that is well-focused on your reference. For example, ServiceReferences
|
||||
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
message:
|
||||
type: string
|
||||
mode:
|
||||
type: string
|
||||
startTime:
|
||||
format: date-time
|
||||
type: string
|
||||
status:
|
||||
description: WorkflowRunPhase is a label for the condition of
|
||||
a WorkflowRun at the current time
|
||||
type: string
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStepStatus record the status of a workflow
|
||||
step, include step status and subStep status
|
||||
properties:
|
||||
firstExecuteTime:
|
||||
description: FirstExecuteTime is the first time this step
|
||||
execution.
|
||||
format: date-time
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
lastExecuteTime:
|
||||
description: LastExecuteTime is the last time this step
|
||||
execution.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A human readable message indicating details
|
||||
about why the workflowStep is in this state.
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
phase:
|
||||
description: WorkflowStepPhase describes the phase of a
|
||||
workflow step.
|
||||
type: string
|
||||
reason:
|
||||
description: A brief CamelCase message indicating details
|
||||
about why the workflowStep is in this state.
|
||||
type: string
|
||||
subSteps:
|
||||
items:
|
||||
description: StepStatus record the base status of workflow
|
||||
step, which could be workflow step or subStep
|
||||
properties:
|
||||
firstExecuteTime:
|
||||
description: FirstExecuteTime is the first time this
|
||||
step execution.
|
||||
format: date-time
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
lastExecuteTime:
|
||||
description: LastExecuteTime is the last time this
|
||||
step execution.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A human readable message indicating details
|
||||
about why the workflowStep is in this state.
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
phase:
|
||||
description: WorkflowStepPhase describes the phase
|
||||
of a workflow step.
|
||||
type: string
|
||||
reason:
|
||||
description: A brief CamelCase message indicating
|
||||
details about why the workflowStep is in this state.
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
type: object
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
suspendState:
|
||||
type: string
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- finished
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.components[*].name
|
||||
name: COMPONENT
|
||||
|
||||
@@ -18,333 +18,6 @@ spec:
|
||||
singular: componentdefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.workload.definition.kind
|
||||
name: WORKLOAD-KIND
|
||||
type: string
|
||||
- jsonPath: .metadata.annotations.definition\.oam\.dev/description
|
||||
name: DESCRIPTION
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ComponentDefinition is the Schema for the componentdefinitions
|
||||
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: ComponentDefinitionSpec defines the desired state of ComponentDefinition
|
||||
properties:
|
||||
childResourceKinds:
|
||||
description: ChildResourceKinds are the list of GVK of the child resources
|
||||
this workload generates
|
||||
items:
|
||||
description: A ChildResourceKind defines a child Kubernetes resource
|
||||
kind with a selector
|
||||
properties:
|
||||
apiVersion:
|
||||
description: APIVersion of the child resource
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the child resource
|
||||
type: string
|
||||
selector:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Selector to select the child resources that the
|
||||
workload wants to expose to traits
|
||||
type: object
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type: array
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
podSpecPath:
|
||||
description: PodSpecPath indicates where/if this workload has K8s
|
||||
podSpec field if one workload has podSpec, trait can do lot's of
|
||||
assumption such as port, env, volume fields.
|
||||
type: string
|
||||
revisionLabel:
|
||||
description: RevisionLabel indicates which label for underlying resources(e.g.
|
||||
pods) of this workload can be used by trait to create resource selectors(e.g.
|
||||
label selector for pods).
|
||||
type: string
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workload
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
default: false
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for workload
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
workload:
|
||||
description: Workload is a workload type descriptor
|
||||
properties:
|
||||
definition:
|
||||
description: Definition mutually exclusive to workload.type, a
|
||||
embedded WorkloadDefinition
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type:
|
||||
description: Type ref to a WorkloadDefinition via name
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- workload
|
||||
type: object
|
||||
status:
|
||||
description: ComponentDefinitionStatus is the status of ComponentDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.workload.definition.kind
|
||||
name: WORKLOAD-KIND
|
||||
|
||||
@@ -1,586 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.3
|
||||
name: healthscopes.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: HealthScope
|
||||
listKind: HealthScopeList
|
||||
plural: healthscopes
|
||||
singular: healthscope
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.health
|
||||
name: HEALTH
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A HealthScope determines an aggregate health status based of
|
||||
the health of components.
|
||||
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: A HealthScopeSpec defines the desired state of a HealthScope.
|
||||
properties:
|
||||
appReferences:
|
||||
description: AppRefs records references of applications' components
|
||||
items:
|
||||
description: AppReference records references of an application's
|
||||
components
|
||||
properties:
|
||||
appName:
|
||||
type: string
|
||||
compReferences:
|
||||
items:
|
||||
description: CompReference records references of a component's
|
||||
resources
|
||||
properties:
|
||||
compName:
|
||||
type: string
|
||||
traits:
|
||||
items:
|
||||
description: "ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object.
|
||||
--- New uses of this type are discouraged because
|
||||
of difficulty describing its usage when embedded in
|
||||
APIs. 1. Ignored fields. It includes many fields
|
||||
which are not generally honored. For instance, ResourceVersion
|
||||
and FieldPath are both very rarely valid in actual
|
||||
usage. 2. Invalid usage help. It is impossible to
|
||||
add specific help for individual usage. In most embedded
|
||||
usages, there are particular restrictions like, \"must
|
||||
refer only to types A and B\" or \"UID not honored\"
|
||||
or \"name must be restricted\". Those cannot be well
|
||||
described when embedded. 3. Inconsistent validation.
|
||||
\ Because the usages are different, the validation
|
||||
rules are different by usage, which makes it hard
|
||||
for users to predict what will happen. 4. The fields
|
||||
are both imprecise and overly precise. Kind is not
|
||||
a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping.
|
||||
\ In most cases, the dependency is on the group,resource
|
||||
tuple and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type
|
||||
is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs
|
||||
embed an underspecified API type they do not control.
|
||||
\n Instead of using this type, create a locally provided
|
||||
and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration:
|
||||
https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
workload:
|
||||
description: "ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object. ---
|
||||
New uses of this type are discouraged because of difficulty
|
||||
describing its usage when embedded in APIs. 1. Ignored
|
||||
fields. It includes many fields which are not generally
|
||||
honored. For instance, ResourceVersion and FieldPath
|
||||
are both very rarely valid in actual usage. 2. Invalid
|
||||
usage help. It is impossible to add specific help for
|
||||
individual usage. In most embedded usages, there are
|
||||
particular restrictions like, \"must refer only to types
|
||||
A and B\" or \"UID not honored\" or \"name must be restricted\".
|
||||
Those cannot be well described when embedded. 3. Inconsistent
|
||||
validation. Because the usages are different, the validation
|
||||
rules are different by usage, which makes it hard for
|
||||
users to predict what will happen. 4. The fields are
|
||||
both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during
|
||||
interpretation and require a REST mapping. In most
|
||||
cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is
|
||||
embedded in many locations, updates to this type will
|
||||
affect numerous schemas. Don't make new APIs embed
|
||||
an underspecified API type they do not control. \n Instead
|
||||
of using this type, create a locally provided and used
|
||||
type that is well-focused on your reference. For example,
|
||||
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
probe-interval:
|
||||
description: ProbeInterval is the amount of time in seconds between
|
||||
probing tries.
|
||||
format: int32
|
||||
type: integer
|
||||
probe-timeout:
|
||||
description: ProbeTimeout is the amount of time in seconds to wait
|
||||
when receiving a response before marked failure.
|
||||
format: int32
|
||||
type: integer
|
||||
workloadRefs:
|
||||
description: WorkloadReferences to the workloads that are in this
|
||||
scope.
|
||||
items:
|
||||
description: "ObjectReference contains enough information to let
|
||||
you inspect or modify the referred object. --- New uses of this
|
||||
type are discouraged because of difficulty describing its usage
|
||||
when embedded in APIs. 1. Ignored fields. It includes many fields
|
||||
which are not generally honored. For instance, ResourceVersion
|
||||
and FieldPath are both very rarely valid in actual usage. 2. Invalid
|
||||
usage help. It is impossible to add specific help for individual
|
||||
usage. In most embedded usages, there are particular restrictions
|
||||
like, \"must refer only to types A and B\" or \"UID not honored\"
|
||||
or \"name must be restricted\". Those cannot be well described
|
||||
when embedded. 3. Inconsistent validation. Because the usages
|
||||
are different, the validation rules are different by usage, which
|
||||
makes it hard for users to predict what will happen. 4. The fields
|
||||
are both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during interpretation
|
||||
and require a REST mapping. In most cases, the dependency is
|
||||
on the group,resource tuple and the version of the actual struct
|
||||
is irrelevant. 5. We cannot easily change it. Because this type
|
||||
is embedded in many locations, updates to this type will affect
|
||||
numerous schemas. Don't make new APIs embed an underspecified
|
||||
API type they do not control. \n Instead of using this type, create
|
||||
a locally provided and used type that is well-focused on your
|
||||
reference. For example, ServiceReferences for admission registration:
|
||||
https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
required:
|
||||
- workloadRefs
|
||||
type: object
|
||||
status:
|
||||
description: A HealthScopeStatus represents the observed state of a HealthScope.
|
||||
properties:
|
||||
appHealthConditions:
|
||||
description: AppHealthConditions represents health condition of applications
|
||||
in the scope
|
||||
items:
|
||||
description: AppHealthCondition represents health condition of an
|
||||
application
|
||||
properties:
|
||||
appName:
|
||||
type: string
|
||||
components:
|
||||
items:
|
||||
description: WorkloadHealthCondition represents informative
|
||||
health condition of a workload.
|
||||
properties:
|
||||
componentName:
|
||||
description: ComponentName represents the component name
|
||||
if target is a workload
|
||||
type: string
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
targetWorkload:
|
||||
description: "ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object. ---
|
||||
New uses of this type are discouraged because of difficulty
|
||||
describing its usage when embedded in APIs. 1. Ignored
|
||||
fields. It includes many fields which are not generally
|
||||
honored. For instance, ResourceVersion and FieldPath
|
||||
are both very rarely valid in actual usage. 2. Invalid
|
||||
usage help. It is impossible to add specific help for
|
||||
individual usage. In most embedded usages, there are
|
||||
particular restrictions like, \"must refer only to types
|
||||
A and B\" or \"UID not honored\" or \"name must be restricted\".
|
||||
Those cannot be well described when embedded. 3. Inconsistent
|
||||
validation. Because the usages are different, the validation
|
||||
rules are different by usage, which makes it hard for
|
||||
users to predict what will happen. 4. The fields are
|
||||
both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during
|
||||
interpretation and require a REST mapping. In most
|
||||
cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is
|
||||
embedded in many locations, updates to this type will
|
||||
affect numerous schemas. Don't make new APIs embed
|
||||
an underspecified API type they do not control. \n Instead
|
||||
of using this type, create a locally provided and used
|
||||
type that is well-focused on your reference. For example,
|
||||
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
traits:
|
||||
items:
|
||||
description: TraitHealthCondition represents informative
|
||||
health condition of a trait.
|
||||
properties:
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status
|
||||
strings.
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
- resource
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
workloadStatus:
|
||||
description: WorkloadStatus represents status of workloads
|
||||
whose HealthStatus is UNKNOWN.
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
type: object
|
||||
type: array
|
||||
envName:
|
||||
type: string
|
||||
required:
|
||||
- appName
|
||||
type: object
|
||||
type: array
|
||||
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
|
||||
healthConditions:
|
||||
description: WorkloadHealthConditions represents health condition
|
||||
of workloads in the scope Use AppHealthConditions to provide app
|
||||
level status
|
||||
items:
|
||||
description: WorkloadHealthCondition represents informative health
|
||||
condition of a workload.
|
||||
properties:
|
||||
componentName:
|
||||
description: ComponentName represents the component name if
|
||||
target is a workload
|
||||
type: string
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
targetWorkload:
|
||||
description: "ObjectReference contains enough information to
|
||||
let you inspect or modify the referred object. --- New uses
|
||||
of this type are discouraged because of difficulty describing
|
||||
its usage when embedded in APIs. 1. Ignored fields. It includes
|
||||
many fields which are not generally honored. For instance,
|
||||
ResourceVersion and FieldPath are both very rarely valid in
|
||||
actual usage. 2. Invalid usage help. It is impossible to
|
||||
add specific help for individual usage. In most embedded
|
||||
usages, there are particular restrictions like, \"must refer
|
||||
only to types A and B\" or \"UID not honored\" or \"name must
|
||||
be restricted\". Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different,
|
||||
the validation rules are different by usage, which makes it
|
||||
hard for users to predict what will happen. 4. The fields
|
||||
are both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during interpretation
|
||||
and require a REST mapping. In most cases, the dependency
|
||||
is on the group,resource tuple and the version of the actual
|
||||
struct is irrelevant. 5. We cannot easily change it. Because
|
||||
this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an
|
||||
underspecified API type they do not control. \n Instead of
|
||||
using this type, create a locally provided and used type that
|
||||
is well-focused on your reference. For example, ServiceReferences
|
||||
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
traits:
|
||||
items:
|
||||
description: TraitHealthCondition represents informative health
|
||||
condition of a trait.
|
||||
properties:
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
- resource
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
workloadStatus:
|
||||
description: WorkloadStatus represents status of workloads whose
|
||||
HealthStatus is UNKNOWN.
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
type: object
|
||||
type: array
|
||||
scopeHealthCondition:
|
||||
description: ScopeHealthCondition represents health condition summary
|
||||
of the scope
|
||||
properties:
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
healthyWorkloads:
|
||||
format: int64
|
||||
type: integer
|
||||
total:
|
||||
format: int64
|
||||
type: integer
|
||||
unhealthyWorkloads:
|
||||
format: int64
|
||||
type: integer
|
||||
unknownWorkloads:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- healthStatus
|
||||
type: object
|
||||
required:
|
||||
- scopeHealthCondition
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -18,69 +18,6 @@ spec:
|
||||
singular: scopedefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.definitionRef.name
|
||||
name: DEFINITION-NAME
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A ScopeDefinition registers a kind of Kubernetes custom resource
|
||||
as a valid OAM scope kind by referencing its CustomResourceDefinition. The
|
||||
CRD is used to validate the schema of the scope when it is embedded in an
|
||||
OAM ApplicationConfiguration.
|
||||
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: A ScopeDefinitionSpec defines the desired state of a ScopeDefinition.
|
||||
properties:
|
||||
allowComponentOverlap:
|
||||
description: AllowComponentOverlap specifies whether an OAM component
|
||||
may exist in multiple instances of this kind of scope.
|
||||
type: boolean
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this scope kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
workloadRefsPath:
|
||||
description: WorkloadRefsPath indicates if/where a scope accepts workloadRef
|
||||
objects
|
||||
type: string
|
||||
required:
|
||||
- allowComponentOverlap
|
||||
- definitionRef
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.definitionRef.name
|
||||
name: DEFINITION-NAME
|
||||
@@ -131,7 +68,7 @@ spec:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
workloadRefsPath:
|
||||
description: WorkloadRefsPath indicates if/where a scope accepts workloadRef
|
||||
objects
|
||||
@@ -18,325 +18,6 @@ spec:
|
||||
singular: traitdefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.appliesToWorkloads
|
||||
name: APPLIES-TO
|
||||
type: string
|
||||
- jsonPath: .metadata.annotations.definition\.oam\.dev/description
|
||||
name: DESCRIPTION
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A TraitDefinition registers a kind of Kubernetes custom resource
|
||||
as a valid OAM trait kind by referencing its CustomResourceDefinition. The
|
||||
CRD is used to validate the schema of the trait when it is embedded in an
|
||||
OAM ApplicationConfiguration.
|
||||
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: A TraitDefinitionSpec defines the desired state of a TraitDefinition.
|
||||
properties:
|
||||
appliesToWorkloads:
|
||||
description: AppliesToWorkloads specifies the list of workload kinds
|
||||
this trait applies to. Workload kinds are specified in kind.group/version
|
||||
format, e.g. server.core.oam.dev/v1alpha2. Traits that omit this
|
||||
field apply to all workload kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
conflictsWith:
|
||||
description: 'ConflictsWith specifies the list of traits(CRD name,
|
||||
Definition name, CRD group) which could not apply to the same workloads
|
||||
with this trait. Traits that omit this field can work with any other
|
||||
traits. Example rules: "service" # Trait definition name "services.k8s.io"
|
||||
# API resource/crd name "*.networking.k8s.io" # API group "labelSelector:foo=bar"
|
||||
# label selector labelSelector format: https://pkg.go.dev/k8s.io/apimachinery/pkg/labels#Parse'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this trait kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
podDisruptive:
|
||||
description: PodDisruptive specifies whether using the trait will
|
||||
cause the pod to restart or not.
|
||||
type: boolean
|
||||
revisionEnabled:
|
||||
description: Revision indicates whether a trait is aware of component
|
||||
revision
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the trait
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
default: false
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for trait
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
workloadRefPath:
|
||||
description: WorkloadRefPath indicates where/if a trait accepts a
|
||||
workloadRef object
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
description: TraitDefinitionStatus is the status of TraitDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the trait definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.appliesToWorkloads
|
||||
name: APPLIES-TO
|
||||
|
||||
@@ -45,11 +45,9 @@ import (
|
||||
"github.com/oam-dev/kubevela/cmd/core/app/options"
|
||||
"github.com/oam-dev/kubevela/pkg/auth"
|
||||
"github.com/oam-dev/kubevela/pkg/cache"
|
||||
standardcontroller "github.com/oam-dev/kubevela/pkg/controller"
|
||||
commonconfig "github.com/oam-dev/kubevela/pkg/controller/common"
|
||||
oamv1alpha2 "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/application"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
oamv1alpha2 "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/application"
|
||||
"github.com/oam-dev/kubevela/pkg/features"
|
||||
"github.com/oam-dev/kubevela/pkg/monitor/watcher"
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
@@ -171,11 +169,6 @@ func run(ctx context.Context, s *options.CoreOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := utils.CheckDisabledCapabilities(s.DisableCaps); err != nil {
|
||||
klog.ErrorS(err, "Unable to get enabled capabilities")
|
||||
return err
|
||||
}
|
||||
|
||||
pd, err := packages.NewPackageDiscover(mgr.GetConfig())
|
||||
if err != nil {
|
||||
klog.Error(err, "Failed to create CRD discovery for CUE package client")
|
||||
@@ -247,11 +240,6 @@ func prepareRun(ctx context.Context, mgr manager.Manager, s *options.CoreOptions
|
||||
return err
|
||||
}
|
||||
|
||||
if err := standardcontroller.Setup(mgr, s.DisableCaps, *s.ControllerArgs); err != nil {
|
||||
klog.ErrorS(err, "Unable to setup the vela core controller")
|
||||
return err
|
||||
}
|
||||
|
||||
if err := multicluster.InitClusterInfo(mgr.GetConfig()); err != nil {
|
||||
klog.ErrorS(err, "Init control plane cluster info")
|
||||
return err
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: alibaba-oss
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
# WorkFlow with OCM
|
||||
|
||||
In this tutorial, you will create an ack cluster as a production environment and deploy the configured app
|
||||
to this production environment.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- In order to follow the guide, you will need a Kubernetes cluster version 1.20+ as control-plane cluster, and
|
||||
the cluster's APIServer has an external IP.
|
||||
|
||||
- Store the AK/AS of Alibaba Cloud to the Secret.
|
||||
|
||||
```shell
|
||||
export ALICLOUD_ACCESS_KEY=xxx; export ALICLOUD_SECRET_KEY=yyy
|
||||
```
|
||||
|
||||
```shell
|
||||
# If you'd like to use Alicloud Security Token Service, also export `ALICLOUD_SECURITY_TOKEN`.
|
||||
export ALICLOUD_SECURITY_TOKEN=zzz
|
||||
```
|
||||
|
||||
```shell
|
||||
sh hack/prepare-alibaba-credentials.sh
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl get secret -n vela-system
|
||||
NAME TYPE DATA AGE
|
||||
alibaba-account-creds Opaque 1 11s
|
||||
```
|
||||
|
||||
- Install Definitions
|
||||
```shell
|
||||
kubectl apply -f definitions
|
||||
```
|
||||
|
||||
## Create Initializer terraform-alibaba
|
||||
|
||||
Initializer terraform-alibaba will create an environment which allows users use terraform to create cloud resource on aliyun.
|
||||
|
||||
```shell
|
||||
kubectl apply -f initializers/init-terraform-alibaba.yaml
|
||||
```
|
||||
|
||||
It will take few minutes to wait the `PHASE` of Initializer `terraform-alibaba` to be `success`.
|
||||
|
||||
```shell
|
||||
$ kubectl get initializers.core.oam.dev -n vela-system
|
||||
NAMESPACE NAME PHASE AGE
|
||||
vela-system terraform-alibaba success 94s
|
||||
```
|
||||
|
||||
## Create Initializer managed-cluster
|
||||
|
||||
Initializer managed-cluster can create an ack cluster and use OCM to manage the cluster.
|
||||
|
||||
1. You should set the `hubAPIServer` to the public network address in `init-managed-cluster.yaml`
|
||||
```yaml
|
||||
# init-managed-cluster.yaml
|
||||
- name: register-ack
|
||||
type: register-cluster
|
||||
inputs:
|
||||
...
|
||||
properties:
|
||||
# user should set public network address of your control-plane cluster APIServer
|
||||
hubAPIServer: {{ public network address of APIServer }}
|
||||
```
|
||||
|
||||
2. Apply the Initializer managed-cluster
|
||||
```shell
|
||||
kubectl apply -f initializers/init-managed-cluster.yaml
|
||||
```
|
||||
|
||||
It will take 15 to 20 minutes to create an ack cluster, please wait until the status of `managed-cluster` to be `success`.
|
||||
|
||||
```shell
|
||||
$ kubectl get initializers.core.oam.dev -n vela-system
|
||||
NAMESPACE NAME PHASE AGE
|
||||
vela-system managed-cluster success 45m
|
||||
```
|
||||
|
||||
3. Check the new ack cluster has been registered
|
||||
|
||||
```shell
|
||||
$ kubectl get managedclusters.cluster.open-cluster-management.io
|
||||
NAME HUB ACCEPTED MANAGED CLUSTER URLS JOINED AVAILABLE AGE
|
||||
poc-01 true {{ APIServer address }} True True 30s
|
||||
```
|
||||
|
||||
|
||||
## Deploy the resource to ack cluster
|
||||
|
||||
install trait `expose` from default capability center.
|
||||
|
||||
```shell
|
||||
vela cap install default-cap-center/expose
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl apply -f app.yaml
|
||||
```
|
||||
|
||||
check the app `workflow-demo` was created successfully
|
||||
|
||||
```shell
|
||||
$ kubectl get app workflow-demo
|
||||
NAME COMPONENT TYPE PHASE HEALTHY STATUS AGE
|
||||
workflow-demo podinfo-server webservice running true 7s
|
||||
```
|
||||
|
||||
use kubectl connect to the managed-cluster `poc-01` and check the resources in the app
|
||||
are successfully deployed to the cluster `poc-01`.
|
||||
|
||||
```shell
|
||||
$ kubectl get deployments
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
podinfo-server 1/1 1 1 40s
|
||||
```
|
||||
@@ -1,48 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: workflow-demo
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: podinfo-server
|
||||
type: webservice
|
||||
properties:
|
||||
image: stefanprodan/podinfo:5.2.1
|
||||
port: 9898
|
||||
traits:
|
||||
- type: expose
|
||||
properties:
|
||||
port: [9898]
|
||||
|
||||
policies:
|
||||
- name: prod-env
|
||||
type: env-binding
|
||||
properties:
|
||||
engine: ocm
|
||||
envs:
|
||||
- name: prod
|
||||
patch:
|
||||
components:
|
||||
- name: podinfo-server
|
||||
type: webservice
|
||||
properties:
|
||||
image: stefanprodan/podinfo:6.0.0
|
||||
port: 9898
|
||||
traits:
|
||||
- type: expose
|
||||
properties:
|
||||
port: [9898]
|
||||
type: LoadBalancer
|
||||
placement:
|
||||
clusterSelector:
|
||||
labels:
|
||||
purpose: test
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: deploy-server
|
||||
type: mutil-env
|
||||
properties:
|
||||
env: prod
|
||||
policy: prod-env
|
||||
@@ -1,57 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
name: create-ack
|
||||
namespace: vela-system
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"vela/op"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
configuration: op.#Load & {
|
||||
component: parameter.component
|
||||
}
|
||||
|
||||
apply: op.#Apply & {
|
||||
value: {
|
||||
configuration.value.workload
|
||||
}
|
||||
}
|
||||
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: apply.value.status.state == "Available"
|
||||
}
|
||||
|
||||
secretName: apply.value.spec.writeConnectionSecretToRef.name
|
||||
secretNamespace: apply.value.spec.writeConnectionSecretToRef.namespace
|
||||
|
||||
ackConn: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
kind: "Secret"
|
||||
metadata: {
|
||||
name: secretName
|
||||
namespace: secretNamespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parameter: {
|
||||
component: string
|
||||
}
|
||||
|
||||
connInfo: {
|
||||
clusterName: base64.Decode(null, ackConn.value.data["name"])
|
||||
clusterCACert: base64.Decode(null, ackConn.value.data["cluster_ca_cert"])
|
||||
clientCert: base64.Decode(null, ackConn.value.data["client_cert"])
|
||||
clientKey: base64.Decode(null, ackConn.value.data["client_key"])
|
||||
clusterAPIServer: base64.Decode(null, ackConn.value.data["api_server_internet"])
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
name: register-cluster
|
||||
namespace: vela-system
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import ("vela/op")
|
||||
|
||||
clusterrole: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "rbac.authorization.k8s.io/v1"
|
||||
kind: "ClusterRole"
|
||||
metadata: {
|
||||
name: "cluster-register"
|
||||
}
|
||||
rules: [{
|
||||
apiGroups: [""]
|
||||
resources: ["configmaps", "namespaces", "serviceaccounts", "services", "secrets"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
|
||||
}, {
|
||||
apiGroups: ["", "events.k8s.io"]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "update", "patch"]
|
||||
}, {
|
||||
apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterrolebindings", "rolebindings"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
|
||||
}, {
|
||||
apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles", "roles"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "escalate", "bind"]
|
||||
}, {
|
||||
apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles", "roles"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "escalate", "bind"]
|
||||
}, {
|
||||
apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["certificatesigningrequests"]
|
||||
verbs: ["create", "get", "list", "watch"]
|
||||
}, {
|
||||
apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["certificatesigningrequests/approval"]
|
||||
verbs: ["update"]
|
||||
}, {
|
||||
apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["signers"]
|
||||
resourceNames: ["kubernetes.io/*"]
|
||||
verbs: ["approve"]
|
||||
}, {
|
||||
apiGroups: ["cluster.open-cluster-management.io"]
|
||||
resources: ["managedclusters"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "delete"]
|
||||
}, {
|
||||
apiGroups: ["register.open-cluster-management.io"]
|
||||
resources: ["managedclusters", "managedclusters/accept"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "delete"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
serviceaccount: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
kind: "ServiceAccount"
|
||||
metadata: {
|
||||
name: "cluster-register"
|
||||
namespace: "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rolebinding: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "rbac.authorization.k8s.io/v1"
|
||||
kind: "ClusterRoleBinding"
|
||||
metadata: {
|
||||
name: "cluster-register"
|
||||
}
|
||||
roleRef: {
|
||||
apiGroup: "rbac.authorization.k8s.io"
|
||||
kind: "ClusterRole"
|
||||
name: "cluster-register"
|
||||
}
|
||||
subjects: [{
|
||||
kind: "ServiceAccount"
|
||||
name: "cluster-register"
|
||||
namespace: "default"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
register: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "batch/v1"
|
||||
kind: "Job"
|
||||
metadata: {
|
||||
name: "cluster-register"
|
||||
namespace: "default"
|
||||
}
|
||||
spec: {
|
||||
template: {
|
||||
spec: {
|
||||
containers: [{
|
||||
name: "cluster-register"
|
||||
image: "oamdev/cluster-register:v1.0"
|
||||
imagePullPolicy: "Always"
|
||||
command: [
|
||||
"/app", "--cluster-name=" + "\(parameter.connInfo.clusterName)",
|
||||
"--hub-api-server=" + "\(parameter.hubAPIServer)",
|
||||
"--cluster-ca-cert=" + "\(parameter.connInfo.clusterCACert)",
|
||||
"--client-cert=" + "\(parameter.connInfo.clientCert)",
|
||||
"--client-key=" + "\(parameter.connInfo.clientKey)",
|
||||
"--api-server-internet=" + "\(parameter.connInfo.clusterAPIServer)",
|
||||
"--kube-config=" + "\(parameter.connInfo.kubeConfig)",
|
||||
]
|
||||
}]
|
||||
restartPolicy: "OnFailure"
|
||||
serviceAccountName: "cluster-register"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: register.value.status.succeeded == 1
|
||||
}
|
||||
|
||||
clusterSet: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "cluster.open-cluster-management.io/v1alpha1"
|
||||
kind: "ManagedClusterSet"
|
||||
metadata: name: parameter.env
|
||||
}
|
||||
}
|
||||
|
||||
clusterSetBinding: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "cluster.open-cluster-management.io/v1alpha1"
|
||||
kind: "ManagedClusterSetBinding"
|
||||
metadata: {
|
||||
name: parameter.env
|
||||
namespace: parameter.initNameSpace
|
||||
}
|
||||
spec: clusterSet: parameter.env
|
||||
}
|
||||
}
|
||||
|
||||
managedCluster: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "cluster.open-cluster-management.io/v1"
|
||||
kind: "ManagedCluster"
|
||||
metadata: {
|
||||
name: parameter.connInfo.clusterName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
patchManagedCluster: op.#Apply & {
|
||||
value: {
|
||||
managedCluster.value
|
||||
metadata: labels: {
|
||||
"cluster.open-cluster-management.io/clusterset": parameter.env
|
||||
}
|
||||
metadata: labels: parameter.patchLabels
|
||||
}
|
||||
}
|
||||
|
||||
parameter: {
|
||||
env: string
|
||||
initNameSpace: *"default" | string
|
||||
patchLabels: [string]: string
|
||||
hubAPIServer: *"" | string
|
||||
connInfo: {
|
||||
clusterName: string
|
||||
clusterCACert: *"" | string
|
||||
clientCert: *"" | string
|
||||
clientKey: *"" | string
|
||||
clusterAPIServer: *"" | string
|
||||
kubeConfig: *"" | string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "accessKeyID: ${ALICLOUD_ACCESS_KEY}\naccessKeySecret: ${ALICLOUD_SECRET_KEY}\nsecurityToken: ${ALICLOUD_SECURITY_TOKEN}" > alibaba-credentials.conf
|
||||
kubectl create namespace vela-system
|
||||
kubectl create secret generic alibaba-account-creds -n vela-system --from-file=credentials=alibaba-credentials.conf
|
||||
rm -f alibaba-credentials.conf
|
||||
@@ -1,48 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Initializer
|
||||
metadata:
|
||||
name: managed-cluster
|
||||
namespace: vela-system
|
||||
spec:
|
||||
appTemplate:
|
||||
spec:
|
||||
components:
|
||||
- name: ack-worker
|
||||
type: alibaba-ack
|
||||
properties:
|
||||
writeConnectionSecretToRef:
|
||||
name: ack-conn
|
||||
namespace: vela-system
|
||||
workflow:
|
||||
steps:
|
||||
- name: terraform-ack
|
||||
type: create-ack
|
||||
properties:
|
||||
component: ack-worker
|
||||
outputs:
|
||||
- name: connInfo
|
||||
valueFrom: connInfo
|
||||
|
||||
- name: register-ack
|
||||
type: register-cluster
|
||||
inputs:
|
||||
- from: connInfo
|
||||
parameterKey: connInfo
|
||||
properties:
|
||||
# user should set public network address of APIServer
|
||||
hubAPIServer: {{ public network address of APIServer }}
|
||||
env: prod
|
||||
initNameSpace: default
|
||||
patchLabels:
|
||||
purpose: test
|
||||
dependsOn:
|
||||
- ref:
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Initializer
|
||||
name: terraform-alibaba
|
||||
namespace: vela-system
|
||||
- ref:
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Initializer
|
||||
name: ocm-cluster-manager
|
||||
namespace: vela-system
|
||||
@@ -1,31 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Initializer
|
||||
metadata:
|
||||
name: terraform-alibaba
|
||||
namespace: vela-system
|
||||
spec:
|
||||
appTemplate:
|
||||
spec:
|
||||
components:
|
||||
- name: default
|
||||
type: raw
|
||||
properties:
|
||||
apiVersion: terraform.core.oam.dev/v1beta1
|
||||
kind: Provider
|
||||
metadata:
|
||||
namespace: default
|
||||
spec:
|
||||
provider: alibaba
|
||||
region: cn-hongkong
|
||||
credentials:
|
||||
source: Secret
|
||||
secretRef:
|
||||
namespace: vela-system
|
||||
name: alibaba-account-creds
|
||||
key: credentials
|
||||
dependsOn:
|
||||
- ref:
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Initializer
|
||||
name: terraform
|
||||
namespace: vela-system
|
||||
@@ -1,119 +0,0 @@
|
||||
# Rollout with OCM
|
||||
|
||||
In this tutorial, you will use rollout in runtime cluster with OCM.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Have a multi-cluster environment witch have installed OCM by following this [guide](../README.md). The name of managed cluster generally is `poc-01`.
|
||||
|
||||
- Install vela-rollout chart in managed-cluster with Helm.
|
||||
```shell
|
||||
$ helm repo add kubevela https://charts.kubevela.net/core
|
||||
```
|
||||
```shell
|
||||
$ helm install vela-rollout --create-namespace -n vela-system kubevela/vela-rollout
|
||||
```
|
||||
|
||||
## Install workflowStepDefinition
|
||||
|
||||
Apply workflowStepDefinitions in control-plane cluster.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f dispatchRevDef.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f dispatchTraits.yaml
|
||||
```
|
||||
|
||||
## Deploy and rollout
|
||||
|
||||
1. Apply application in control-plane cluster.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f app-first-scale.yaml
|
||||
```
|
||||
|
||||
Wait a few minutes, check rollout and workload status in managed cluster.
|
||||
```shell
|
||||
$ kubectl get rollout
|
||||
NAME TARGET UPGRADED READY BATCH-STATE ROLLING-STATE AGE
|
||||
nginx-server 2 2 2 batchReady rolloutSucceed 25h
|
||||
```
|
||||
```shell
|
||||
$ kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-server-v1 2/2 2 2 25h
|
||||
```
|
||||
|
||||
2. Update application to v2.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f app-update-v2.yaml
|
||||
```
|
||||
|
||||
check rollout and workload status.
|
||||
```shell
|
||||
$ kubectl get rollout
|
||||
NAME TARGET UPGRADED READY BATCH-STATE ROLLING-STATE AGE
|
||||
nginx-server 2 2 2 batchReady rolloutSucceed 25h
|
||||
```
|
||||
```shell
|
||||
$ kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-server-v2 2/2 2 2 25h
|
||||
```
|
||||
|
||||
3. Scale up.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f app-v2-scale.yaml
|
||||
```
|
||||
|
||||
check the status of rollout and workload.
|
||||
```shell
|
||||
$ kubectl get rollout
|
||||
NAME TARGET UPGRADED READY BATCH-STATE ROLLING-STATE AGE
|
||||
nginx-server 4 4 4 batchReady rolloutSucceed 25h
|
||||
```
|
||||
```shell
|
||||
$ kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-server-v2 4/4 4 4 25h
|
||||
```
|
||||
|
||||
4. Roll back to v1.
|
||||
```shell
|
||||
$ kubectl apply -f app-revert.yaml
|
||||
```
|
||||
|
||||
check rollout and workload status.
|
||||
```shell
|
||||
$ kubectl get rollout
|
||||
NAME TARGET UPGRADED READY BATCH-STATE ROLLING-STATE AGE
|
||||
nginx-server 4 4 4 batchReady rolloutSucceed 25h
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-server-v1 4/4 4 4 25h
|
||||
```
|
||||
|
||||
5. Scale down.
|
||||
```shell
|
||||
$ kubectl apply -f app-scale-down-v1.yaml
|
||||
```
|
||||
|
||||
check rollout and workload status.
|
||||
```shell
|
||||
$ kubectl get rollout
|
||||
NAME TARGET UPGRADED READY BATCH-STATE ROLLING-STATE AGE
|
||||
nginx-server 2 2 2 batchReady rolloutSucceed 25h
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-server-v1 2/2 2 2 25h
|
||||
```
|
||||
@@ -1,36 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: workflow-rollout-demo
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: nginx-server
|
||||
externalRevision: nginx-server-v1
|
||||
type: webservice
|
||||
properties:
|
||||
image: nginx:1.20.0
|
||||
port: 80
|
||||
traits:
|
||||
- type: rollout
|
||||
properties:
|
||||
targetRevision: nginx-server-v1
|
||||
targetSize: 2
|
||||
# Rollout the two replicas in two batches
|
||||
rolloutBatches:
|
||||
- replicas: 1
|
||||
- replicas: 1
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: dispatch-comp-rev-v1
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v1
|
||||
cluster: poc-01
|
||||
|
||||
- name: dispatchRollout
|
||||
type: dispatch-traits
|
||||
properties:
|
||||
component: nginx-server
|
||||
cluster: poc-01
|
||||
@@ -1,41 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: workflow-rollout-demo
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: nginx-server
|
||||
externalRevision: nginx-server-v2
|
||||
type: webservice
|
||||
properties:
|
||||
image: nginx:1.21
|
||||
port: 80
|
||||
traits:
|
||||
- type: rollout
|
||||
properties:
|
||||
targetRevision: nginx-server-v1
|
||||
targetSize: 4
|
||||
rolloutBatches:
|
||||
- replicas: 2
|
||||
- replicas: 2
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: dispatch-comp-rev-v1
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v1
|
||||
cluster: poc-01
|
||||
|
||||
- name: dispatch-comp-rev-v2
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v2
|
||||
cluster: poc-01
|
||||
|
||||
- name: dispatchRollout
|
||||
type: dispatch-traits
|
||||
properties:
|
||||
component: nginx-server
|
||||
cluster: poc-01
|
||||
@@ -1,41 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: workflow-rollout-demo
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: nginx-server
|
||||
externalRevision: nginx-server-v2
|
||||
type: webservice
|
||||
properties:
|
||||
image: nginx:1.21
|
||||
port: 80
|
||||
traits:
|
||||
- type: rollout
|
||||
properties:
|
||||
targetRevision: nginx-server-v1
|
||||
targetSize: 2
|
||||
rolloutBatches:
|
||||
- replicas: 1
|
||||
- replicas: 1
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: dispatch-comp-rev-v1
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v1
|
||||
cluster: cluster2
|
||||
|
||||
- name: dispatch-comp-rev-v2
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v2
|
||||
cluster: cluster2
|
||||
|
||||
- name: dispatchRollout
|
||||
type: dispatch-traits
|
||||
properties:
|
||||
component: nginx-server
|
||||
cluster: cluster2
|
||||
@@ -1,43 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: workflow-rollout-demo
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: nginx-server
|
||||
externalRevision: nginx-server-v2
|
||||
type: webservice
|
||||
properties:
|
||||
image: nginx:1.21
|
||||
port: 80
|
||||
traits:
|
||||
- type: rollout
|
||||
properties:
|
||||
targetRevision: nginx-server-v2
|
||||
targetSize: 2
|
||||
# Upgrade the replicas in two batches. Each batch will upgrade only one.
|
||||
rolloutBatches:
|
||||
- replicas: 1
|
||||
- replicas: 1
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
# If we delete this, the ManifestWork will also be removed in managed cluster, which would prohibits us to do rollback later.
|
||||
- name: dispatch-comp-rev-v1
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v1
|
||||
cluster: poc-01
|
||||
|
||||
- name: dispatch-comp-rev-v2
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v2
|
||||
cluster: poc-01
|
||||
|
||||
- name: dispatchRollout
|
||||
type: dispatch-traits
|
||||
properties:
|
||||
component: nginx-server
|
||||
cluster: poc-01
|
||||
@@ -1,42 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: workflow-rollout-demo
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: nginx-server
|
||||
externalRevision: nginx-server-v2
|
||||
type: webservice
|
||||
properties:
|
||||
image: nginx:1.21
|
||||
port: 80
|
||||
traits:
|
||||
- type: rollout
|
||||
properties:
|
||||
targetRevision: nginx-server-v2
|
||||
targetSize: 4
|
||||
# This means to rollout two more replicas in two batches.
|
||||
rolloutBatches:
|
||||
- replicas: 1
|
||||
- replicas: 1
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: dispatch-comp-rev-v1
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v1
|
||||
cluster: poc-01
|
||||
|
||||
- name: dispatch-comp-rev-v2
|
||||
type: dispatch-comp-rev
|
||||
properties:
|
||||
compRev: nginx-server-v2
|
||||
cluster: poc-01
|
||||
|
||||
- name: dispatchRollout
|
||||
type: dispatch-traits
|
||||
properties:
|
||||
component: nginx-server
|
||||
cluster: poc-01
|
||||
@@ -1,60 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
name: dispatch-comp-rev
|
||||
namespace: vela-system
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import ("vela/op")
|
||||
|
||||
componentRev: op.#Read & {
|
||||
value: {
|
||||
kind: "ControllerRevision"
|
||||
apiVersion: "apps/v1"
|
||||
metadata: {
|
||||
name: parameter.compRev
|
||||
namespace: context.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "work.open-cluster-management.io/v1"
|
||||
kind: "ManifestWork"
|
||||
metadata: {
|
||||
namespace: parameter.cluster
|
||||
name: "comprevision-" + parameter.compRev
|
||||
}
|
||||
spec: {
|
||||
workload: {
|
||||
manifests: [{
|
||||
kind: "ControllerRevision"
|
||||
apiVersion: "apps/v1"
|
||||
metadata: {
|
||||
name: parameter.compRev
|
||||
namespace: context.namespace
|
||||
}
|
||||
data: {
|
||||
apiVersion: "core.oam.dev/v1alpha2"
|
||||
kind: "Component"
|
||||
metadata:
|
||||
name: context.name
|
||||
namespace: context.namespace
|
||||
spec:
|
||||
workload: {
|
||||
componentRev.value.data.spec.workload
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parameter: {
|
||||
compRev: string
|
||||
cluster: string
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
name: dispatch-traits
|
||||
namespace: vela-system
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import ("vela/op")
|
||||
|
||||
comp: op.#Load & {
|
||||
component: parameter.component
|
||||
}
|
||||
|
||||
apply: op.#Apply & {
|
||||
value: {
|
||||
apiVersion: "work.open-cluster-management.io/v1"
|
||||
kind: "ManifestWork"
|
||||
metadata: {
|
||||
namespace: parameter.cluster
|
||||
name: parameter.component + "-traits"
|
||||
}
|
||||
spec: {
|
||||
workload: manifests : comp.value.auxiliaries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parameter: {
|
||||
component: string
|
||||
cluster: string
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: alibaba-oss
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
# Quick start
|
||||
|
||||
This example show case how one can use a flagger trait to rollout a component with
|
||||
|
||||
## Install OAM flagger
|
||||
```shell script
|
||||
make
|
||||
helm install -n flagger rollout charts/flagger/
|
||||
```
|
||||
|
||||
## Install Vela core
|
||||
```shell script
|
||||
make
|
||||
bin/vela install
|
||||
```
|
||||
|
||||
## Run ApplicationConfiguration V1
|
||||
```shell script
|
||||
kubectl apply -f e2e/raw-objects/samples/rollout-demo/definitions.yaml
|
||||
traitdefinition.core.oam.dev/canaries.flagger.app created
|
||||
traitdefinition.core.oam.dev/ingresses.extensions created
|
||||
workloaddefinition.core.oam.dev/deployments.apps created
|
||||
|
||||
kubectl apply -f e2e/raw-objects/samples/rollout-demo/deploy-component-v1.yaml
|
||||
component.core.oam.dev/rollout-demo-app created
|
||||
|
||||
kubectl apply -f e2e/raw-objects/samples/rollout-demo/appConfig-rollout-v1.yaml
|
||||
applicationconfiguration.core.oam.dev/sample-application-rollout created
|
||||
```
|
||||
|
||||
## Verify that revision workload is created
|
||||
```shell script
|
||||
kubectl get controllerrevision
|
||||
NAME CONTROLLER REVISION AGE
|
||||
rollout-demo-app-v1 component.core.oam.dev/rollout-demo-app 1 64s
|
||||
|
||||
kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
rollout-demo-app-v1 1/1 1 1 80s
|
||||
```
|
||||
|
||||
## Upgrade the component to v2 and change the revision name of the component in the appConfig
|
||||
```shell script
|
||||
kubectl apply -f e2e/raw-objects/samples/rollout-demo/deploy-component-v2.yaml
|
||||
component.core.oam.dev/rollout-demo-app configured
|
||||
|
||||
kubectl apply -f e2e/raw-objects/samples/rollout-demo/appConfig-rollout-v2.yaml
|
||||
applicationconfiguration.core.oam.dev/sample-application-rollout created
|
||||
```
|
||||
|
||||
## Verify that new revision workload is created and the workloads
|
||||
```shell script
|
||||
kubectl get controllerrevision
|
||||
NAME CONTROLLER REVISION AGE
|
||||
rollout-demo-app-v1 component.core.oam.dev/rollout-demo-app 1 90s
|
||||
rollout-demo-app-v2 component.core.oam.dev/rollout-demo-app 2 5s
|
||||
```
|
||||
|
||||
## Verify that we have created services that select all pods in all the revisions
|
||||
```shell script
|
||||
kubectl get svc
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
rollout-demo-app ClusterIP 10.103.185.101 <none> 80/TCP 2m52s
|
||||
rollout-demo-app-canary ClusterIP 10.99.87.149 <none> 80/TCP 2m22s
|
||||
rollout-demo-app-primary ClusterIP 10.102.31.57 <none> 80/TCP 2m22s
|
||||
|
||||
kubectl describe svc rollout-demo-app
|
||||
Name: rollout-demo-app
|
||||
Namespace: default
|
||||
Labels: app=rollout-demo-app
|
||||
Annotations: <none>
|
||||
Selector: app=rollout-demo-app
|
||||
Type: ClusterIP
|
||||
IP: 10.103.185.101
|
||||
Port: http 80/TCP
|
||||
TargetPort: 8080/TCP
|
||||
Endpoints: 172.17.0.13:8080,172.17.0.14:8080,172.17.0.15:8080 + 4 more...
|
||||
Session Affinity: None
|
||||
Events: <none>
|
||||
```
|
||||
|
||||
## Verify the version of the canary and primary deployment are what is intended
|
||||
```shell script
|
||||
kubectl get deploy rollout-demo-app-v1 -o=jsonpath="{.spec.template.spec.containers[0].image}"
|
||||
stefanprodan/podinfo:4.0.6
|
||||
|
||||
kubectl get deploy rollout-demo-app-v2 -o=jsonpath="{.spec.template.spec.containers[0].image}"
|
||||
stefanprodan/podinfo:5.0.2
|
||||
```
|
||||
|
||||
## Observe the flagger canary
|
||||
```shell script
|
||||
kubectl get canary --watch
|
||||
NAME STATUS WEIGHT LASTTRANSITIONTIME
|
||||
rollout-demo-app Initializing 0 2020-10-24T10:59:56Z
|
||||
rollout-demo-app Initializing 0 2020-10-24T10:59:56Z
|
||||
rollout-demo-app Initialized 0 2020-10-24T11:00:54Z
|
||||
rollout-demo-app Progressing 0 2020-10-24T11:01:24Z
|
||||
rollout-demo-app Progressing 10 2020-10-24T11:01:54Z
|
||||
rollout-demo-app Progressing 20 2020-10-24T11:02:24Z
|
||||
rollout-demo-app Progressing 30 2020-10-24T11:02:54Z
|
||||
rollout-demo-app Progressing 40 2020-10-24T11:03:24Z
|
||||
rollout-demo-app Progressing 50 2020-10-24T11:03:54Z
|
||||
rollout-demo-app Promoting 0 2020-10-24T11:04:24Z
|
||||
rollout-demo-app Promoting 100 2020-10-24T11:04:54Z
|
||||
rollout-demo-app Finalising 0 2020-10-24T11:05:24Z
|
||||
```
|
||||
|
||||
## Observe that the rollout through the canary object, you shall see something like this
|
||||
```shell script
|
||||
kubectl describe canary
|
||||
...
|
||||
...
|
||||
Events:
|
||||
Type Reason Age From Message
|
||||
---- ------ ---- ---- -------
|
||||
Warning Synced 5m30s flagger waiting for rollout to finish: observed deployment generation less then desired generation
|
||||
Normal Synced 5m (x2 over 5m30s) flagger all the metrics providers are available!
|
||||
Normal Synced 5m flagger Initialization done! rollout-demo-app.default
|
||||
Normal Synced 4m30s flagger New revision detected! Scaling up rollout-demo-app-v2.default
|
||||
Normal Synced 4m flagger Starting canary analysis for rollout-demo-app-v2.default
|
||||
Normal Synced 4m flagger Advance rollout-demo-app.default canary weight 10
|
||||
Normal Synced 3m30s flagger Advance rollout-demo-app.default canary weight 20
|
||||
Normal Synced 3m flagger Advance rollout-demo-app.default canary weight 30
|
||||
Normal Synced 2m30s flagger Advance rollout-demo-app.default canary weight 40
|
||||
Normal Synced 2m flagger Advance rollout-demo-app.default canary weight 50
|
||||
Normal Synced 30s flagger Promote rollout-demo-app.default
|
||||
Normal Synced 30s flagger Promoting the traffic to the new targe in one shot
|
||||
Normal Synced 0s (x3 over 60s) flagger (combined from similar events): Promotion completed!
|
||||
|
||||
```
|
||||
|
||||
## Verify that the instances of the v2 workload is the same as the canary maxReplica
|
||||
```shell script
|
||||
kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
rollout-demo-app-v1 0/0 0 0 15m
|
||||
rollout-demo-app-v2 7/7 7 7 15m
|
||||
```
|
||||
|
||||
## Roll back to V1
|
||||
```shell script
|
||||
kubectl apply -f e2e/raw-objects/samples/rollout-demo/appConfig-rollback-v1.yaml
|
||||
applicationconfiguration.core.oam.dev/sample-application-rollout configured
|
||||
```
|
||||
|
||||
## Observe the flagger canary rollback
|
||||
```shell script
|
||||
kubectl get canary --watch
|
||||
NAME STATUS WEIGHT LASTTRANSITIONTIME
|
||||
rollback-demo-app Initialized 0 2020-10-24T11:17:04Z
|
||||
rollback-demo-app Progressing 0 2020-10-24T11:17:34Z
|
||||
rollback-demo-app Progressing 10 2020-10-24T11:18:04Z
|
||||
rollback-demo-app Progressing 20 2020-10-24T11:18:34Z
|
||||
rollback-demo-app Progressing 30 2020-10-24T11:19:04Z
|
||||
rollback-demo-app Progressing 40 2020-10-24T11:19:34Z
|
||||
rollback-demo-app Progressing 50 2020-10-24T11:20:04Z
|
||||
rollback-demo-app Promoting 0 2020-10-24T11:20:34Z
|
||||
rollback-demo-app Promoting 100 2020-10-24T11:21:04Z
|
||||
rollback-demo-app Finalising 0 2020-10-24T11:21:34Z
|
||||
rollback-demo-app Succeeded 0 2020-10-24T11:22:04Z
|
||||
```
|
||||
|
||||
## Verify that the instances of the v1 workload is the same as the canary maxReplica
|
||||
```shell script
|
||||
kubectl get deploy
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
rollout-demo-app-v1 7/7 7 7 24m
|
||||
rollout-demo-app-v2 0/0 0 0 24m
|
||||
```
|
||||
|
||||
## Clean up
|
||||
```shell script
|
||||
kubectl delete -f e2e/raw-objects/samples/rollout-demo/
|
||||
```
|
||||
|
||||
## Improvements
|
||||
1. The current component garbage collector uses a very unreliable way to figour out if a workload is a revisioned one that needs to keep or GCed. (basically to see if its name starts with componentName-)
|
||||
2. The workload name will not be component-v when the user actually put a name in the component. This will lead to problems in the above case
|
||||
3. Modify the primary/canary service so that they point to the primary/canary resources individually
|
||||
@@ -1,72 +0,0 @@
|
||||
# Rollout Trait Design
|
||||
|
||||
## Flagger rollout flow
|
||||
Here is the 10,000 ft overview of the flagger rollout flow
|
||||
|
||||
The overall controller Run function starts the processNextItem every second in the background. The processNextItme basically calls SyncHandler on each item in the queue.
|
||||
It calls the scheduleCanary() function in a for loop.
|
||||
|
||||
SyncHandler
|
||||
1. Set the canary status as **Initializing** if canary is not deleted
|
||||
2. Finalize (revert) the canary process if the canary has "revertOnDelete" flag. This means reverting the canary process when the canary object is deleted. OAM should NEVER set this to true.
|
||||
3. Each canary will be mapped to a job which runs the "AdvanceCanary" logic below forever until stopped
|
||||
|
||||
AdvanceCanary
|
||||
1. Create Canary controller/Service router/Mesh router/ through a factory
|
||||
2. CanaryController initialize the primary resource by copying from the target
|
||||
3. ServiceRouter initialize creates the serivce for the canary/primary resources
|
||||
4. Check if the canary has changed if the primary is initialized successfully. Just return if not.
|
||||
5. Check if the rollout webhook confirms to start
|
||||
6. Check if the Primary is ready, return if not
|
||||
7. MeshRouter starts to calculate the traffic weight between primary/canary
|
||||
8. Set the canary status as **Initialized** if it's initializing and return. Otherwise, set it to **Progressing** if it determined to advance
|
||||
9. Check if the canary revision (spec) changes or dependency changes during rollout, if so, reset to **Progressing**
|
||||
10. Check if no need to do analysis, go straight to finish the rollout if not. The default is to route 100% to primary which is not what we want. OAM should NEVER set this to true.
|
||||
11. Check with rollback webhooks, rollback if something is wrong
|
||||
12. Check if the status is promoting, call controller promote which just copy canary spec to primary. This will set the status to **Finalizing** if there is no error.
|
||||
13. Check if the status is finalizing. Finalize delete the canary and set the canary status as **Succeeded**
|
||||
14. Roll back if the number of failed cases cross certain threshold.
|
||||
15. Pick a strategy based on the spec.Analysis (A/B testing, Blue/Green or Canary). The canary status is set as **Promoting** at the end of those phase.
|
||||
|
||||
|
||||
## Problems with the flagger design in OAM
|
||||
The problem with the current flagger design is that it wants to be strictly GitOps compatible. Thus, it
|
||||
cannot touch the image related fields in the "target" object. That's why it has to create a "primary" deployment
|
||||
and treat the "target" as the "canary" while doing the rollout. It finally "promotes" the primary
|
||||
by copying everything from the "canary" to the "primary" after it 's done.
|
||||
|
||||
We don't need to stick to that scheme, but we face a similar problem as our component/workload controller
|
||||
will constantly reconcile the target component too.
|
||||
1. One way is to pin the component to a specific revision in the application configuration. The user then can modify
|
||||
the component and that can be automatically picked up by the rollout trait. The draw-back of this approach is that
|
||||
the upgrade will end up with the workload with the latest version not the workload in the applcation configuration.
|
||||
2. Another way is to not allow the component to specify the "replicas" by the user. In this way, a user can modify
|
||||
the container related fields which leads to a new workload of size 0 created. The rollout trait
|
||||
can pick up the "last" revision of the component and its corresponding workload as the source. The nice part of this
|
||||
approach is the new component will be the canary, thus keeping it under the application controller's control
|
||||
and ready to be upgraded again.
|
||||
|
||||
We decide to take the second approach as it matches with the flow better.
|
||||
|
||||
## Proposed OAM Design
|
||||
- Add a new "meshProvider" type "OAM", the scheduler will automatically set the meshProvider as the "routeTrait" implementation
|
||||
which is SMI for now.
|
||||
- OAM can fill the workloadRef to the `targetRef` automatically. This will point the trait to the workload
|
||||
which has its "componentRevisionName" in its label.
|
||||
- Write an OAM flagger resource controller that works with the podSpecWorkload/containerizedWorkload/Deployment
|
||||
- Find the last live component revision as the canary if the user didn't explicitly spell out the revisionName
|
||||
- We need to use the workload itself as the canary, and the "source" as the primary
|
||||
- The Initialize function will be no-op
|
||||
- The controller will adjust the replica size between the canary and the primary if there is HPA associated with the workload
|
||||
- The Promote function will simply reduce the primary (source) replicas zero and bump the canary (target)
|
||||
- It seems that we don't need an OAM specific router (even if the service/routing name is a bit mis-matched)
|
||||
- Remove all the hard coded string literal "primary" from the scheduler.go file
|
||||
|
||||
## What is not covered
|
||||
- This design does not cover the case that HPA is involved. This requires some changes at the OAM
|
||||
runtime to keep the HPA trait on the old workload.
|
||||
- We need a way to translate the status of the flagger trait status back to the rollout output if we
|
||||
don't plan to introduce a rollout CRD.
|
||||
- The rollout experience needs to be combined with the metris/route/autoscaler traits together to have
|
||||
a merely complete CD experience. The very basic case is for the canary to emit Prometheus metrics. The rollout
|
||||
trait needs to setup metrics checkers and threatholds to move to the next stages.
|
||||
@@ -1,40 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ApplicationConfiguration
|
||||
metadata:
|
||||
name: sample-application-rollout
|
||||
spec:
|
||||
components:
|
||||
- revisionName: rollout-demo-app-v1
|
||||
traits:
|
||||
- trait:
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: rollback-demo-app
|
||||
spec:
|
||||
sourceRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: rollout-demo-app-v2
|
||||
namespace: default
|
||||
provider: smi
|
||||
progressDeadlineSeconds: 60
|
||||
service:
|
||||
name: rollout-demo-app
|
||||
# ClusterIP port number
|
||||
port: 80
|
||||
# container port number or name
|
||||
targetPort: 8080
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 15s
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 10
|
||||
# max traffic percentage routed to canary
|
||||
# percentage (0-100)
|
||||
maxWeight: 50
|
||||
# canary increment step
|
||||
# percentage (0-100)
|
||||
stepWeight: 10
|
||||
# max replicas scale up to canary
|
||||
maxReplicas: 7
|
||||
@@ -1,34 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ApplicationConfiguration
|
||||
metadata:
|
||||
name: sample-application-rollout
|
||||
spec:
|
||||
components:
|
||||
- revisionName: rollout-demo-app-v1
|
||||
traits:
|
||||
- trait:
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: rollout-demo-app
|
||||
spec:
|
||||
provider: smi
|
||||
progressDeadlineSeconds: 60
|
||||
service:
|
||||
# ClusterIP port number
|
||||
port: 80
|
||||
# container port number or name
|
||||
targetPort: 8080
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 0s
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 10
|
||||
# max traffic percentage routed to canary
|
||||
# percentage (0-100)
|
||||
maxWeight: 50
|
||||
# canary increment step
|
||||
# percentage (0-100)
|
||||
stepWeight: 10
|
||||
# max replicas scale up to canary
|
||||
maxReplicas: 7
|
||||
@@ -1,35 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ApplicationConfiguration
|
||||
metadata:
|
||||
name: sample-application-rollout
|
||||
spec:
|
||||
components:
|
||||
- revisionName: rollout-demo-app-v2
|
||||
traits:
|
||||
- trait:
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: rollout-demo-app
|
||||
spec:
|
||||
provider: smi
|
||||
progressDeadlineSeconds: 60
|
||||
service:
|
||||
name: rollout-demo-app
|
||||
# ClusterIP port number
|
||||
port: 80
|
||||
# container port number or name
|
||||
targetPort: 8080
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 15s
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 10
|
||||
# max traffic percentage routed to canary
|
||||
# percentage (0-100)
|
||||
maxWeight: 50
|
||||
# canary increment step
|
||||
# percentage (0-100)
|
||||
stepWeight: 10
|
||||
# max replicas scale up to canary
|
||||
maxReplicas: 7
|
||||
@@ -1,20 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
name: canaries.flagger.app
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- podspecworkload.standard.oam.dev
|
||||
- deployments.apps
|
||||
definitionRef:
|
||||
name: canaries.flagger.app
|
||||
workloadRefPath: spec.targetRef
|
||||
revisionEnabled: true
|
||||
---
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
metadata:
|
||||
name: deployments.apps
|
||||
spec:
|
||||
definitionRef:
|
||||
name: deployments.apps
|
||||
@@ -1,26 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Component
|
||||
metadata:
|
||||
name: rollout-demo-app
|
||||
spec:
|
||||
workload:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: rollout-demo-app
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: rollout-demo-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: rollout-demo-app
|
||||
spec:
|
||||
containers:
|
||||
- image: stefanprodan/podinfo:4.0.6
|
||||
name: metrics-provider
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
@@ -1,26 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Component
|
||||
metadata:
|
||||
name: rollout-demo-app
|
||||
spec:
|
||||
workload:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: rollout-demo-app
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: rollout-demo-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: rollout-demo-app
|
||||
spec:
|
||||
containers:
|
||||
- image: stefanprodan/podinfo:5.0.2
|
||||
name: metrics-provider
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
@@ -1,19 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Component
|
||||
metadata:
|
||||
name: rollout-demo-app
|
||||
spec:
|
||||
workload:
|
||||
apiVersion: standard.oam.dev/v1alpha1
|
||||
kind: PodSpecWorkload
|
||||
metadata:
|
||||
labels:
|
||||
app: rollout-demo-app
|
||||
spec:
|
||||
podSpec:
|
||||
containers:
|
||||
- image: stefanprodan/podinfo:4.0.6
|
||||
name: metrics-provider
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
@@ -1,19 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Component
|
||||
metadata:
|
||||
name: rollout-demo-app
|
||||
spec:
|
||||
workload:
|
||||
apiVersion: standard.oam.dev/v1alpha1
|
||||
kind: PodSpecWorkload
|
||||
metadata:
|
||||
labels:
|
||||
app: rollout-demo-app
|
||||
spec:
|
||||
podSpec:
|
||||
containers:
|
||||
- image: stefanprodan/podinfo:5.0.2
|
||||
name: metrics-provider
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
17
go.mod
17
go.mod
@@ -8,9 +8,6 @@ require (
|
||||
github.com/FogDong/uitable v0.0.5
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8
|
||||
github.com/alibabacloud-go/cs-20151215/v3 v3.0.35
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4
|
||||
github.com/alibabacloud-go/tea v1.1.20
|
||||
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
|
||||
github.com/bluele/gcache v0.0.2
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869
|
||||
@@ -23,10 +20,9 @@ require (
|
||||
github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d
|
||||
github.com/dave/jennifer v1.6.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/deckarep/golang-set v1.8.0
|
||||
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
|
||||
github.com/ettle/strcase v0.1.1
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
|
||||
github.com/fatih/camelcase v1.0.0 // indirect
|
||||
@@ -134,15 +130,7 @@ require (
|
||||
github.com/acomagu/bufpipe v1.0.4 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/alessio/shellescape v1.4.1 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
|
||||
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
|
||||
github.com/alibabacloud-go/tea-utils v1.4.5 // indirect
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.1 // indirect
|
||||
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
|
||||
github.com/aliyun/credentials-go v1.1.2 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
|
||||
@@ -152,7 +140,6 @@ require (
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.5.5 // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/cockroachdb/apd/v2 v2.0.2 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||
@@ -262,12 +249,10 @@ require (
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/skeema/knownhosts v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tjfoc/gmsm v1.3.2 // indirect
|
||||
github.com/vbatts/tar-split v0.11.3 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
|
||||
75
go.sum
75
go.sum
@@ -1,18 +1,15 @@
|
||||
cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
|
||||
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o=
|
||||
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
|
||||
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.3.0/go.mod h1:9IAwXhoyBJ7z9LcAwkj0/7NnPzYaPeZxxVp3zm+5IqA=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs=
|
||||
cuelang.org/go v0.5.0 h1:D6N0UgTGJCOxFKU8RU+qYvavKNsVc/+ZobmifStVJzU=
|
||||
@@ -129,41 +126,9 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
|
||||
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
|
||||
github.com/alibabacloud-go/cs-20151215/v3 v3.0.35 h1:yArmXiJD8m8WPu8ZKBroLNAn+5REA6c9BngwZIh4A4Q=
|
||||
github.com/alibabacloud-go/cs-20151215/v3 v3.0.35/go.mod h1:NxWlrjZkPlfsrPPfsHmHBKwF82MDEfc/0qNA4ooIMQ8=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.2/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4 h1:7Q2FEyqxeZeIkwYMwRC3uphxV4i7O2eV4ETe21d6lS4=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
|
||||
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 h1:NqugFkGxx1TXSh/pBcU00Y6bljgDPaFdh5MUSeJ7e50=
|
||||
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.1 h1:ZkBv2/jnghxtU0p+upSU0GGzW1VL9GQdZO3mcSUTUy8=
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.1/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
|
||||
github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
|
||||
github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg=
|
||||
github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea v1.1.20 h1:wFK4xEbvGYMtzTyHhIju9D7ecWxvSUdoLO6y4vDLFik=
|
||||
github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
|
||||
github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA=
|
||||
github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.0/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.1 h1:K6kwgo+UiYx+/kr6CO0PN5ACZDzE3nnn9d77215AkTs=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.1/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
|
||||
github.com/alibabacloud-go/tea-xml v1.1.2 h1:oLxa7JUXm2EDFzMg+7oRsYc+kutgCVwm+bZlhhmvW5M=
|
||||
github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/aliyun/credentials-go v1.1.2 h1:qU1vwGIBb3UJ8BwunHDRFtAhS6jnQLnde/yk0+Ih2GY=
|
||||
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
@@ -263,8 +228,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
|
||||
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||
@@ -273,7 +236,6 @@ github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUK
|
||||
github.com/cloudtty/cloudtty v0.5.2 h1:3sp9CU4aN7nhBNCKCsae277Sw06uKx+o2dnln3mVXvo=
|
||||
github.com/cloudtty/cloudtty v0.5.2/go.mod h1:gyxZNmuHhu+53n0mQV6n8TfMw4uwJHIA/7hZ2kKv1/4=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
@@ -336,8 +298,6 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
|
||||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
@@ -393,7 +353,6 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
@@ -760,7 +719,6 @@ github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1a
|
||||
github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
@@ -769,7 +727,6 @@ github.com/gophercloud/gophercloud v0.10.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU8
|
||||
github.com/gophercloud/gophercloud v0.11.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
@@ -1264,7 +1221,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@@ -1408,7 +1364,6 @@ github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ys
|
||||
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
@@ -1420,8 +1375,6 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
|
||||
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
@@ -1483,8 +1436,6 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
|
||||
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||
@@ -1527,7 +1478,6 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
@@ -1581,7 +1531,6 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
|
||||
@@ -1689,19 +1638,15 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
@@ -1740,7 +1685,6 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@@ -1785,7 +1729,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
@@ -1824,8 +1767,6 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
@@ -1875,9 +1816,7 @@ golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1910,7 +1849,6 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1919,11 +1857,9 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1983,7 +1919,6 @@ golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
@@ -2025,7 +1960,6 @@ golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
@@ -2055,11 +1989,9 @@ golang.org/x/tools v0.0.0-20200313205530-4303120df7d8/go.mod h1:Sl4aGygMT6LrqrWc
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200422205258-72e4a01eba43/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200603131246-cc40288be839/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
@@ -2096,7 +2028,6 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
|
||||
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
@@ -2105,7 +2036,6 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
@@ -2132,8 +2062,6 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY
|
||||
google.golang.org/genproto v0.0.0-20200603110839-e855014d5736/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
@@ -2168,8 +2096,6 @@ google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
@@ -2227,7 +2153,6 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
|
||||
@@ -17,15 +17,4 @@ done
|
||||
|
||||
rm ${TEMPLATE_DIR}/*.bak
|
||||
|
||||
TEMPLATE_DIR="../../legacy/charts/vela-core-legacy/crds"
|
||||
|
||||
for filename in `ls "$TEMPLATE_DIR"`; do
|
||||
|
||||
sed -i.bak '/creationTimestamp: null/d' "${TEMPLATE_DIR}/$filename"
|
||||
|
||||
done
|
||||
|
||||
rm ${TEMPLATE_DIR}/*.bak
|
||||
|
||||
|
||||
popd
|
||||
|
||||
@@ -26,12 +26,7 @@ import (
|
||||
|
||||
var (
|
||||
oldCRD = map[string]bool{
|
||||
"components": true,
|
||||
"applicationconfigurations": true,
|
||||
"scopedefinitions": true,
|
||||
"rollouts": true,
|
||||
"healthscopes": true,
|
||||
"workloaddefinitions": true,
|
||||
"workloaddefinitions": true,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# Legacy Support
|
||||
|
||||
Now lots of apps are still running on Kubernetes clusters version v1.14 or v1.15, while KubeVela core requires the minimum
|
||||
Kubernetes version to be v1.16+.
|
||||
|
||||
Currently, the main blocker is KubeVela uses CRD v1, while those old Kubernetes versions don't support CRD v1.
|
||||
So we generate v1beta1 CRD here for convenience. But we have no guarantee that KubeVela core will support the
|
||||
legacy Kubernetes versions.
|
||||
|
||||
Follow the instructions in [README](../README.md) to create a namespace like `vela-system` and add the OAM Kubernetes
|
||||
Runtime helm repo.
|
||||
|
||||
```
|
||||
$ kubectl create namespace vela-system
|
||||
$ helm repo add kubevela https://charts.kubevela.net/core
|
||||
```
|
||||
|
||||
Run the following command to install a KubeVela core legacy chart.
|
||||
|
||||
```
|
||||
$ helm install -n vela-system vela-core-legacy kubevela/vela-core-legacy
|
||||
```
|
||||
|
||||
If you'd like to install an older version of the legacy chart, use `helm search` to choose a proper chart version. Remember
|
||||
to add flag `--devel` if you prefer pre-release versions.
|
||||
```
|
||||
$ helm search repo vela-core-legacy -l
|
||||
NAME CHART VERSION APP VERSION DESCRIPTION
|
||||
kubevela/vela-core-legacy 0.2 0.2 A Helm chart for legacy KubeVela core Controlle...
|
||||
kubevela/vela-core-legacy 0.0.1 0.1 A Helm chart for legacy KubeVela core Controlle...
|
||||
|
||||
$ helm install -n vela-system kubevela-legacy kubevela/vela-core-legacy --version 0.0.1
|
||||
```
|
||||
|
||||
Install the legacy chart as below if you want a nightly version.
|
||||
|
||||
```
|
||||
$ helm install -n vela-system vela-core-legacy kubevela/vela-core-legacy --set image.tag=master
|
||||
```
|
||||
@@ -1,21 +0,0 @@
|
||||
apiVersion: v1
|
||||
name: vela-core-legacy
|
||||
description: A Helm chart for legacy KubeVela Core Controller, targeted on Kubernetes v1.14 and v1.15
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
version: 0.1.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application.
|
||||
appVersion: 0.1.0
|
||||
@@ -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: []
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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: []
|
||||
@@ -1,674 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: componentdefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: ComponentDefinition
|
||||
listKind: ComponentDefinitionList
|
||||
plural: componentdefinitions
|
||||
shortNames:
|
||||
- comp
|
||||
singular: componentdefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.workload.definition.kind
|
||||
name: WORKLOAD-KIND
|
||||
type: string
|
||||
- jsonPath: .metadata.annotations.definition\.oam\.dev/description
|
||||
name: DESCRIPTION
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ComponentDefinition is the Schema for the componentdefinitions
|
||||
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: ComponentDefinitionSpec defines the desired state of ComponentDefinition
|
||||
properties:
|
||||
childResourceKinds:
|
||||
description: ChildResourceKinds are the list of GVK of the child resources
|
||||
this workload generates
|
||||
items:
|
||||
description: A ChildResourceKind defines a child Kubernetes resource
|
||||
kind with a selector
|
||||
properties:
|
||||
apiVersion:
|
||||
description: APIVersion of the child resource
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the child resource
|
||||
type: string
|
||||
selector:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Selector to select the child resources that the
|
||||
workload wants to expose to traits
|
||||
type: object
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type: array
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
podSpecPath:
|
||||
description: PodSpecPath indicates where/if this workload has K8s
|
||||
podSpec field if one workload has podSpec, trait can do lot's of
|
||||
assumption such as port, env, volume fields.
|
||||
type: string
|
||||
revisionLabel:
|
||||
description: RevisionLabel indicates which label for underlying resources(e.g.
|
||||
pods) of this workload can be used by trait to create resource selectors(e.g.
|
||||
label selector for pods).
|
||||
type: string
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workload
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for workload
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
workload:
|
||||
description: Workload is a workload type descriptor
|
||||
properties:
|
||||
definition:
|
||||
description: Definition mutually exclusive to workload.type, a
|
||||
embedded WorkloadDefinition
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type:
|
||||
description: Type ref to a WorkloadDefinition via name
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- workload
|
||||
type: object
|
||||
status:
|
||||
description: ComponentDefinitionStatus is the status of ComponentDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.workload.definition.kind
|
||||
name: WORKLOAD-KIND
|
||||
type: string
|
||||
- jsonPath: .metadata.annotations.definition\.oam\.dev/description
|
||||
name: DESCRIPTION
|
||||
type: string
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ComponentDefinition is the Schema for the componentdefinitions
|
||||
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: ComponentDefinitionSpec defines the desired state of ComponentDefinition
|
||||
properties:
|
||||
childResourceKinds:
|
||||
description: ChildResourceKinds are the list of GVK of the child resources
|
||||
this workload generates
|
||||
items:
|
||||
description: A ChildResourceKind defines a child Kubernetes resource
|
||||
kind with a selector
|
||||
properties:
|
||||
apiVersion:
|
||||
description: APIVersion of the child resource
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the child resource
|
||||
type: string
|
||||
selector:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Selector to select the child resources that the
|
||||
workload wants to expose to traits
|
||||
type: object
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type: array
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
podSpecPath:
|
||||
description: PodSpecPath indicates where/if this workload has K8s
|
||||
podSpec field if one workload has podSpec, trait can do lot's of
|
||||
assumption such as port, env, volume fields.
|
||||
type: string
|
||||
revisionLabel:
|
||||
description: RevisionLabel indicates which label for underlying resources(e.g.
|
||||
pods) of this workload can be used by trait to create resource selectors(e.g.
|
||||
label selector for pods).
|
||||
type: string
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workload
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for workload
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
workload:
|
||||
description: Workload is a workload type descriptor
|
||||
properties:
|
||||
definition:
|
||||
description: Definition mutually exclusive to workload.type, a
|
||||
embedded WorkloadDefinition
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type:
|
||||
description: Type ref to a WorkloadDefinition via name
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- workload
|
||||
type: object
|
||||
status:
|
||||
description: ComponentDefinitionStatus is the status of ComponentDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -1,171 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: components.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: Component
|
||||
listKind: ComponentList
|
||||
plural: components
|
||||
singular: component
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.workload.kind
|
||||
name: WORKLOAD-KIND
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: age
|
||||
type: date
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A Component describes how an OAM workload kind may be instantiated.
|
||||
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: A ComponentSpec defines the desired state of a Component.
|
||||
properties:
|
||||
helm:
|
||||
description: HelmRelease records a Helm release used by a Helm module
|
||||
workload.
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm module
|
||||
workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
parameters:
|
||||
description: Parameters exposed by this component. ApplicationConfigurations
|
||||
that reference this component may specify values for these parameters,
|
||||
which will in turn be injected into the embedded workload.
|
||||
items:
|
||||
description: A ComponentParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: FieldPaths specifies an array of fields within
|
||||
this Component's workload that will be overwritten by the
|
||||
value of this parameter. The type of the parameter (e.g. int,
|
||||
string) is inferred from the type of these fields; All fields
|
||||
must be of the same type. Fields are specified as JSON field
|
||||
paths without a leading dot, for example 'spec.replicas'.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter. OAM ApplicationConfigurations
|
||||
will specify parameter values using this name.
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value for this
|
||||
parameter must be supplied when authoring an ApplicationConfiguration.
|
||||
type: boolean
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
workload:
|
||||
description: A Workload that will be created for each ApplicationConfiguration
|
||||
that includes this Component. Workload is an instance of a workloadDefinition.
|
||||
We either use the GVK info or a special "type" field in the workload
|
||||
to associate the content of the workload with its workloadDefinition
|
||||
type: object
|
||||
|
||||
|
||||
required:
|
||||
- workload
|
||||
type: object
|
||||
status:
|
||||
description: A ComponentStatus represents the observed state of a Component.
|
||||
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
|
||||
latestRevision:
|
||||
description: LatestRevision of component
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
observedGeneration:
|
||||
description: The generation observed by the component controller.
|
||||
format: int64
|
||||
type: integer
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,319 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.6.2
|
||||
name: envbindings.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: EnvBinding
|
||||
listKind: EnvBindingList
|
||||
plural: envbindings
|
||||
shortNames:
|
||||
- envbind
|
||||
singular: envbinding
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.engine
|
||||
name: ENGINE
|
||||
type: string
|
||||
- jsonPath: .status.phase
|
||||
name: PHASE
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: AGE
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: EnvBinding is the Schema for the EnvBinding 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: A EnvBindingSpec defines the desired state of a EnvBinding.
|
||||
properties:
|
||||
appTemplate:
|
||||
description: AppTemplate indicates the application template.
|
||||
type: object
|
||||
|
||||
|
||||
engine:
|
||||
description: ClusterManagementEngine represents a multi-cluster management
|
||||
solution
|
||||
type: string
|
||||
envs:
|
||||
items:
|
||||
description: EnvConfig is the configuration for different environments.
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
patch:
|
||||
description: EnvPatch specify the parameter configuration for
|
||||
different environments
|
||||
properties:
|
||||
components:
|
||||
items:
|
||||
description: ApplicationComponent describe the component
|
||||
of application
|
||||
properties:
|
||||
dependsOn:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
externalRevision:
|
||||
description: ExternalRevision specified the component
|
||||
revisionName
|
||||
type: string
|
||||
inputs:
|
||||
description: StepInputs defines variable input of
|
||||
WorkflowStep
|
||||
items:
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
parameterKey:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- parameterKey
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
outputs:
|
||||
description: StepOutputs defines output variable of
|
||||
WorkflowStep
|
||||
items:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
valueFrom:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- valueFrom
|
||||
type: object
|
||||
type: array
|
||||
properties:
|
||||
type: object
|
||||
|
||||
scopes:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: scopes in ApplicationComponent defines
|
||||
the component-level scopes the format is <scope-type:scope-instance-name>
|
||||
pairs, the key represents type of `ScopeDefinition`
|
||||
while the value represent the name of scope instance.
|
||||
type: object
|
||||
|
||||
traits:
|
||||
description: Traits define the trait of one component,
|
||||
the type must be array to keep the order.
|
||||
items:
|
||||
description: ApplicationTrait defines the trait
|
||||
of application
|
||||
properties:
|
||||
properties:
|
||||
type: object
|
||||
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- components
|
||||
type: object
|
||||
placement:
|
||||
description: EnvPlacement defines the placement rules for an
|
||||
app.
|
||||
properties:
|
||||
clusterSelector:
|
||||
description: ClusterSelector defines the rules to select
|
||||
a Cluster resource. Either name or labels is needed.
|
||||
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
|
||||
namespaceSelector:
|
||||
description: NamespaceSelector defines the rules to select
|
||||
a Namespace resource. Either name or labels is needed.
|
||||
properties:
|
||||
labels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Labels defines the label selector to select
|
||||
the namespace.
|
||||
type: object
|
||||
name:
|
||||
description: Name is the name of the namespace.
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
selector:
|
||||
description: EnvSelector defines which components should this
|
||||
env contains
|
||||
properties:
|
||||
components:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- patch
|
||||
type: object
|
||||
type: array
|
||||
outputResourcesTo:
|
||||
description: OutputResourcesTo specifies the namespace and name of
|
||||
a ConfigMap which store the resources rendered after differentiated
|
||||
configuration
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- appTemplate
|
||||
- envs
|
||||
type: object
|
||||
status:
|
||||
description: A EnvBindingStatus is the status of EnvBinding
|
||||
properties:
|
||||
clusterDecisions:
|
||||
items:
|
||||
description: ClusterDecision recorded the mapping of environment
|
||||
and cluster
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
env:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- env
|
||||
type: object
|
||||
type: array
|
||||
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: EnvBindingPhase is a label for the condition of a EnvBinding
|
||||
at the current time
|
||||
type: string
|
||||
resourceTracker:
|
||||
description: ResourceTracker record the status of the ResourceTracker
|
||||
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
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -1,586 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: healthscopes.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: HealthScope
|
||||
listKind: HealthScopeList
|
||||
plural: healthscopes
|
||||
singular: healthscope
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.health
|
||||
name: HEALTH
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A HealthScope determines an aggregate health status based of
|
||||
the health of components.
|
||||
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: A HealthScopeSpec defines the desired state of a HealthScope.
|
||||
properties:
|
||||
appReferences:
|
||||
description: AppRefs records references of applications' components
|
||||
items:
|
||||
description: AppReference records references of an application's
|
||||
components
|
||||
properties:
|
||||
appName:
|
||||
type: string
|
||||
compReferences:
|
||||
items:
|
||||
description: CompReference records references of a component's
|
||||
resources
|
||||
properties:
|
||||
compName:
|
||||
type: string
|
||||
traits:
|
||||
items:
|
||||
description: "ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object.
|
||||
--- New uses of this type are discouraged because
|
||||
of difficulty describing its usage when embedded in
|
||||
APIs. 1. Ignored fields. It includes many fields
|
||||
which are not generally honored. For instance, ResourceVersion
|
||||
and FieldPath are both very rarely valid in actual
|
||||
usage. 2. Invalid usage help. It is impossible to
|
||||
add specific help for individual usage. In most embedded
|
||||
usages, there are particular restrictions like, \"must
|
||||
refer only to types A and B\" or \"UID not honored\"
|
||||
or \"name must be restricted\". Those cannot be well
|
||||
described when embedded. 3. Inconsistent validation.
|
||||
\ Because the usages are different, the validation
|
||||
rules are different by usage, which makes it hard
|
||||
for users to predict what will happen. 4. The fields
|
||||
are both imprecise and overly precise. Kind is not
|
||||
a precise mapping to a URL. This can produce ambiguity
|
||||
during interpretation and require a REST mapping.
|
||||
\ In most cases, the dependency is on the group,resource
|
||||
tuple and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type
|
||||
is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs
|
||||
embed an underspecified API type they do not control.
|
||||
\n Instead of using this type, create a locally provided
|
||||
and used type that is well-focused on your reference.
|
||||
For example, ServiceReferences for admission registration:
|
||||
https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
workload:
|
||||
description: "ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object. ---
|
||||
New uses of this type are discouraged because of difficulty
|
||||
describing its usage when embedded in APIs. 1. Ignored
|
||||
fields. It includes many fields which are not generally
|
||||
honored. For instance, ResourceVersion and FieldPath
|
||||
are both very rarely valid in actual usage. 2. Invalid
|
||||
usage help. It is impossible to add specific help for
|
||||
individual usage. In most embedded usages, there are
|
||||
particular restrictions like, \"must refer only to types
|
||||
A and B\" or \"UID not honored\" or \"name must be restricted\".
|
||||
Those cannot be well described when embedded. 3. Inconsistent
|
||||
validation. Because the usages are different, the validation
|
||||
rules are different by usage, which makes it hard for
|
||||
users to predict what will happen. 4. The fields are
|
||||
both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during
|
||||
interpretation and require a REST mapping. In most
|
||||
cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is
|
||||
embedded in many locations, updates to this type will
|
||||
affect numerous schemas. Don't make new APIs embed
|
||||
an underspecified API type they do not control. \n Instead
|
||||
of using this type, create a locally provided and used
|
||||
type that is well-focused on your reference. For example,
|
||||
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: array
|
||||
probe-interval:
|
||||
description: ProbeInterval is the amount of time in seconds between
|
||||
probing tries.
|
||||
format: int32
|
||||
type: integer
|
||||
probe-timeout:
|
||||
description: ProbeTimeout is the amount of time in seconds to wait
|
||||
when receiving a response before marked failure.
|
||||
format: int32
|
||||
type: integer
|
||||
workloadRefs:
|
||||
description: WorkloadReferences to the workloads that are in this
|
||||
scope.
|
||||
items:
|
||||
description: "ObjectReference contains enough information to let
|
||||
you inspect or modify the referred object. --- New uses of this
|
||||
type are discouraged because of difficulty describing its usage
|
||||
when embedded in APIs. 1. Ignored fields. It includes many fields
|
||||
which are not generally honored. For instance, ResourceVersion
|
||||
and FieldPath are both very rarely valid in actual usage. 2. Invalid
|
||||
usage help. It is impossible to add specific help for individual
|
||||
usage. In most embedded usages, there are particular restrictions
|
||||
like, \"must refer only to types A and B\" or \"UID not honored\"
|
||||
or \"name must be restricted\". Those cannot be well described
|
||||
when embedded. 3. Inconsistent validation. Because the usages
|
||||
are different, the validation rules are different by usage, which
|
||||
makes it hard for users to predict what will happen. 4. The fields
|
||||
are both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during interpretation
|
||||
and require a REST mapping. In most cases, the dependency is
|
||||
on the group,resource tuple and the version of the actual struct
|
||||
is irrelevant. 5. We cannot easily change it. Because this type
|
||||
is embedded in many locations, updates to this type will affect
|
||||
numerous schemas. Don't make new APIs embed an underspecified
|
||||
API type they do not control. \n Instead of using this type, create
|
||||
a locally provided and used type that is well-focused on your
|
||||
reference. For example, ServiceReferences for admission registration:
|
||||
https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
required:
|
||||
- workloadRefs
|
||||
type: object
|
||||
status:
|
||||
description: A HealthScopeStatus represents the observed state of a HealthScope.
|
||||
properties:
|
||||
appHealthConditions:
|
||||
description: AppHealthConditions represents health condition of applications
|
||||
in the scope
|
||||
items:
|
||||
description: AppHealthCondition represents health condition of an
|
||||
application
|
||||
properties:
|
||||
appName:
|
||||
type: string
|
||||
components:
|
||||
items:
|
||||
description: WorkloadHealthCondition represents informative
|
||||
health condition of a workload.
|
||||
properties:
|
||||
componentName:
|
||||
description: ComponentName represents the component name
|
||||
if target is a workload
|
||||
type: string
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
targetWorkload:
|
||||
description: "ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object. ---
|
||||
New uses of this type are discouraged because of difficulty
|
||||
describing its usage when embedded in APIs. 1. Ignored
|
||||
fields. It includes many fields which are not generally
|
||||
honored. For instance, ResourceVersion and FieldPath
|
||||
are both very rarely valid in actual usage. 2. Invalid
|
||||
usage help. It is impossible to add specific help for
|
||||
individual usage. In most embedded usages, there are
|
||||
particular restrictions like, \"must refer only to types
|
||||
A and B\" or \"UID not honored\" or \"name must be restricted\".
|
||||
Those cannot be well described when embedded. 3. Inconsistent
|
||||
validation. Because the usages are different, the validation
|
||||
rules are different by usage, which makes it hard for
|
||||
users to predict what will happen. 4. The fields are
|
||||
both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during
|
||||
interpretation and require a REST mapping. In most
|
||||
cases, the dependency is on the group,resource tuple
|
||||
and the version of the actual struct is irrelevant.
|
||||
5. We cannot easily change it. Because this type is
|
||||
embedded in many locations, updates to this type will
|
||||
affect numerous schemas. Don't make new APIs embed
|
||||
an underspecified API type they do not control. \n Instead
|
||||
of using this type, create a locally provided and used
|
||||
type that is well-focused on your reference. For example,
|
||||
ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
traits:
|
||||
items:
|
||||
description: TraitHealthCondition represents informative
|
||||
health condition of a trait.
|
||||
properties:
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status
|
||||
strings.
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
- resource
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
workloadStatus:
|
||||
description: WorkloadStatus represents status of workloads
|
||||
whose HealthStatus is UNKNOWN.
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
type: object
|
||||
type: array
|
||||
envName:
|
||||
type: string
|
||||
required:
|
||||
- appName
|
||||
type: object
|
||||
type: array
|
||||
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
|
||||
healthConditions:
|
||||
description: WorkloadHealthConditions represents health condition
|
||||
of workloads in the scope Use AppHealthConditions to provide app
|
||||
level status
|
||||
items:
|
||||
description: WorkloadHealthCondition represents informative health
|
||||
condition of a workload.
|
||||
properties:
|
||||
componentName:
|
||||
description: ComponentName represents the component name if
|
||||
target is a workload
|
||||
type: string
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
targetWorkload:
|
||||
description: "ObjectReference contains enough information to
|
||||
let you inspect or modify the referred object. --- New uses
|
||||
of this type are discouraged because of difficulty describing
|
||||
its usage when embedded in APIs. 1. Ignored fields. It includes
|
||||
many fields which are not generally honored. For instance,
|
||||
ResourceVersion and FieldPath are both very rarely valid in
|
||||
actual usage. 2. Invalid usage help. It is impossible to
|
||||
add specific help for individual usage. In most embedded
|
||||
usages, there are particular restrictions like, \"must refer
|
||||
only to types A and B\" or \"UID not honored\" or \"name must
|
||||
be restricted\". Those cannot be well described when embedded.
|
||||
3. Inconsistent validation. Because the usages are different,
|
||||
the validation rules are different by usage, which makes it
|
||||
hard for users to predict what will happen. 4. The fields
|
||||
are both imprecise and overly precise. Kind is not a precise
|
||||
mapping to a URL. This can produce ambiguity during interpretation
|
||||
and require a REST mapping. In most cases, the dependency
|
||||
is on the group,resource tuple and the version of the actual
|
||||
struct is irrelevant. 5. We cannot easily change it. Because
|
||||
this type is embedded in many locations, updates to this type
|
||||
will affect numerous schemas. Don't make new APIs embed an
|
||||
underspecified API type they do not control. \n Instead of
|
||||
using this type, create a locally provided and used type that
|
||||
is well-focused on your reference. For example, ServiceReferences
|
||||
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
|
||||
."
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
traits:
|
||||
items:
|
||||
description: TraitHealthCondition represents informative health
|
||||
condition of a trait.
|
||||
properties:
|
||||
customStatusMsg:
|
||||
type: string
|
||||
diagnosis:
|
||||
type: string
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
- resource
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
workloadStatus:
|
||||
description: WorkloadStatus represents status of workloads whose
|
||||
HealthStatus is UNKNOWN.
|
||||
type: string
|
||||
required:
|
||||
- healthStatus
|
||||
type: object
|
||||
type: array
|
||||
scopeHealthCondition:
|
||||
description: ScopeHealthCondition represents health condition summary
|
||||
of the scope
|
||||
properties:
|
||||
healthStatus:
|
||||
description: HealthStatus represents health status strings.
|
||||
type: string
|
||||
healthyWorkloads:
|
||||
format: int64
|
||||
type: integer
|
||||
total:
|
||||
format: int64
|
||||
type: integer
|
||||
unhealthyWorkloads:
|
||||
format: int64
|
||||
type: integer
|
||||
unknownWorkloads:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- healthStatus
|
||||
type: object
|
||||
required:
|
||||
- scopeHealthCondition
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: policies.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: Policy
|
||||
listKind: PolicyList
|
||||
plural: policies
|
||||
singular: policy
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .type
|
||||
name: TYPE
|
||||
type: string
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Policy is the Schema for the policy 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
|
||||
properties:
|
||||
type: object
|
||||
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources: {}
|
||||
@@ -1,286 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: policydefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: PolicyDefinition
|
||||
listKind: PolicyDefinitionList
|
||||
plural: policydefinitions
|
||||
shortNames:
|
||||
- def-policy
|
||||
singular: policydefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: PolicyDefinition is the Schema for the policydefinitions 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: PolicyDefinitionSpec defines the desired state of PolicyDefinition
|
||||
properties:
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this trait kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
manageHealthCheck:
|
||||
description: ManageHealthCheck means the policy will handle health
|
||||
checking and skip application controller built-in health checking.
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the policy definition. Only CUE schematic is supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: PolicyDefinitionStatus is the status of PolicyDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -1,187 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: resourcetrackers.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: ResourceTracker
|
||||
listKind: ResourceTrackerList
|
||||
plural: resourcetrackers
|
||||
shortNames:
|
||||
- rt
|
||||
singular: resourcetracker
|
||||
scope: Cluster
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.type
|
||||
name: TYPE
|
||||
type: string
|
||||
- jsonPath: .metadata.labels['app\.oam\.dev\/name']
|
||||
name: APP
|
||||
type: string
|
||||
- jsonPath: .metadata.labels['app\.oam\.dev\/namespace']
|
||||
name: APP-NS
|
||||
type: string
|
||||
- jsonPath: .spec.applicationGeneration
|
||||
name: APP-GEN
|
||||
type: number
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: An ResourceTracker represents a tracker for track cross namespace
|
||||
resources
|
||||
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: ResourceTrackerSpec define the spec of resourceTracker
|
||||
properties:
|
||||
applicationGeneration:
|
||||
format: int64
|
||||
type: integer
|
||||
compression:
|
||||
description: ResourceTrackerCompression represents the compressed
|
||||
components in ResourceTracker.
|
||||
properties:
|
||||
data:
|
||||
type: string
|
||||
type:
|
||||
description: Type the compression type
|
||||
type: string
|
||||
type: object
|
||||
managedResources:
|
||||
items:
|
||||
description: ManagedResource define the resource to be managed by
|
||||
ResourceTracker
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
cluster:
|
||||
type: string
|
||||
component:
|
||||
type: string
|
||||
creator:
|
||||
type: string
|
||||
deleted:
|
||||
description: Deleted marks the resource to be deleted
|
||||
type: boolean
|
||||
env:
|
||||
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
|
||||
raw:
|
||||
type: object
|
||||
|
||||
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
|
||||
skipGC:
|
||||
description: SkipGC marks the resource to skip gc
|
||||
type: boolean
|
||||
trait:
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
type:
|
||||
description: ResourceTrackerType defines the type of resourceTracker
|
||||
type: string
|
||||
required:
|
||||
- applicationGeneration
|
||||
type: object
|
||||
status:
|
||||
description: ResourceTrackerStatus define the status of resourceTracker
|
||||
For backward-compatibility
|
||||
properties:
|
||||
trackedResources:
|
||||
description: Deprecated
|
||||
items:
|
||||
description: ClusterObjectReference defines the object reference
|
||||
with cluster.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
cluster:
|
||||
type: string
|
||||
creator:
|
||||
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
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -1,376 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
name: rollouts.core.oam.dev
|
||||
spec:
|
||||
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
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: Rollout
|
||||
listKind: RolloutList
|
||||
plural: rollouts
|
||||
shortNames:
|
||||
- rollout
|
||||
singular: rollout
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Rollout is the Schema for the Rollout 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: RolloutSpec defines how to describe an update between different compRevision
|
||||
properties:
|
||||
componentName:
|
||||
description: ComponentName specify the component name
|
||||
type: string
|
||||
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: APIVersion of the referenced object.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the referenced object.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
uid:
|
||||
description: UID of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
- name
|
||||
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: APIVersion of the referenced object.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the referenced object.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
uid:
|
||||
description: UID of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
- name
|
||||
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
|
||||
sourceRevisionName:
|
||||
description: SourceRevisionName contains the name of the componentRevisionName that we need to upgrade from. it can be empty only when it's the first time to deploy the application
|
||||
type: string
|
||||
targetRevisionName:
|
||||
description: TargetRevisionName contains the name of the componentRevisionName that we need to upgrade to.
|
||||
type: string
|
||||
required:
|
||||
- componentName
|
||||
- rolloutPlan
|
||||
- targetRevisionName
|
||||
type: object
|
||||
status:
|
||||
description: RolloutStatus defines the observed state of rollout
|
||||
properties:
|
||||
LastSourceRevision:
|
||||
description: LastSourceRevision contains the name of the componentRevisionName 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
|
||||
lastTargetRevision:
|
||||
description: LastUpgradedTargetRevision contains the name of the componentRevisionName 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
|
||||
- lastTargetRevision
|
||||
- rollingState
|
||||
- upgradedReadyReplicas
|
||||
- upgradedReplicas
|
||||
type: object
|
||||
type: object
|
||||
version: v1beta1
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -1,673 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: traitdefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: TraitDefinition
|
||||
listKind: TraitDefinitionList
|
||||
plural: traitdefinitions
|
||||
shortNames:
|
||||
- trait
|
||||
singular: traitdefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.appliesToWorkloads
|
||||
name: APPLIES-TO
|
||||
type: string
|
||||
- jsonPath: .metadata.annotations.definition\.oam\.dev/description
|
||||
name: DESCRIPTION
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A TraitDefinition registers a kind of Kubernetes custom resource
|
||||
as a valid OAM trait kind by referencing its CustomResourceDefinition. The
|
||||
CRD is used to validate the schema of the trait when it is embedded in an
|
||||
OAM ApplicationConfiguration.
|
||||
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: A TraitDefinitionSpec defines the desired state of a TraitDefinition.
|
||||
properties:
|
||||
appliesToWorkloads:
|
||||
description: AppliesToWorkloads specifies the list of workload kinds
|
||||
this trait applies to. Workload kinds are specified in kind.group/version
|
||||
format, e.g. server.core.oam.dev/v1alpha2. Traits that omit this
|
||||
field apply to all workload kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
conflictsWith:
|
||||
description: 'ConflictsWith specifies the list of traits(CRD name,
|
||||
Definition name, CRD group) which could not apply to the same workloads
|
||||
with this trait. Traits that omit this field can work with any other
|
||||
traits. Example rules: "service" # Trait definition name "services.k8s.io"
|
||||
# API resource/crd name "*.networking.k8s.io" # API group "labelSelector:foo=bar"
|
||||
# label selector labelSelector format: https://pkg.go.dev/k8s.io/apimachinery/pkg/labels#Parse'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this trait kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
podDisruptive:
|
||||
description: PodDisruptive specifies whether using the trait will
|
||||
cause the pod to restart or not.
|
||||
type: boolean
|
||||
revisionEnabled:
|
||||
description: Revision indicates whether a trait is aware of component
|
||||
revision
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the trait
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for trait
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
workloadRefPath:
|
||||
description: WorkloadRefPath indicates where/if a trait accepts a
|
||||
workloadRef object
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
description: TraitDefinitionStatus is the status of TraitDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the trait definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.appliesToWorkloads
|
||||
name: APPLIES-TO
|
||||
type: string
|
||||
- jsonPath: .metadata.annotations.definition\.oam\.dev/description
|
||||
name: DESCRIPTION
|
||||
type: string
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A TraitDefinition registers a kind of Kubernetes custom resource
|
||||
as a valid OAM trait kind by referencing its CustomResourceDefinition. The
|
||||
CRD is used to validate the schema of the trait when it is embedded in an
|
||||
OAM ApplicationConfiguration.
|
||||
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: A TraitDefinitionSpec defines the desired state of a TraitDefinition.
|
||||
properties:
|
||||
appliesToWorkloads:
|
||||
description: AppliesToWorkloads specifies the list of workload kinds
|
||||
this trait applies to. Workload kinds are specified in resource.group/version
|
||||
format, e.g. server.core.oam.dev/v1alpha2. Traits that omit this
|
||||
field apply to all workload kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
conflictsWith:
|
||||
description: 'ConflictsWith specifies the list of traits(CRD name,
|
||||
Definition name, CRD group) which could not apply to the same workloads
|
||||
with this trait. Traits that omit this field can work with any other
|
||||
traits. Example rules: "service" # Trait definition name "services.k8s.io"
|
||||
# API resource/crd name "*.networking.k8s.io" # API group "labelSelector:foo=bar"
|
||||
# label selector labelSelector format: https://pkg.go.dev/k8s.io/apimachinery/pkg/labels#Parse'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
controlPlaneOnly:
|
||||
description: ControlPlaneOnly defines which cluster is dispatched
|
||||
to
|
||||
type: boolean
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this trait kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
manageWorkload:
|
||||
description: ManageWorkload defines the trait would be responsible
|
||||
for creating the workload
|
||||
type: boolean
|
||||
podDisruptive:
|
||||
description: PodDisruptive specifies whether using the trait will
|
||||
cause the pod to restart or not.
|
||||
type: boolean
|
||||
revisionEnabled:
|
||||
description: Revision indicates whether a trait is aware of component
|
||||
revision
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the trait. Only CUE and Kube schematic are supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
stage:
|
||||
description: Stage defines the stage information to which this trait
|
||||
resource processing belongs. Currently, PreDispatch and PostDispatch
|
||||
are provided, which are used to control resource pre-process and
|
||||
post-process respectively.
|
||||
type: string
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for trait
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
workloadRefPath:
|
||||
description: WorkloadRefPath indicates where/if a trait accepts a
|
||||
workloadRef object
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
description: TraitDefinitionStatus is the status of TraitDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -1,172 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.9.0
|
||||
name: workflows.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: Workflow
|
||||
listKind: WorkflowList
|
||||
plural: workflows
|
||||
singular: workflow
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Workflow is the Schema for the workflow API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
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
|
||||
mode:
|
||||
description: WorkflowExecuteMode defines the mode of workflow execution
|
||||
properties:
|
||||
steps:
|
||||
description: Steps is the mode of workflow steps execution
|
||||
type: string
|
||||
subSteps:
|
||||
description: SubSteps is the mode of workflow sub steps execution
|
||||
type: string
|
||||
type: object
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStep defines how to execute a workflow step.
|
||||
properties:
|
||||
dependsOn:
|
||||
description: DependsOn is the dependency of the step
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
if:
|
||||
description: If is the if condition of the step
|
||||
type: string
|
||||
inputs:
|
||||
description: Inputs is the inputs of the step
|
||||
items:
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
parameterKey:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- parameterKey
|
||||
type: object
|
||||
type: array
|
||||
meta:
|
||||
description: Meta is the meta data of the workflow step.
|
||||
properties:
|
||||
alias:
|
||||
type: string
|
||||
type: object
|
||||
name:
|
||||
description: Name is the unique name of the workflow step.
|
||||
type: string
|
||||
outputs:
|
||||
description: Outputs is the outputs of the step
|
||||
items:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
valueFrom:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- valueFrom
|
||||
type: object
|
||||
type: array
|
||||
properties:
|
||||
description: Properties is the properties of the step
|
||||
type: object
|
||||
|
||||
subSteps:
|
||||
items:
|
||||
description: WorkflowStepBase defines the workflow step base
|
||||
properties:
|
||||
dependsOn:
|
||||
description: DependsOn is the dependency of the step
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
if:
|
||||
description: If is the if condition of the step
|
||||
type: string
|
||||
inputs:
|
||||
description: Inputs is the inputs of the step
|
||||
items:
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
parameterKey:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- parameterKey
|
||||
type: object
|
||||
type: array
|
||||
meta:
|
||||
description: Meta is the meta data of the workflow step.
|
||||
properties:
|
||||
alias:
|
||||
type: string
|
||||
type: object
|
||||
name:
|
||||
description: Name is the unique name of the workflow step.
|
||||
type: string
|
||||
outputs:
|
||||
description: Outputs is the outputs of the step
|
||||
items:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
valueFrom:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- valueFrom
|
||||
type: object
|
||||
type: array
|
||||
properties:
|
||||
description: Properties is the properties of the step
|
||||
type: object
|
||||
|
||||
timeout:
|
||||
description: Timeout is the timeout of the step
|
||||
type: string
|
||||
type:
|
||||
description: Type is the type of the workflow step.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
timeout:
|
||||
description: Timeout is the timeout of the step
|
||||
type: string
|
||||
type:
|
||||
description: Type is the type of the workflow step.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
@@ -1,283 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: workflowstepdefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: WorkflowStepDefinition
|
||||
listKind: WorkflowStepDefinitionList
|
||||
plural: workflowstepdefinitions
|
||||
shortNames:
|
||||
- workflowstep
|
||||
singular: workflowstepdefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: WorkflowStepDefinition is the Schema for the workflowstepdefinitions
|
||||
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: WorkflowStepDefinitionSpec defines the desired state of WorkflowStepDefinition
|
||||
properties:
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this trait kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workflow step definition. Only CUE schematic
|
||||
is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: WorkflowStepDefinitionStatus is the status of WorkflowStepDefinition
|
||||
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
|
||||
configMapRef:
|
||||
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
|
||||
V3 JSON schema of Component parameters.
|
||||
type: string
|
||||
latestRevision:
|
||||
description: LatestRevision of the component definition
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
revision:
|
||||
format: int64
|
||||
type: integer
|
||||
revisionHash:
|
||||
description: RevisionHash record the hash value of the spec of
|
||||
ApplicationRevision object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- revision
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -1,625 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.4
|
||||
name: workloaddefinitions.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: WorkloadDefinition
|
||||
listKind: WorkloadDefinitionList
|
||||
plural: workloaddefinitions
|
||||
shortNames:
|
||||
- workload
|
||||
singular: workloaddefinition
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.definitionRef.name
|
||||
name: DEFINITION-NAME
|
||||
type: string
|
||||
name: v1alpha2
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A WorkloadDefinition registers a kind of Kubernetes custom resource
|
||||
as a valid OAM workload kind by referencing its CustomResourceDefinition.
|
||||
The CRD is used to validate the schema of the workload when it is embedded
|
||||
in an OAM Component.
|
||||
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: A WorkloadDefinitionSpec defines the desired state of a WorkloadDefinition.
|
||||
properties:
|
||||
childResourceKinds:
|
||||
description: ChildResourceKinds are the list of GVK of the child resources
|
||||
this workload generates
|
||||
items:
|
||||
description: A ChildResourceKind defines a child Kubernetes resource
|
||||
kind with a selector
|
||||
properties:
|
||||
apiVersion:
|
||||
description: APIVersion of the child resource
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the child resource
|
||||
type: string
|
||||
selector:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Selector to select the child resources that the
|
||||
workload wants to expose to traits
|
||||
type: object
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type: array
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this workload kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
podSpecPath:
|
||||
description: PodSpecPath indicates where/if this workload has K8s
|
||||
podSpec field if one workload has podSpec, trait can do lot's of
|
||||
assumption such as port, env, volume fields.
|
||||
type: string
|
||||
revisionLabel:
|
||||
description: RevisionLabel indicates which label for underlying resources(e.g.
|
||||
pods) of this workload can be used by trait to create resource selectors(e.g.
|
||||
label selector for pods).
|
||||
type: string
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workload
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for workload
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- definitionRef
|
||||
type: object
|
||||
status:
|
||||
description: WorkloadDefinitionStatus is the status of WorkloadDefinition
|
||||
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
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
subresources: {}
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.definitionRef.name
|
||||
name: DEFINITION-NAME
|
||||
type: string
|
||||
- jsonPath: .metadata.annotations.definition\.oam\.dev/description
|
||||
name: DESCRIPTION
|
||||
type: string
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: A WorkloadDefinition registers a kind of Kubernetes custom resource
|
||||
as a valid OAM workload kind by referencing its CustomResourceDefinition.
|
||||
The CRD is used to validate the schema of the workload when it is embedded
|
||||
in an OAM Component.
|
||||
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: A WorkloadDefinitionSpec defines the desired state of a WorkloadDefinition.
|
||||
properties:
|
||||
childResourceKinds:
|
||||
description: ChildResourceKinds are the list of GVK of the child resources
|
||||
this workload generates
|
||||
items:
|
||||
description: A ChildResourceKind defines a child Kubernetes resource
|
||||
kind with a selector
|
||||
properties:
|
||||
apiVersion:
|
||||
description: APIVersion of the child resource
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of the child resource
|
||||
type: string
|
||||
selector:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Selector to select the child resources that the
|
||||
workload wants to expose to traits
|
||||
type: object
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
type: object
|
||||
type: array
|
||||
definitionRef:
|
||||
description: Reference to the CustomResourceDefinition that defines
|
||||
this workload kind.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced CustomResourceDefinition.
|
||||
type: string
|
||||
version:
|
||||
description: Version indicate which version should be used if
|
||||
CRD has multiple versions by default it will use the first one
|
||||
if not specified
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
extension:
|
||||
description: Extension is used for extension needs by OAM platform
|
||||
builders
|
||||
type: object
|
||||
|
||||
podSpecPath:
|
||||
description: PodSpecPath indicates where/if this workload has K8s
|
||||
podSpec field if one workload has podSpec, trait can do lot's of
|
||||
assumption such as port, env, volume fields.
|
||||
type: string
|
||||
revisionLabel:
|
||||
description: RevisionLabel indicates which label for underlying resources(e.g.
|
||||
pods) of this workload can be used by trait to create resource selectors(e.g.
|
||||
label selector for pods).
|
||||
type: string
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workload
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
properties:
|
||||
template:
|
||||
description: Template defines the abstraction template data
|
||||
of the capability, it will replace the old CUE template
|
||||
in extension field. Template is a required field if CUE
|
||||
is defined in Capability Definition.
|
||||
type: string
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
helm:
|
||||
description: A Helm represents resources used by a Helm module
|
||||
properties:
|
||||
release:
|
||||
description: Release records a Helm release used by a Helm
|
||||
module workload.
|
||||
type: object
|
||||
|
||||
repository:
|
||||
description: HelmRelease records a Helm repository used by
|
||||
a Helm module workload.
|
||||
type: object
|
||||
|
||||
required:
|
||||
- release
|
||||
- repository
|
||||
type: object
|
||||
kube:
|
||||
description: Kube defines the encapsulation in raw Kubernetes
|
||||
resource format
|
||||
properties:
|
||||
parameters:
|
||||
description: Parameters defines configurable parameters
|
||||
items:
|
||||
description: A KubeParameter defines a configurable parameter
|
||||
of a component.
|
||||
properties:
|
||||
description:
|
||||
description: Description of this parameter.
|
||||
type: string
|
||||
fieldPaths:
|
||||
description: "FieldPaths specifies an array of fields
|
||||
within this workload that will be overwritten by the
|
||||
value of this parameter. \tAll fields must be of the
|
||||
same type. Fields are specified as JSON field paths
|
||||
without a leading dot, for example 'spec.replicas'."
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
description: Name of this parameter
|
||||
type: string
|
||||
required:
|
||||
|
||||
description: Required specifies whether or not a value
|
||||
for this parameter must be supplied when authoring
|
||||
an Application.
|
||||
type: boolean
|
||||
type:
|
||||
description: 'ValueType indicates the type of the parameter
|
||||
value, and only supports basic data types: string,
|
||||
number, boolean.'
|
||||
enum:
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
type: string
|
||||
required:
|
||||
- fieldPaths
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
template:
|
||||
description: Template defines the raw Kubernetes resource
|
||||
type: object
|
||||
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
terraform:
|
||||
description: Terraform is the struct to describe cloud resources
|
||||
managed by Hashicorp Terraform
|
||||
properties:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
type: string
|
||||
customRegion:
|
||||
description: Region is cloud provider's region. It will override
|
||||
the region in the region field of ProviderReference
|
||||
type: string
|
||||
deleteResource:
|
||||
default: true
|
||||
description: DeleteResource will determine whether provisioned
|
||||
cloud resources will be deleted when CR is deleted
|
||||
type: boolean
|
||||
gitCredentialsSecretReference:
|
||||
description: GitCredentialsSecretReference specifies the reference
|
||||
to the secret containing the git credentials
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference
|
||||
a secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which
|
||||
the secret name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
path:
|
||||
description: Path is the sub-directory of remote git repository.
|
||||
It's valid when remote is set
|
||||
type: string
|
||||
providerRef:
|
||||
description: ProviderReference specifies the reference to
|
||||
Provider
|
||||
properties:
|
||||
name:
|
||||
description: Name of the referenced object.
|
||||
type: string
|
||||
namespace:
|
||||
default: default
|
||||
description: Namespace of the referenced object.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
it is, HCL or JSON syntax
|
||||
enum:
|
||||
- hcl
|
||||
- json
|
||||
- remote
|
||||
type: string
|
||||
writeConnectionSecretToRef:
|
||||
description: WriteConnectionSecretToReference specifies the
|
||||
namespace and name of a Secret to which any connection details
|
||||
for this managed resource should be written. Connection
|
||||
details frequently include the endpoint, username, and password
|
||||
required to connect to the managed resource.
|
||||
properties:
|
||||
name:
|
||||
description: Name of the secret.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- configuration
|
||||
type: object
|
||||
type: object
|
||||
status:
|
||||
description: Status defines the custom health policy and status message
|
||||
for workload
|
||||
properties:
|
||||
customStatus:
|
||||
description: CustomStatus defines the custom status message that
|
||||
could display to user
|
||||
type: string
|
||||
healthPolicy:
|
||||
description: HealthPolicy defines the health check policy for
|
||||
the abstraction
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- definitionRef
|
||||
type: object
|
||||
status:
|
||||
description: WorkloadDefinitionStatus is the status of WorkloadDefinition
|
||||
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
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources: {}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +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 main // #nosec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if len(os.Args) > 1 {
|
||||
dir = os.Args[1]
|
||||
}
|
||||
err = filepath.Walk(dir, func(path string, info os.FileInfo, _ error) error {
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
/* #nosec */
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "failed to read file", err)
|
||||
return err
|
||||
}
|
||||
newdata := strings.ReplaceAll(string(data), "x-kubernetes-embedded-resource: true", "")
|
||||
newdata = strings.ReplaceAll(newdata, "x-kubernetes-preserve-unknown-fields: true", "")
|
||||
newdata = strings.ReplaceAll(newdata, "default: false", "")
|
||||
/* #nosec */
|
||||
if err = os.WriteFile(path, []byte(newdata), 0644); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "failed to write file:", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -352,7 +352,7 @@ func (af *Appfile) SetOAMContract(comp *types.ComponentManifest) error {
|
||||
Name: comp.StandardWorkload.GetName(),
|
||||
}
|
||||
for _, trait := range comp.Traits {
|
||||
af.assembleTrait(trait, compName, commonLabels)
|
||||
af.assembleTrait(trait, comp.Name, commonLabels)
|
||||
if err := af.setWorkloadRefToTrait(workloadRef, trait); err != nil && !IsNotFoundInAppFile(err) {
|
||||
return errors.WithMessagef(err, "cannot set workload reference to trait %q", trait.GetName())
|
||||
}
|
||||
@@ -443,14 +443,12 @@ func (af *Appfile) setWorkloadLabels(wl *unstructured.Unstructured, commonLabels
|
||||
}
|
||||
|
||||
func (af *Appfile) assembleTrait(trait *unstructured.Unstructured, compName string, labels map[string]string) {
|
||||
traitType := trait.GetLabels()[oam.TraitTypeLabel]
|
||||
// only set generated name when name is unspecified
|
||||
// it's by design to set arbitrary name in render phase
|
||||
if len(trait.GetName()) == 0 {
|
||||
traitType := trait.GetLabels()[oam.TraitTypeLabel]
|
||||
cpTrait := trait.DeepCopy()
|
||||
// remove labels that should not be calculated into hash
|
||||
util.RemoveLabels(cpTrait, []string{oam.LabelAppRevision})
|
||||
traitName := util.GenTraitNameCompatible(compName, cpTrait, traitType)
|
||||
traitName := util.GenTraitName(compName, cpTrait, traitType)
|
||||
trait.SetName(traitName)
|
||||
}
|
||||
af.setTraitLabels(trait, labels)
|
||||
|
||||
@@ -335,137 +335,6 @@ wait: op.#ConditionalWait & {
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("Test Policy", func() {
|
||||
It("test generate PolicyWorkloads", func() {
|
||||
testAppfile := &Appfile{
|
||||
Name: "test-app",
|
||||
Namespace: "default",
|
||||
Workloads: []*Workload{
|
||||
{
|
||||
Name: "test-comp",
|
||||
Type: "worker",
|
||||
CapabilityCategory: oamtypes.KubeCategory,
|
||||
engine: definition.NewWorkloadAbstractEngine("test-comp", pd),
|
||||
FullTemplate: &Template{
|
||||
Kube: &common.Kube{
|
||||
Template: func() runtime.RawExtension {
|
||||
yamlStr := `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
ports:
|
||||
- containerPort: 80 `
|
||||
b, _ := yaml.YAMLToJSON([]byte(yamlStr))
|
||||
return runtime.RawExtension{Raw: b}
|
||||
}(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
PolicyWorkloads: []*Workload{
|
||||
{
|
||||
Name: "test-policy",
|
||||
Type: "test-policy",
|
||||
Params: map[string]interface{}{
|
||||
"boundComponents": []string{"test-comp"},
|
||||
},
|
||||
FullTemplate: &Template{TemplateStr: ` output: {
|
||||
apiVersion: "core.oam.dev/v1alpha2"
|
||||
kind: "HealthScope"
|
||||
spec: {
|
||||
for k, v in parameter.boundComponents {
|
||||
compName: v
|
||||
workload: {
|
||||
apiVersion: context.artifacts[v].workload.apiVersion
|
||||
kind: context.artifacts[v].workload.kind
|
||||
name: v
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
outputs: virtualservice: {
|
||||
apiVersion: "networking.istio.io/v1alpha3"
|
||||
kind: "VirtualService"
|
||||
spec: {
|
||||
hosts: "abc"
|
||||
http: ["abc"]
|
||||
}
|
||||
}
|
||||
parameter: {
|
||||
boundComponents: [...string]
|
||||
}`},
|
||||
engine: definition.NewWorkloadAbstractEngine("test-policy", pd),
|
||||
},
|
||||
},
|
||||
app: &v1beta1.Application{},
|
||||
}
|
||||
_, err := testAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(BeNil())
|
||||
testAppfile.parser = &Parser{client: k8sClient}
|
||||
gotPolicies, err := testAppfile.GeneratePolicyManifests(context.Background())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(gotPolicies)).ShouldNot(Equal(0))
|
||||
|
||||
expectPolicy0 := unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"compName": "test-comp",
|
||||
"workload": map[string]interface{}{
|
||||
"name": "test-comp",
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
},
|
||||
},
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-policy",
|
||||
"namespace": "default",
|
||||
"labels": map[string]interface{}{
|
||||
"app.oam.dev/name": "test-app",
|
||||
"app.oam.dev/component": "test-policy",
|
||||
"app.oam.dev/appRevision": "",
|
||||
},
|
||||
},
|
||||
"apiVersion": "core.oam.dev/v1alpha2",
|
||||
"kind": "HealthScope",
|
||||
},
|
||||
}
|
||||
Expect(len(gotPolicies)).Should(Equal(2))
|
||||
gotPolicy := gotPolicies[0]
|
||||
Expect(cmp.Diff(gotPolicy.Object, expectPolicy0.Object)).Should(BeEmpty())
|
||||
expectPolicy1 := unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"hosts": "abc",
|
||||
"http": []interface{}{"abc"},
|
||||
},
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test-policy",
|
||||
"namespace": "default",
|
||||
"labels": map[string]interface{}{
|
||||
"app.oam.dev/name": "test-app",
|
||||
"app.oam.dev/component": "test-policy",
|
||||
"app.oam.dev/appRevision": "",
|
||||
},
|
||||
},
|
||||
"apiVersion": "networking.istio.io/v1alpha3",
|
||||
"kind": "VirtualService",
|
||||
},
|
||||
}
|
||||
gotPolicy = gotPolicies[1]
|
||||
Expect(cmp.Diff(gotPolicy.Object, expectPolicy1.Object)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
var _ = Describe("Test Terraform schematic appfile", func() {
|
||||
It("workload capability is Terraform", func() {
|
||||
var (
|
||||
|
||||
213
pkg/appfile/dryrun/testdata/diff-apprevision.yaml
vendored
213
pkg/appfile/dryrun/testdata/diff-apprevision.yaml
vendored
@@ -14,30 +14,30 @@ spec:
|
||||
metadata: {}
|
||||
spec:
|
||||
components:
|
||||
- name: myweb-1
|
||||
properties:
|
||||
cmd:
|
||||
- sleep
|
||||
- "1000"
|
||||
enemies: alien
|
||||
image: busybox
|
||||
lives: "3"
|
||||
traits:
|
||||
- properties:
|
||||
domain: www.example.com
|
||||
http:
|
||||
/: 80
|
||||
type: myingress
|
||||
type: myworker
|
||||
- name: myweb-2
|
||||
properties:
|
||||
cmd:
|
||||
- sleep
|
||||
- "1000"
|
||||
enemies: alien
|
||||
image: busybox
|
||||
lives: "3"
|
||||
type: myworker
|
||||
- name: myweb-1
|
||||
properties:
|
||||
cmd:
|
||||
- sleep
|
||||
- "1000"
|
||||
enemies: alien
|
||||
image: busybox
|
||||
lives: "3"
|
||||
traits:
|
||||
- properties:
|
||||
domain: www.example.com
|
||||
http:
|
||||
/: 80
|
||||
type: myingress
|
||||
type: myworker
|
||||
- name: myweb-2
|
||||
properties:
|
||||
cmd:
|
||||
- sleep
|
||||
- "1000"
|
||||
enemies: alien
|
||||
image: busybox
|
||||
lives: "3"
|
||||
type: myworker
|
||||
status: {}
|
||||
applicationConfiguration:
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
@@ -45,50 +45,50 @@ spec:
|
||||
metadata: {}
|
||||
spec:
|
||||
components:
|
||||
- componentName: myweb-1
|
||||
revisionName: myweb-1-v1
|
||||
traits:
|
||||
- trait:
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: livediff-demo-v1
|
||||
app.oam.dev/component: myweb-1
|
||||
app.oam.dev/name: livediff-demo
|
||||
trait.oam.dev/resource: service
|
||||
trait.oam.dev/type: myingress
|
||||
name: myweb-1
|
||||
namespace: default
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
selector:
|
||||
app.oam.dev/component: myweb-1
|
||||
- trait:
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: livediff-demo-v1
|
||||
app.oam.dev/component: myweb-1
|
||||
app.oam.dev/name: livediff-demo
|
||||
trait.oam.dev/resource: ingress
|
||||
trait.oam.dev/type: myingress
|
||||
name: myweb-1
|
||||
namespace: default
|
||||
spec:
|
||||
rules:
|
||||
- host: www.example.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: myweb-1
|
||||
servicePort: 80
|
||||
path: /
|
||||
- componentName: myweb-2
|
||||
revisionName: myweb-2-v1
|
||||
- componentName: myweb-1
|
||||
revisionName: myweb-1-v1
|
||||
traits:
|
||||
- trait:
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: livediff-demo-v1
|
||||
app.oam.dev/component: myweb-1
|
||||
app.oam.dev/name: livediff-demo
|
||||
trait.oam.dev/resource: service
|
||||
trait.oam.dev/type: myingress
|
||||
name: myweb-1
|
||||
namespace: default
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
selector:
|
||||
app.oam.dev/component: myweb-1
|
||||
- trait:
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: livediff-demo-v1
|
||||
app.oam.dev/component: myweb-1
|
||||
app.oam.dev/name: livediff-demo
|
||||
trait.oam.dev/resource: ingress
|
||||
trait.oam.dev/type: myingress
|
||||
name: myweb-1
|
||||
namespace: default
|
||||
spec:
|
||||
rules:
|
||||
- host: www.example.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: myweb-1
|
||||
servicePort: 80
|
||||
path: /
|
||||
- componentName: myweb-2
|
||||
revisionName: myweb-2-v1
|
||||
status:
|
||||
dependency: {}
|
||||
observedGeneration: 0
|
||||
@@ -114,79 +114,6 @@ spec:
|
||||
kind: Deployment
|
||||
type: deployments.apps
|
||||
status: {}
|
||||
components:
|
||||
- raw:
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Component
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/component-revision-hash: b63b8ddf2352632a
|
||||
name: myweb-1
|
||||
spec:
|
||||
workload:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: livediff-demo-v1
|
||||
app.oam.dev/component: myweb-1
|
||||
app.oam.dev/name: livediff-demo
|
||||
workload.oam.dev/type: myworker
|
||||
name: myweb-1
|
||||
namespace: default
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.oam.dev/component: myweb-1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/component: myweb-1
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- sleep
|
||||
- "1000"
|
||||
image: busybox
|
||||
name: myweb-1
|
||||
status:
|
||||
observedGeneration: 0
|
||||
- raw:
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Component
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/component-revision-hash: 85369ee876f97b85
|
||||
name: myweb-2
|
||||
spec:
|
||||
workload:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: livediff-demo-v1
|
||||
app.oam.dev/component: myweb-2
|
||||
app.oam.dev/name: livediff-demo
|
||||
workload.oam.dev/type: myworker
|
||||
name: myweb-2
|
||||
namespace: default
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.oam.dev/component: myweb-2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/component: myweb-2
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- sleep
|
||||
- "1000"
|
||||
image: busybox
|
||||
name: myweb-2
|
||||
status:
|
||||
observedGeneration: 0
|
||||
resourcesConfigMap:
|
||||
name: livediff-demo-v1
|
||||
traitDefinitions:
|
||||
@@ -196,7 +123,7 @@ spec:
|
||||
metadata: {}
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- '*'
|
||||
- '*'
|
||||
definitionRef:
|
||||
name: ""
|
||||
schematic:
|
||||
@@ -212,4 +139,4 @@ spec:
|
||||
parameter.domain\n\t\t\thttp: {\n\t\t\t\tpaths: [\n\t\t\t\t\tfor k, v in parameter.http
|
||||
{\n\t\t\t\t\t\tpath: k\n\t\t\t\t\t\tbackend: {\n\t\t\t\t\t\t\tserviceName:
|
||||
context.name\n\t\t\t\t\t\t\tservicePort: v\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t}\n\t\t}]\n\t}\n}\n"
|
||||
status: {}
|
||||
status: {}
|
||||
51
pkg/appfile/dryrun/testdata/dryrun-exp-ac.yaml
vendored
51
pkg/appfile/dryrun/testdata/dryrun-exp-ac.yaml
vendored
@@ -1,51 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ApplicationConfiguration
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app.oam.dev/name: app-dryrun
|
||||
name: app-dryrun
|
||||
spec:
|
||||
components:
|
||||
- componentName: myweb
|
||||
traits:
|
||||
- trait:
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: ""
|
||||
app.oam.dev/component: myweb
|
||||
app.oam.dev/name: app-dryrun
|
||||
trait.oam.dev/resource: service
|
||||
trait.oam.dev/type: myingress
|
||||
name: myweb
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
selector:
|
||||
app.oam.dev/component: myweb
|
||||
- trait:
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
labels:
|
||||
app.oam.dev/appRevision: ""
|
||||
app.oam.dev/component: myweb
|
||||
app.oam.dev/name: app-dryrun
|
||||
trait.oam.dev/resource: ingress
|
||||
trait.oam.dev/type: myingress
|
||||
name: myweb
|
||||
spec:
|
||||
rules:
|
||||
- host: www.example.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: myweb
|
||||
servicePort: 80
|
||||
path: /
|
||||
status:
|
||||
dependency: {}
|
||||
observedGeneration: 0
|
||||
@@ -29,11 +29,9 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/mock"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
@@ -83,7 +81,7 @@ func TestLoadComponentTemplate(t *testing.T) {
|
||||
`
|
||||
|
||||
var componentDefintion = `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: worker
|
||||
@@ -129,100 +127,6 @@ spec:
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadWorkloadTemplate(t *testing.T) {
|
||||
cueTemplate := `
|
||||
context: {
|
||||
name: "test"
|
||||
}
|
||||
output: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
"app.oam.dev/component": context.name
|
||||
}
|
||||
|
||||
template: {
|
||||
metadata: labels: {
|
||||
"app.oam.dev/component": context.name
|
||||
}
|
||||
|
||||
spec: {
|
||||
containers: [{
|
||||
name: context.name
|
||||
image: parameter.image
|
||||
|
||||
if parameter["cmd"] != _|_ {
|
||||
command: parameter.cmd
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
selector:
|
||||
matchLabels:
|
||||
"app.oam.dev/component": context.name
|
||||
}
|
||||
}
|
||||
|
||||
parameter: {
|
||||
// +usage=Which image would you like to use for your service
|
||||
// +short=i
|
||||
image: string
|
||||
|
||||
cmd?: [...string]
|
||||
}
|
||||
`
|
||||
|
||||
var workloadDefintion = `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
metadata:
|
||||
name: worker
|
||||
namespace: default
|
||||
annotations:
|
||||
definition.oam.dev/description: "Long-running scalable backend worker without network endpoint"
|
||||
spec:
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
extension:
|
||||
template: |
|
||||
` + cueTemplate
|
||||
|
||||
// Create mock client
|
||||
tclient := test.MockClient{
|
||||
MockGet: func(ctx context.Context, key ktypes.NamespacedName, obj client.Object) error {
|
||||
switch o := obj.(type) {
|
||||
case *v1alpha2.WorkloadDefinition:
|
||||
cd, err := oamutil.UnMarshalStringToWorkloadDefinition(workloadDefintion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*o = *cd
|
||||
case *v1alpha2.ComponentDefinition:
|
||||
err := mock.NewMockNotFoundErr()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
temp, err := LoadTemplate(context.TODO(), &tclient, "worker", types.TypeComponentDefinition)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
inst := cuecontext.New().CompileString(temp.TemplateStr)
|
||||
instDest := cuecontext.New().CompileString(cueTemplate)
|
||||
s1, _ := inst.Value().String()
|
||||
s2, _ := instDest.Value().String()
|
||||
if s1 != s2 {
|
||||
t.Errorf("parsered template is not correct")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadTraitTemplate(t *testing.T) {
|
||||
cueTemplate := `
|
||||
parameter: {
|
||||
@@ -275,7 +179,7 @@ func TestLoadTraitTemplate(t *testing.T) {
|
||||
`
|
||||
|
||||
var traitDefintion = `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
@@ -414,7 +318,7 @@ func TestLoadSchematicToTemplate(t *testing.T) {
|
||||
|
||||
func TestDryRunTemplateLoader(t *testing.T) {
|
||||
compDefStr := `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
name: myworker
|
||||
@@ -431,7 +335,7 @@ spec:
|
||||
template: testCUE `
|
||||
|
||||
traitDefStr := `
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
name: myingress
|
||||
|
||||
@@ -1,227 +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 cloudprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
cs20151215 "github.com/alibabacloud-go/cs-20151215/v3/client"
|
||||
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||||
"github.com/alibabacloud-go/tea/tea"
|
||||
types "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
|
||||
v1beta12 "github.com/oam-dev/terraform-controller/api/v1beta2"
|
||||
"github.com/pkg/errors"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/utils/util"
|
||||
)
|
||||
|
||||
const (
|
||||
aliyunAPIEndpoint = "cs.cn-hangzhou.aliyuncs.com"
|
||||
)
|
||||
|
||||
// AliyunCloudProvider describes the cloud provider in aliyun
|
||||
type AliyunCloudProvider struct {
|
||||
*cs20151215.Client
|
||||
k8sClient client.Client
|
||||
accessKeyID string
|
||||
accessKeySecret string
|
||||
}
|
||||
|
||||
// NewAliyunCloudProvider create aliyun cloud provider
|
||||
func NewAliyunCloudProvider(accessKeyID string, accessKeySecret string, k8sClient client.Client) (*AliyunCloudProvider, error) {
|
||||
config := &openapi.Config{
|
||||
AccessKeyId: pointer.String(accessKeyID),
|
||||
AccessKeySecret: pointer.String(accessKeySecret),
|
||||
}
|
||||
config.Endpoint = tea.String(aliyunAPIEndpoint)
|
||||
c, err := cs20151215.NewClient(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AliyunCloudProvider{Client: c, k8sClient: k8sClient, accessKeyID: accessKeyID, accessKeySecret: accessKeySecret}, nil
|
||||
}
|
||||
|
||||
// IsInvalidKey check if error is InvalidAccessKey or InvalidSecretKey
|
||||
func (provider *AliyunCloudProvider) IsInvalidKey(err error) bool {
|
||||
return strings.Contains(err.Error(), "InvalidAccessKeyId") || strings.Contains(err.Error(), "Code: SignatureDoesNotMatch")
|
||||
}
|
||||
|
||||
func (provider *AliyunCloudProvider) decodeClusterLabels(tags []*cs20151215.Tag) map[string]string {
|
||||
labels := map[string]string{}
|
||||
for _, tag := range tags {
|
||||
if tag != nil {
|
||||
labels[getString(tag.Key)] = getString(tag.Value)
|
||||
}
|
||||
}
|
||||
return labels
|
||||
}
|
||||
|
||||
func (provider *AliyunCloudProvider) decodeClusterURL(masterURL string) (url struct {
|
||||
APIServerEndpoint string `json:"api_server_endpoint"`
|
||||
IntranetAPIServerEndpoint string `json:"intranet_api_server_endpoint"`
|
||||
}) {
|
||||
if err := json.Unmarshal([]byte(masterURL), &url); err != nil {
|
||||
klog.Info("failed to unmarshal masterUrl %s", masterURL)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (provider *AliyunCloudProvider) getDashboardURL(clusterID string) string {
|
||||
return fmt.Sprintf("https://cs.console.aliyun.com/#/k8s/cluster/%s/v2/info/overview", clusterID)
|
||||
}
|
||||
|
||||
func getString(s *string) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
return *s
|
||||
}
|
||||
|
||||
// ListCloudClusters list clusters with page info, return clusters, total count and error
|
||||
func (provider *AliyunCloudProvider) ListCloudClusters(pageNumber int, pageSize int) ([]*CloudCluster, int, error) {
|
||||
describeClustersV1Request := &cs20151215.DescribeClustersV1Request{
|
||||
PageSize: pointer.Int64(int64(pageSize)),
|
||||
PageNumber: pointer.Int64(int64(pageNumber)),
|
||||
}
|
||||
resp, err := provider.DescribeClustersV1(describeClustersV1Request)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var clusters []*CloudCluster
|
||||
for _, cluster := range resp.Body.Clusters {
|
||||
if cluster == nil {
|
||||
continue
|
||||
}
|
||||
labels := provider.decodeClusterLabels(cluster.Tags)
|
||||
url := provider.decodeClusterURL(getString(cluster.MasterUrl))
|
||||
clusters = append(clusters, &CloudCluster{
|
||||
ID: getString(cluster.ClusterId),
|
||||
Name: getString(cluster.Name),
|
||||
Type: getString(cluster.ClusterType),
|
||||
Zone: getString(cluster.ZoneId),
|
||||
ZoneID: getString(cluster.ZoneId),
|
||||
RegionID: getString(cluster.RegionId),
|
||||
VpcID: getString(cluster.VpcId),
|
||||
Labels: labels,
|
||||
Status: getString(cluster.State),
|
||||
APIServerURL: url.APIServerEndpoint,
|
||||
DashBoardURL: provider.getDashboardURL(getString(cluster.ClusterId)),
|
||||
})
|
||||
}
|
||||
return clusters, int(*resp.Body.PageInfo.TotalCount), nil
|
||||
}
|
||||
|
||||
// GetClusterKubeConfig get cluster kubeconfig by clusterID
|
||||
func (provider *AliyunCloudProvider) GetClusterKubeConfig(clusterID string) (string, error) {
|
||||
req := &cs20151215.DescribeClusterUserKubeconfigRequest{}
|
||||
resp, err := provider.DescribeClusterUserKubeconfig(pointer.String(clusterID), req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return *resp.Body.Config, nil
|
||||
}
|
||||
|
||||
// GetClusterInfo retrieves cluster info by clusterID
|
||||
func (provider *AliyunCloudProvider) GetClusterInfo(clusterID string) (*CloudCluster, error) {
|
||||
resp, err := provider.DescribeClusterDetail(pointer.String(clusterID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cluster := resp.Body
|
||||
labels := provider.decodeClusterLabels(cluster.Tags)
|
||||
url := provider.decodeClusterURL(*cluster.MasterUrl)
|
||||
return &CloudCluster{
|
||||
Provider: ProviderAliyun,
|
||||
ID: *cluster.ClusterId,
|
||||
Name: *cluster.Name,
|
||||
Type: *cluster.ClusterType,
|
||||
Zone: *cluster.ZoneId,
|
||||
ZoneID: *cluster.ZoneId,
|
||||
RegionID: *cluster.RegionId,
|
||||
VpcID: *cluster.VpcId,
|
||||
Labels: labels,
|
||||
Status: *cluster.State,
|
||||
APIServerURL: url.APIServerEndpoint,
|
||||
DashBoardURL: provider.getDashboardURL(*cluster.ClusterId),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateCloudCluster create cloud cluster
|
||||
func (provider *AliyunCloudProvider) CreateCloudCluster(ctx context.Context, clusterName string, zone string, worker int, cpu int64, mem int64) (string, error) {
|
||||
name := GetCloudClusterFullName(ProviderAliyun, clusterName)
|
||||
ns := util.GetRuntimeNamespace()
|
||||
terraformProviderName, err := bootstrapTerraformProvider(ctx, provider.k8sClient, ns, ProviderAliyun, "alibaba", provider.accessKeyID, provider.accessKeySecret, "cn-hongkong")
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to bootstrap terraform provider")
|
||||
}
|
||||
properties := map[string]interface{}{
|
||||
"k8s_name_prefix": clusterName,
|
||||
}
|
||||
if zone != "" {
|
||||
properties["zone_id"] = zone
|
||||
}
|
||||
if cpu != 0 {
|
||||
properties["cpu_core_count"] = cpu
|
||||
}
|
||||
if mem != 0 {
|
||||
properties["memory_size"] = mem
|
||||
}
|
||||
if worker != 0 {
|
||||
properties["k8s_worker_number"] = worker
|
||||
}
|
||||
bs, err := json.Marshal(properties)
|
||||
if err != nil {
|
||||
return name, errors.Wrapf(err, "failed to marshal cloud cluster app properties")
|
||||
}
|
||||
|
||||
cfg := v1beta12.Configuration{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
Labels: map[string]string{
|
||||
CloudClusterCreatorLabelKey: ProviderAliyun,
|
||||
},
|
||||
},
|
||||
Spec: v1beta12.ConfigurationSpec{
|
||||
ProviderReference: &types.Reference{
|
||||
Name: terraformProviderName,
|
||||
Namespace: ns,
|
||||
},
|
||||
Remote: "https://github.com/kubevela-contrib/terraform-modules.git",
|
||||
Variable: &runtime.RawExtension{Raw: bs},
|
||||
},
|
||||
}
|
||||
cfg.Spec.Path = "alibaba/cs/dedicated-kubernetes"
|
||||
cfg.Spec.WriteConnectionSecretToReference = &types.SecretReference{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
}
|
||||
|
||||
if err = provider.k8sClient.Create(ctx, &cfg); err != nil {
|
||||
return name, errors.Wrapf(err, "failed to create cloud cluster terraform configuration")
|
||||
}
|
||||
|
||||
return name, nil
|
||||
}
|
||||
@@ -1,48 +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 cloudprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
const (
|
||||
// CloudClusterCreatorLabelKey labels the creator of cloud cluster
|
||||
CloudClusterCreatorLabelKey = "api.core.oam.dev/cloud-cluster-creator"
|
||||
)
|
||||
|
||||
// CloudClusterProvider abstracts the cloud provider to provide cluster access
|
||||
type CloudClusterProvider interface {
|
||||
IsInvalidKey(err error) bool
|
||||
ListCloudClusters(pageNumber int, pageSize int) ([]*CloudCluster, int, error)
|
||||
GetClusterKubeConfig(clusterID string) (string, error)
|
||||
GetClusterInfo(clusterID string) (*CloudCluster, error)
|
||||
CreateCloudCluster(ctx context.Context, clusterName string, zone string, worker int, cpu int64, mem int64) (string, error)
|
||||
}
|
||||
|
||||
// GetClusterProvider creates interface for getting cloud cluster provider
|
||||
func GetClusterProvider(provider string, accessKeyID string, accessKeySecret string, k8sClient client.Client) (CloudClusterProvider, error) {
|
||||
switch provider {
|
||||
case ProviderAliyun:
|
||||
return NewAliyunCloudProvider(accessKeyID, accessKeySecret, k8sClient)
|
||||
default:
|
||||
return nil, errors.Errorf("cluster provider %s is not implemented", provider)
|
||||
}
|
||||
}
|
||||
@@ -1,94 +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 cloudprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
types "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
|
||||
v1beta12 "github.com/oam-dev/terraform-controller/api/v1beta1"
|
||||
"github.com/pkg/errors"
|
||||
v12 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
func computeProviderHashKey(provider string, accessKeyID string, accessKeySecret string) string {
|
||||
return fmt.Sprintf("%x", sha256.Sum256([]byte(strings.Join([]string{provider, accessKeyID, accessKeySecret}, "::"))))[:8] // #nosec
|
||||
}
|
||||
|
||||
// GetCloudClusterFullName construct the full name of cloud cluster which will be used as the name of terraform configuration
|
||||
func GetCloudClusterFullName(provider string, clusterName string) string {
|
||||
return fmt.Sprintf("cloud-cluster-%s-%s", provider, clusterName)
|
||||
}
|
||||
|
||||
func bootstrapTerraformProvider(ctx context.Context, k8sClient client.Client, ns string, provider string, tfProvider string, accessKeyID string, accessKeySecret string, region string) (string, error) {
|
||||
hashKey := computeProviderHashKey(provider, accessKeyID, accessKeySecret)
|
||||
secretName := fmt.Sprintf("tf-provider-cred-%s-%s", provider, hashKey)
|
||||
terraformProviderName := fmt.Sprintf("tf-provider-%s-%s", provider, hashKey)
|
||||
secret := v12.Secret{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: ns,
|
||||
},
|
||||
StringData: map[string]string{"credentials": fmt.Sprintf("accessKeyID: %s\naccessKeySecret: %s\nsecurityToken:\n", accessKeyID, accessKeySecret)},
|
||||
Type: v12.SecretTypeOpaque,
|
||||
}
|
||||
var err error
|
||||
if err = k8sClient.Get(ctx, client.ObjectKeyFromObject(&secret), &v12.Secret{}); err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
err = k8sClient.Create(ctx, &secret)
|
||||
}
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to upsert terraform provider secret")
|
||||
}
|
||||
}
|
||||
|
||||
terraformProvider := v1beta12.Provider{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: terraformProviderName,
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: v1beta12.ProviderSpec{
|
||||
Credentials: v1beta12.ProviderCredentials{
|
||||
SecretRef: &types.SecretKeySelector{
|
||||
Key: "credentials",
|
||||
SecretReference: types.SecretReference{
|
||||
Name: secretName,
|
||||
Namespace: ns,
|
||||
},
|
||||
},
|
||||
Source: types.CredentialsSourceSecret,
|
||||
},
|
||||
Provider: tfProvider,
|
||||
Region: region,
|
||||
},
|
||||
}
|
||||
if err = k8sClient.Get(ctx, client.ObjectKeyFromObject(&terraformProvider), &v1beta12.Provider{}); err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
err = k8sClient.Create(ctx, &terraformProvider)
|
||||
}
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to upsert terraform provider")
|
||||
}
|
||||
}
|
||||
return terraformProviderName, nil
|
||||
}
|
||||
@@ -1,38 +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 cloudprovider
|
||||
|
||||
const (
|
||||
// ProviderAliyun cloud provider aliyun
|
||||
ProviderAliyun = "aliyun"
|
||||
)
|
||||
|
||||
// CloudCluster describes the interface that cloud provider should return
|
||||
type CloudCluster struct {
|
||||
Provider string `json:"provider"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Zone string `json:"zone"`
|
||||
ZoneID string `json:"zoneID"`
|
||||
RegionID string `json:"regionID"`
|
||||
VpcID string `json:"vpcID"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
Status string `json:"status"`
|
||||
APIServerURL string `json:"apiServerURL"`
|
||||
DashBoardURL string `json:"dashboardURL"`
|
||||
}
|
||||
@@ -1,26 +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 common
|
||||
|
||||
// error msg for common usage
|
||||
const (
|
||||
ErrLocatingWorkload = "failed to locate the workload"
|
||||
ErrLocatingService = "failed to locate any the services"
|
||||
ErrCreatingService = "failed to create the services"
|
||||
|
||||
ErrUpdateStatus = "failed to update status"
|
||||
)
|
||||
@@ -1,386 +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 rollout
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
kruisev1 "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/common"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/common/rollout/workloads"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
// the default time to check back if we still have work to do
|
||||
const rolloutReconcileRequeueTime = 5 * time.Second
|
||||
|
||||
// Controller is the controller that controls the rollout plan resource
|
||||
type Controller struct {
|
||||
client client.Client
|
||||
recorder event.Recorder
|
||||
parentController oam.Object
|
||||
|
||||
rolloutSpec *v1alpha1.RolloutPlan
|
||||
rolloutStatus *v1alpha1.RolloutStatus
|
||||
|
||||
targetWorkload *unstructured.Unstructured
|
||||
sourceWorkload *unstructured.Unstructured
|
||||
}
|
||||
|
||||
// NewRolloutPlanController creates a RolloutPlanController
|
||||
func NewRolloutPlanController(client client.Client, parentController oam.Object, recorder event.Recorder,
|
||||
rolloutSpec *v1alpha1.RolloutPlan, rolloutStatus *v1alpha1.RolloutStatus,
|
||||
targetWorkload, sourceWorkload *unstructured.Unstructured) *Controller {
|
||||
initializedRolloutStatus := rolloutStatus.DeepCopy()
|
||||
if len(initializedRolloutStatus.BatchRollingState) == 0 {
|
||||
initializedRolloutStatus.BatchRollingState = v1alpha1.BatchInitializingState
|
||||
}
|
||||
return &Controller{
|
||||
client: client,
|
||||
parentController: parentController,
|
||||
recorder: recorder,
|
||||
rolloutSpec: rolloutSpec.DeepCopy(),
|
||||
rolloutStatus: initializedRolloutStatus,
|
||||
targetWorkload: targetWorkload,
|
||||
sourceWorkload: sourceWorkload,
|
||||
}
|
||||
}
|
||||
|
||||
// Reconcile reconciles a rollout plan
|
||||
func (r *Controller) Reconcile(ctx context.Context) (res reconcile.Result, status *v1alpha1.RolloutStatus) {
|
||||
klog.InfoS("Reconcile the rollout plan", "rollout status", r.rolloutStatus,
|
||||
"target workload", klog.KObj(r.targetWorkload))
|
||||
if r.sourceWorkload != nil {
|
||||
klog.InfoS("We will do rolling upgrades", "source workload", klog.KObj(r.sourceWorkload))
|
||||
}
|
||||
klog.InfoS("rollout status", "rollout state", r.rolloutStatus.RollingState, "batch rolling state",
|
||||
r.rolloutStatus.BatchRollingState, "current batch", r.rolloutStatus.CurrentBatch, "upgraded Replicas",
|
||||
r.rolloutStatus.UpgradedReplicas, "ready Replicas", r.rolloutStatus.UpgradedReadyReplicas)
|
||||
|
||||
defer func() {
|
||||
klog.InfoS("Finished one round of reconciling rollout plan", "rollout state", status.RollingState,
|
||||
"batch rolling state", status.BatchRollingState, "current batch", status.CurrentBatch,
|
||||
"upgraded Replicas", status.UpgradedReplicas, "ready Replicas", status.UpgradedReadyReplicas,
|
||||
"reconcile result ", res)
|
||||
}()
|
||||
status = r.rolloutStatus
|
||||
|
||||
defer func() {
|
||||
if status.RollingState == v1alpha1.RolloutFailedState ||
|
||||
status.RollingState == v1alpha1.RolloutSucceedState {
|
||||
// no need to requeue if we reach the terminal states
|
||||
res = reconcile.Result{}
|
||||
} else {
|
||||
res = reconcile.Result{
|
||||
RequeueAfter: rolloutReconcileRequeueTime,
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
workloadController, err := r.GetWorkloadController()
|
||||
if err != nil {
|
||||
r.rolloutStatus.RolloutFailed(err.Error())
|
||||
r.recorder.Event(r.parentController, event.Warning("Unsupported workload", err))
|
||||
return
|
||||
}
|
||||
|
||||
switch r.rolloutStatus.RollingState {
|
||||
case v1alpha1.VerifyingSpecState:
|
||||
verified, err := workloadController.VerifySpec(ctx)
|
||||
if err != nil {
|
||||
// we can fail it right away, everything after initialized need to be finalized
|
||||
r.rolloutStatus.RolloutFailed(err.Error())
|
||||
} else if verified {
|
||||
r.rolloutStatus.StateTransition(v1alpha1.RollingSpecVerifiedEvent)
|
||||
}
|
||||
|
||||
case v1alpha1.InitializingState:
|
||||
if err = r.initializeRollout(ctx); err == nil {
|
||||
initialized, err := workloadController.Initialize(ctx)
|
||||
if err != nil {
|
||||
r.rolloutStatus.RolloutFailing(err.Error())
|
||||
} else if initialized {
|
||||
r.rolloutStatus.StateTransition(v1alpha1.RollingInitializedEvent)
|
||||
}
|
||||
}
|
||||
|
||||
case v1alpha1.RollingInBatchesState:
|
||||
r.reconcileBatchInRolling(ctx, workloadController)
|
||||
|
||||
case v1alpha1.RolloutFailingState, v1alpha1.RolloutAbandoningState, v1alpha1.RolloutDeletingState:
|
||||
if succeed := workloadController.Finalize(ctx, false); succeed {
|
||||
r.finalizeRollout(ctx)
|
||||
}
|
||||
|
||||
case v1alpha1.FinalisingState:
|
||||
if succeed := workloadController.Finalize(ctx, true); succeed {
|
||||
r.finalizeRollout(ctx)
|
||||
}
|
||||
|
||||
case v1alpha1.RolloutSucceedState:
|
||||
// Nothing to do
|
||||
|
||||
case v1alpha1.RolloutFailedState:
|
||||
// Nothing to do
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("illegal rollout status %+v", r.rolloutStatus))
|
||||
}
|
||||
|
||||
return res, r.rolloutStatus
|
||||
}
|
||||
|
||||
// reconcile logic when we are in the middle of rollout, we have to go through finalizing state before succeed or fail
|
||||
func (r *Controller) reconcileBatchInRolling(ctx context.Context, workloadController workloads.WorkloadController) {
|
||||
if r.rolloutSpec.Paused {
|
||||
r.recorder.Event(r.parentController, event.Normal("Rollout paused", "Rollout paused"))
|
||||
r.rolloutStatus.SetConditions(v1alpha1.NewPositiveCondition(v1alpha1.BatchPaused))
|
||||
return
|
||||
}
|
||||
|
||||
switch r.rolloutStatus.BatchRollingState {
|
||||
case v1alpha1.BatchInitializingState:
|
||||
r.initializeOneBatch(ctx)
|
||||
|
||||
case v1alpha1.BatchInRollingState:
|
||||
// still rolling the batch, the batch rolling is not completed yet
|
||||
upgradeDone, err := workloadController.RolloutOneBatchPods(ctx)
|
||||
if err != nil {
|
||||
r.rolloutStatus.RolloutFailing(err.Error())
|
||||
} else if upgradeDone {
|
||||
r.rolloutStatus.StateTransition(v1alpha1.RolloutOneBatchEvent)
|
||||
}
|
||||
|
||||
case v1alpha1.BatchVerifyingState:
|
||||
// verifying if the application is ready to roll
|
||||
// need to check if they meet the availability requirements in the rollout spec.
|
||||
// TODO: evaluate any metrics/analysis
|
||||
// TODO: We may need to go back to rollout again if the size of the resource can change behind our back
|
||||
verified, err := workloadController.CheckOneBatchPods(ctx)
|
||||
if err != nil {
|
||||
r.rolloutStatus.RolloutFailing(err.Error())
|
||||
} else if verified {
|
||||
r.rolloutStatus.StateTransition(v1alpha1.OneBatchAvailableEvent)
|
||||
}
|
||||
|
||||
case v1alpha1.BatchFinalizingState:
|
||||
// finalize one batch
|
||||
finalized, err := workloadController.FinalizeOneBatch(ctx)
|
||||
if err != nil {
|
||||
r.rolloutStatus.RolloutFailing(err.Error())
|
||||
} else if finalized {
|
||||
r.finalizeOneBatch(ctx)
|
||||
}
|
||||
|
||||
case v1alpha1.BatchReadyState:
|
||||
// all the pods in the are upgraded and their state are ready
|
||||
// wait to move to the next batch if there are any
|
||||
r.tryMovingToNextBatch()
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("illegal status %+v", r.rolloutStatus))
|
||||
}
|
||||
}
|
||||
|
||||
// all the common initialize work before we rollout
|
||||
// TODO: fail the rollout if the webhook call is explicitly rejected (through http status code)
|
||||
func (r *Controller) initializeRollout(ctx context.Context) error {
|
||||
// call the pre-rollout webhooks
|
||||
for _, rw := range r.rolloutSpec.RolloutWebhooks {
|
||||
if rw.Type == v1alpha1.InitializeRolloutHook {
|
||||
err := callWebhook(ctx, r.parentController, string(v1alpha1.InitializingState), rw)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "failed to invoke a webhook",
|
||||
"webhook name", rw.Name, "webhook end point", rw.URL)
|
||||
r.rolloutStatus.RolloutRetry("failed to invoke a webhook")
|
||||
return err
|
||||
}
|
||||
klog.InfoS("successfully invoked a pre rollout webhook", "webhook name", rw.Name, "webhook end point",
|
||||
rw.URL)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// all the common initialize work before we rollout one batch of resources
|
||||
func (r *Controller) initializeOneBatch(ctx context.Context) {
|
||||
rolloutHooks := r.gatherAllWebhooks()
|
||||
// call all the pre-batch rollout webhooks
|
||||
for _, rh := range rolloutHooks {
|
||||
if rh.Type == v1alpha1.PreBatchRolloutHook {
|
||||
err := callWebhook(ctx, r.parentController, string(v1alpha1.BatchInitializingState), rh)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "failed to invoke a webhook",
|
||||
"webhook name", rh.Name, "webhook end point", rh.URL)
|
||||
r.rolloutStatus.RolloutRetry("failed to invoke a webhook")
|
||||
return
|
||||
}
|
||||
klog.InfoS("successfully invoked a pre batch webhook", "webhook name", rh.Name, "webhook end point",
|
||||
rh.URL)
|
||||
}
|
||||
}
|
||||
r.rolloutStatus.StateTransition(v1alpha1.InitializedOneBatchEvent)
|
||||
}
|
||||
|
||||
func (r *Controller) gatherAllWebhooks() []v1alpha1.RolloutWebhook {
|
||||
// we go through the rollout level webhooks first
|
||||
rolloutHooks := r.rolloutSpec.RolloutWebhooks
|
||||
// we then append the batch specific rollout webhooks to the overall webhooks
|
||||
// order matters here
|
||||
currentBatch := int(r.rolloutStatus.CurrentBatch)
|
||||
rolloutHooks = append(rolloutHooks, r.rolloutSpec.RolloutBatches[currentBatch].BatchRolloutWebhooks...)
|
||||
return rolloutHooks
|
||||
}
|
||||
|
||||
// check if we can move to the next batch
|
||||
func (r *Controller) tryMovingToNextBatch() {
|
||||
if r.rolloutSpec.BatchPartition == nil || *r.rolloutSpec.BatchPartition > r.rolloutStatus.CurrentBatch {
|
||||
klog.InfoS("ready to rollout the next batch", "current batch", r.rolloutStatus.CurrentBatch)
|
||||
r.rolloutStatus.StateTransition(v1alpha1.BatchRolloutApprovedEvent)
|
||||
} else {
|
||||
klog.V(common.LogDebug).InfoS("the current batch is waiting to move on", "current batch",
|
||||
r.rolloutStatus.CurrentBatch)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Controller) finalizeOneBatch(ctx context.Context) {
|
||||
rolloutHooks := r.gatherAllWebhooks()
|
||||
// call all the post-batch rollout webhooks
|
||||
for _, rh := range rolloutHooks {
|
||||
if rh.Type == v1alpha1.PostBatchRolloutHook {
|
||||
err := callWebhook(ctx, r.parentController, string(v1alpha1.BatchFinalizingState), rh)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "failed to invoke a webhook",
|
||||
"webhook name", rh.Name, "webhook end point", rh.URL)
|
||||
r.rolloutStatus.RolloutRetry("failed to invoke a webhook")
|
||||
return
|
||||
}
|
||||
klog.InfoS("successfully invoked a post batch webhook", "webhook name", rh.Name, "webhook end point",
|
||||
rh.URL)
|
||||
}
|
||||
}
|
||||
// calculate the next phase
|
||||
currentBatch := int(r.rolloutStatus.CurrentBatch)
|
||||
if currentBatch == len(r.rolloutSpec.RolloutBatches)-1 {
|
||||
// this is the last batch, mark the rollout finalized
|
||||
r.rolloutStatus.StateTransition(v1alpha1.AllBatchFinishedEvent)
|
||||
r.recorder.Event(r.parentController, event.Normal("All batches rolled out",
|
||||
fmt.Sprintf("upgrade pod = %d, total ready pod = %d", r.rolloutStatus.UpgradedReplicas,
|
||||
r.rolloutStatus.UpgradedReadyReplicas)))
|
||||
} else {
|
||||
klog.InfoS("finished one batch rollout", "current batch", r.rolloutStatus.CurrentBatch)
|
||||
// th
|
||||
r.recorder.Event(r.parentController, event.Normal("Batch Finalized",
|
||||
fmt.Sprintf("Batch %d is finalized and ready to go", r.rolloutStatus.CurrentBatch)))
|
||||
r.rolloutStatus.StateTransition(v1alpha1.FinishedOneBatchEvent)
|
||||
}
|
||||
}
|
||||
|
||||
// all the common finalize work after we rollout
|
||||
func (r *Controller) finalizeRollout(ctx context.Context) {
|
||||
// call the post-rollout webhooks
|
||||
for _, rw := range r.rolloutSpec.RolloutWebhooks {
|
||||
if rw.Type == v1alpha1.FinalizeRolloutHook {
|
||||
err := callWebhook(ctx, r.parentController, string(r.rolloutStatus.RollingState), rw)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "failed to invoke a webhook",
|
||||
"webhook name", rw.Name, "webhook end point", rw.URL)
|
||||
r.rolloutStatus.RolloutRetry("failed to invoke a post rollout webhook")
|
||||
return
|
||||
}
|
||||
klog.InfoS("successfully invoked a post rollout webhook", "webhook name", rw.Name, "webhook end point",
|
||||
rw.URL)
|
||||
}
|
||||
}
|
||||
r.rolloutStatus.StateTransition(v1alpha1.RollingFinalizedEvent)
|
||||
}
|
||||
|
||||
// GetWorkloadController pick the right workload controller to work on the workload
|
||||
func (r *Controller) GetWorkloadController() (workloads.WorkloadController, error) {
|
||||
kind := r.targetWorkload.GetObjectKind().GroupVersionKind().Kind
|
||||
target := types.NamespacedName{
|
||||
Namespace: r.targetWorkload.GetNamespace(),
|
||||
Name: r.targetWorkload.GetName(),
|
||||
}
|
||||
var source types.NamespacedName
|
||||
if r.sourceWorkload != nil {
|
||||
source.Namespace = r.sourceWorkload.GetNamespace()
|
||||
source.Name = r.sourceWorkload.GetName()
|
||||
}
|
||||
|
||||
if r.targetWorkload.GroupVersionKind().Group == kruisev1.GroupVersion.Group {
|
||||
// check if the target workload is CloneSet
|
||||
if r.targetWorkload.GetKind() == reflect.TypeOf(kruisev1.CloneSet{}).Name() {
|
||||
// check whether current rollout plan is for workload rolling or scaling
|
||||
if r.sourceWorkload != nil {
|
||||
klog.InfoS("using cloneset rollout controller for this rolloutplan", "source workload name", source.Name, "namespace",
|
||||
source.Namespace, "target workload name", target.Name, "namespace",
|
||||
target.Namespace)
|
||||
return workloads.NewCloneSetRolloutController(r.client, r.recorder, r.parentController,
|
||||
r.rolloutSpec, r.rolloutStatus, target), nil
|
||||
}
|
||||
klog.InfoS("using cloneset scale controller for this rolloutplan", "target workload name", target.Name, "namespace",
|
||||
target.Namespace)
|
||||
return workloads.NewCloneSetScaleController(r.client, r.recorder, r.parentController,
|
||||
r.rolloutSpec, r.rolloutStatus, target), nil
|
||||
}
|
||||
}
|
||||
|
||||
if r.targetWorkload.GroupVersionKind().Group == apps.GroupName {
|
||||
// check if the target workload is Deployment
|
||||
if r.targetWorkload.GetKind() == reflect.TypeOf(apps.Deployment{}).Name() {
|
||||
// check whether current rollout plan is for workload rolling or scaling
|
||||
if r.sourceWorkload != nil {
|
||||
klog.InfoS("using deployment rollout controller for this rolloutplan", "source workload name", source.Name, "namespace",
|
||||
source.Namespace, "target workload name", target.Name, "namespace",
|
||||
target.Namespace)
|
||||
return workloads.NewDeploymentRolloutController(r.client, r.recorder, r.parentController,
|
||||
r.rolloutSpec, r.rolloutStatus, source, target), nil
|
||||
}
|
||||
klog.InfoS("using deployment scale controller for this rolloutplan", "target workload name", target.Name, "namespace",
|
||||
target.Namespace)
|
||||
return workloads.NewDeploymentScaleController(r.client, r.recorder, r.parentController,
|
||||
r.rolloutSpec, r.rolloutStatus, target), nil
|
||||
}
|
||||
|
||||
// check if the target workload is StatefulSet
|
||||
if r.targetWorkload.GetKind() == reflect.TypeOf(apps.StatefulSet{}).Name() {
|
||||
// check whether current rollout plan is for workload rolling or scaling
|
||||
if r.sourceWorkload != nil {
|
||||
return workloads.NewStatefulSetRolloutController(r.client, r.recorder, r.parentController,
|
||||
r.rolloutSpec, r.rolloutStatus, target), nil
|
||||
}
|
||||
return workloads.NewStatefulSetScaleController(r.client, r.recorder, r.parentController,
|
||||
r.rolloutSpec, r.rolloutStatus, target), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("the workload kind `%s` is not supported", kind)
|
||||
}
|
||||
@@ -1,65 +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 rollout
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
func Test_TryMovingToNextBatch(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
r Controller
|
||||
rolloutSpec *v1alpha1.RolloutPlan
|
||||
rolloutStatus *v1alpha1.RolloutStatus
|
||||
wantNextBatch int32
|
||||
wantBatchRollingState v1alpha1.BatchRollingState
|
||||
}{
|
||||
"stay at the same batch": {
|
||||
rolloutSpec: &v1alpha1.RolloutPlan{
|
||||
BatchPartition: pointer.Int32(3),
|
||||
},
|
||||
rolloutStatus: &v1alpha1.RolloutStatus{
|
||||
CurrentBatch: 2,
|
||||
RollingState: v1alpha1.RollingInBatchesState,
|
||||
BatchRollingState: v1alpha1.BatchReadyState,
|
||||
},
|
||||
wantNextBatch: 3,
|
||||
wantBatchRollingState: v1alpha1.BatchInitializingState,
|
||||
},
|
||||
}
|
||||
for name, tt := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r := &Controller{
|
||||
rolloutSpec: tt.rolloutSpec,
|
||||
rolloutStatus: tt.rolloutStatus,
|
||||
}
|
||||
r.tryMovingToNextBatch()
|
||||
if r.rolloutStatus.CurrentBatch != tt.wantNextBatch {
|
||||
t.Errorf("\n%s\n batch miss match: want batch `%d`, got batch:`%d`\n", name,
|
||||
tt.wantNextBatch, r.rolloutStatus.CurrentBatch)
|
||||
}
|
||||
if r.rolloutStatus.BatchRollingState != tt.wantBatchRollingState {
|
||||
t.Errorf("\n%s\nstate miss match: want state `%s`, got state:`%s`\n", name,
|
||||
tt.wantBatchRollingState, r.rolloutStatus.BatchRollingState)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,131 +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 rollout
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
// issue an http call to the an end ponit
|
||||
func makeHTTPRequest(ctx context.Context, webhookEndPoint, method string, payload interface{}) ([]byte, int, error) {
|
||||
payloadBin, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return nil, http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
hook, err := url.Parse(webhookEndPoint)
|
||||
if err != nil {
|
||||
return nil, http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(context.Background(), method, hook.String(), bytes.NewBuffer(payloadBin))
|
||||
if err != nil {
|
||||
return nil, http.StatusInternalServerError, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// issue request with retry
|
||||
var r *http.Response
|
||||
var body []byte
|
||||
err = retry.OnError(retry.DefaultBackoff,
|
||||
func(error) bool {
|
||||
// not sure what not to retry on
|
||||
return true
|
||||
}, func() error {
|
||||
var requestErr error
|
||||
r, requestErr = http.DefaultClient.Do(req.WithContext(ctx))
|
||||
defer func() {
|
||||
if r != nil {
|
||||
_ = r.Body.Close()
|
||||
}
|
||||
}()
|
||||
if requestErr != nil {
|
||||
return requestErr
|
||||
}
|
||||
body, requestErr = io.ReadAll(r.Body)
|
||||
if requestErr != nil {
|
||||
return requestErr
|
||||
}
|
||||
if r.StatusCode >= http.StatusInternalServerError {
|
||||
requestErr = fmt.Errorf("internal server error, status code = %d", r.StatusCode)
|
||||
}
|
||||
return requestErr
|
||||
})
|
||||
|
||||
// failed even with retry
|
||||
if err != nil {
|
||||
if r != nil {
|
||||
return nil, r.StatusCode, err
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
return body, r.StatusCode, nil
|
||||
}
|
||||
|
||||
// callWebhook does a HTTP POST to an external service and
|
||||
// returns an error if the response status code is non-2xx
|
||||
func callWebhook(ctx context.Context, resource klog.KMetadata, phase string, rw v1alpha1.RolloutWebhook) error {
|
||||
payload := v1alpha1.RolloutWebhookPayload{
|
||||
Name: resource.GetName(),
|
||||
Namespace: resource.GetNamespace(),
|
||||
Phase: phase,
|
||||
}
|
||||
|
||||
if rw.Metadata != nil {
|
||||
payload.Metadata = *rw.Metadata
|
||||
}
|
||||
// make the http request
|
||||
if len(rw.Method) == 0 {
|
||||
rw.Method = http.MethodPost
|
||||
}
|
||||
_, status, err := makeHTTPRequest(ctx, rw.URL, rw.Method, payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(rw.ExpectedStatus) == 0 {
|
||||
if status > http.StatusAccepted {
|
||||
err := fmt.Errorf("we fail the webhook request based on status, http status = %d", status)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// check if the returned status is expected
|
||||
accepted := false
|
||||
for _, es := range rw.ExpectedStatus {
|
||||
if es == status {
|
||||
accepted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !accepted {
|
||||
err := fmt.Errorf("http request to the webhook not accepeted, http status = %d", status)
|
||||
klog.ErrorS(err, "The status is not expected", "expected status", rw.ExpectedStatus)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,246 +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 rollout
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
const mockUrlBase = "127.0.0.1:"
|
||||
|
||||
func TestMakeHTTPRequest(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
type mockHTTPParameter struct {
|
||||
method string
|
||||
statusCode int
|
||||
body string
|
||||
}
|
||||
type want struct {
|
||||
err error
|
||||
statusCode int
|
||||
body string
|
||||
}
|
||||
tests := map[string]struct {
|
||||
url string
|
||||
method string
|
||||
payload interface{}
|
||||
httpParameter mockHTTPParameter
|
||||
want want
|
||||
}{
|
||||
"Test normal case": {
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodPost,
|
||||
statusCode: http.StatusAccepted,
|
||||
body: "all good",
|
||||
},
|
||||
want: want{
|
||||
err: nil,
|
||||
statusCode: http.StatusAccepted,
|
||||
body: "all good",
|
||||
},
|
||||
},
|
||||
"Test http failed case with retry": {
|
||||
url: "127.0.0.1:13622",
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodGet,
|
||||
statusCode: http.StatusAccepted,
|
||||
body: "doesn't matter",
|
||||
},
|
||||
want: want{
|
||||
err: fmt.Errorf("internal server error, status code = %d", http.StatusNotImplemented),
|
||||
statusCode: -1,
|
||||
body: "",
|
||||
},
|
||||
},
|
||||
"Test failed case with retry": {
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodPost,
|
||||
statusCode: http.StatusNotImplemented,
|
||||
body: "please retry",
|
||||
},
|
||||
want: want{
|
||||
err: fmt.Errorf("internal server error, status code = %d", http.StatusNotImplemented),
|
||||
statusCode: http.StatusNotImplemented,
|
||||
body: "",
|
||||
},
|
||||
},
|
||||
"Test client error failed case": {
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodPost,
|
||||
statusCode: http.StatusBadRequest,
|
||||
body: "bad request",
|
||||
},
|
||||
want: want{
|
||||
err: nil,
|
||||
statusCode: http.StatusBadRequest,
|
||||
body: "bad request",
|
||||
},
|
||||
},
|
||||
}
|
||||
for testName, tt := range tests {
|
||||
func(testName string) {
|
||||
mockUrl := mockUrlBase + strconv.FormatInt(rand.Int63n(128)+2000, 10)
|
||||
// generate a test server so we can capture and inspect the request
|
||||
testServer := NewMock(tt.httpParameter.method, mockUrl, tt.httpParameter.statusCode, tt.httpParameter.body)
|
||||
defer testServer.Close()
|
||||
if len(tt.url) == 0 {
|
||||
tt.url = mockUrl
|
||||
}
|
||||
gotReply, gotCode, gotErr := makeHTTPRequest(ctx, "http://"+tt.url, tt.method, tt.payload)
|
||||
if gotCode != tt.want.statusCode {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want code `%d`, got code:`%d` got err: %v \n", testName, tt.want.statusCode,
|
||||
gotCode, gotErr)
|
||||
}
|
||||
if gotCode == -1 {
|
||||
// we don't know exactly what error we should get when the network call failed
|
||||
if gotErr == nil {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want some error, got error:`%s`\n", testName, gotErr)
|
||||
}
|
||||
} else {
|
||||
if (tt.want.err == nil && gotErr != nil) || (tt.want.err != nil && gotErr == nil) {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", testName, tt.want.err, gotErr)
|
||||
}
|
||||
if tt.want.err != nil && gotErr != nil && gotErr.Error() != tt.want.err.Error() {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", testName, tt.want.err, gotErr)
|
||||
}
|
||||
}
|
||||
if string(gotReply) != tt.want.body {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want reply `%s`, got reply:`%s`\n", testName, tt.want.body, string(gotReply))
|
||||
}
|
||||
}(testName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallWebhook(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
body := "all good"
|
||||
res := appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "name",
|
||||
Namespace: "namespace",
|
||||
},
|
||||
}
|
||||
type args struct {
|
||||
resource oam.Object
|
||||
phase string
|
||||
rw v1alpha1.RolloutWebhook
|
||||
}
|
||||
tests := map[string]struct {
|
||||
returnedStatusCode int
|
||||
args args
|
||||
wantErr error
|
||||
}{
|
||||
"Test success case": {
|
||||
returnedStatusCode: http.StatusAccepted,
|
||||
args: args{
|
||||
resource: &res,
|
||||
phase: string(v1alpha1.RollingInBatchesState),
|
||||
rw: v1alpha1.RolloutWebhook{},
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
"Test failed default case": {
|
||||
returnedStatusCode: http.StatusAlreadyReported,
|
||||
args: args{
|
||||
resource: &res,
|
||||
phase: string(v1alpha1.RollingInBatchesState),
|
||||
rw: v1alpha1.RolloutWebhook{},
|
||||
},
|
||||
wantErr: fmt.Errorf("we fail the webhook request based on status, http status = %d", http.StatusAlreadyReported),
|
||||
},
|
||||
"Test expected treated as success case": {
|
||||
returnedStatusCode: http.StatusAlreadyReported,
|
||||
args: args{
|
||||
resource: &res,
|
||||
phase: string(v1alpha1.RollingInBatchesState),
|
||||
rw: v1alpha1.RolloutWebhook{
|
||||
ExpectedStatus: []int{http.StatusNoContent, http.StatusAlreadyReported},
|
||||
},
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
"Test not expected treated as failed case": {
|
||||
returnedStatusCode: http.StatusGone,
|
||||
args: args{
|
||||
resource: &res,
|
||||
phase: string(v1alpha1.RolloutFailedState),
|
||||
rw: v1alpha1.RolloutWebhook{
|
||||
ExpectedStatus: []int{http.StatusNoContent, http.StatusAlreadyReported},
|
||||
},
|
||||
},
|
||||
wantErr: fmt.Errorf("http request to the webhook not accepeted, http status = %d", http.StatusGone),
|
||||
},
|
||||
}
|
||||
for name, tt := range tests {
|
||||
func(name string) {
|
||||
url := mockUrlBase + strconv.FormatInt(rand.Int63n(4848)+2000, 10)
|
||||
tt.args.rw.URL = "http://" + url
|
||||
// generate a test server so we can capture and inspect the request
|
||||
testServer := NewMock(http.MethodPost, url, tt.returnedStatusCode, body)
|
||||
defer testServer.Close()
|
||||
|
||||
gotErr := callWebhook(ctx, tt.args.resource, tt.args.phase, tt.args.rw)
|
||||
if (tt.wantErr == nil && gotErr != nil) || (tt.wantErr != nil && gotErr == nil) {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", name, tt.wantErr, gotErr)
|
||||
}
|
||||
if tt.wantErr != nil && gotErr != nil && gotErr.Error() != tt.wantErr.Error() {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", name, tt.wantErr, gotErr)
|
||||
}
|
||||
}(name)
|
||||
}
|
||||
}
|
||||
|
||||
func NewMock(method, mockUrl string, statusCode int, body string) *httptest.Server {
|
||||
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if req.Method == method {
|
||||
w.WriteHeader(statusCode)
|
||||
w.Write([]byte(body))
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
}))
|
||||
l, err := net.Listen("tcp", mockUrl)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ts.Listener.Close()
|
||||
ts.Listener = l
|
||||
ts.Start()
|
||||
return ts
|
||||
}
|
||||
@@ -1,322 +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 workloads
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
// CloneSetRolloutController is responsible for handle rollout Cloneset type of workloads
|
||||
type CloneSetRolloutController struct {
|
||||
cloneSetController
|
||||
}
|
||||
|
||||
// NewCloneSetRolloutController creates a new Cloneset rollout controller
|
||||
func NewCloneSetRolloutController(client client.Client, recorder event.Recorder, parentController oam.Object,
|
||||
rolloutSpec *v1alpha1.RolloutPlan, rolloutStatus *v1alpha1.RolloutStatus, workloadName types.NamespacedName) *CloneSetRolloutController {
|
||||
return &CloneSetRolloutController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
client: client,
|
||||
recorder: recorder,
|
||||
parentController: parentController,
|
||||
rolloutSpec: rolloutSpec,
|
||||
rolloutStatus: rolloutStatus,
|
||||
},
|
||||
targetNamespacedName: workloadName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VerifySpec verifies that the target rollout resource is consistent with the rollout spec
|
||||
func (c *CloneSetRolloutController) VerifySpec(ctx context.Context) (bool, error) {
|
||||
var verifyErr error
|
||||
defer func() {
|
||||
if verifyErr != nil {
|
||||
klog.Error(verifyErr)
|
||||
c.recorder.Event(c.parentController, event.Warning("VerifyFailed", verifyErr))
|
||||
}
|
||||
}()
|
||||
|
||||
// fetch the cloneset and get its current size
|
||||
currentReplicas, verifyErr := c.size(ctx)
|
||||
if verifyErr != nil {
|
||||
// do not fail the rollout because we can't get the resource
|
||||
c.rolloutStatus.RolloutRetry(verifyErr.Error())
|
||||
// nolint: nilerr
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// the cloneset size has to be the same as the current size
|
||||
if c.cloneSet.Spec.Replicas != nil && *c.cloneSet.Spec.Replicas != c.cloneSet.Status.Replicas {
|
||||
verifyErr = fmt.Errorf("the cloneset is still scaling, target = %d, cloneset size = %d",
|
||||
*c.cloneSet.Spec.Replicas, c.cloneSet.Status.Replicas)
|
||||
// we can wait for the cloneset scale operation to finish
|
||||
c.rolloutStatus.RolloutRetry(verifyErr.Error())
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// make sure that the updateRevision is different from what we have already done
|
||||
targetHash, verifyErr := utils.ComputeSpecHash(c.cloneSet.Spec)
|
||||
if verifyErr != nil {
|
||||
// do not fail the rollout because we can't compute the hash value for some reason
|
||||
c.rolloutStatus.RolloutRetry(verifyErr.Error())
|
||||
// nolint:nilerr
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if targetHash == c.rolloutStatus.LastAppliedPodTemplateIdentifier {
|
||||
return false, fmt.Errorf("there is no difference between the source and target, hash = %s", targetHash)
|
||||
}
|
||||
|
||||
// check if the rollout batch replicas added up to the Cloneset replicas
|
||||
if verifyErr = c.verifyRolloutBatchReplicaValue(currentReplicas); verifyErr != nil {
|
||||
return false, verifyErr
|
||||
}
|
||||
|
||||
// record the size
|
||||
klog.InfoS("record the target size", "total replicas", currentReplicas)
|
||||
c.rolloutStatus.RolloutTargetSize = currentReplicas
|
||||
c.rolloutStatus.RolloutOriginalSize = currentReplicas
|
||||
|
||||
// check if the cloneset is disabled
|
||||
if !c.cloneSet.Spec.UpdateStrategy.Paused {
|
||||
return false, fmt.Errorf("the cloneset %s is in the middle of updating, need to be paused first",
|
||||
c.cloneSet.GetName())
|
||||
}
|
||||
|
||||
// check if the cloneset has any controller
|
||||
if controller := metav1.GetControllerOf(c.cloneSet); controller != nil {
|
||||
return false, fmt.Errorf("the cloneset %s has a controller owner %s",
|
||||
c.cloneSet.GetName(), controller.String())
|
||||
}
|
||||
|
||||
// mark the rollout verified
|
||||
c.recorder.Event(c.parentController, event.Normal("Rollout Verified",
|
||||
"Rollout spec and the CloneSet resource are verified"))
|
||||
// record the new pod template hash only if it succeeds
|
||||
c.rolloutStatus.NewPodTemplateIdentifier = targetHash
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Initialize makes sure that the cloneset is under our control
|
||||
func (c *CloneSetRolloutController) Initialize(ctx context.Context) (bool, error) {
|
||||
totalReplicas, err := c.size(ctx)
|
||||
if err != nil {
|
||||
c.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if controller := metav1.GetControllerOf(c.cloneSet); controller != nil {
|
||||
if controller.Kind == v1alpha1.RolloutKind && controller.APIVersion == v1alpha1.SchemeGroupVersion.String() {
|
||||
// it's already there
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
// add the parent controller to the owner of the cloneset
|
||||
// before kicking start the update and start from every pod in the old version
|
||||
clonePatch := client.MergeFrom(c.cloneSet.DeepCopy())
|
||||
ref := metav1.NewControllerRef(c.parentController, c.parentController.GetObjectKind().GroupVersionKind())
|
||||
c.cloneSet.SetOwnerReferences(append(c.cloneSet.GetOwnerReferences(), *ref))
|
||||
c.cloneSet.Spec.UpdateStrategy.Paused = false
|
||||
c.cloneSet.Spec.UpdateStrategy.Partition = &intstr.IntOrString{Type: intstr.Int, IntVal: totalReplicas}
|
||||
|
||||
// patch the CloneSet
|
||||
if err := c.client.Patch(ctx, c.cloneSet, clonePatch, client.FieldOwner(c.parentController.GetUID())); err != nil {
|
||||
c.recorder.Event(c.parentController, event.Warning("Failed to the start the cloneset update", err))
|
||||
c.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false, nil
|
||||
}
|
||||
// mark the rollout initialized
|
||||
c.recorder.Event(c.parentController, event.Normal("Rollout Initialized", "Rollout resource are initialized"))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// RolloutOneBatchPods calculates the number of pods we can upgrade once according to the rollout spec
|
||||
// and then set the partition accordingly, return if we are done
|
||||
func (c *CloneSetRolloutController) RolloutOneBatchPods(ctx context.Context) (bool, error) {
|
||||
// calculate what's the total pods that should be upgraded given the currentBatch in the status
|
||||
cloneSetSize, err := c.size(ctx)
|
||||
if err != nil {
|
||||
c.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false, nil
|
||||
}
|
||||
|
||||
newPodTarget := calculateNewBatchTarget(c.rolloutSpec, 0, int(cloneSetSize), int(c.rolloutStatus.CurrentBatch))
|
||||
// set the Partition as the desired number of pods in old revisions.
|
||||
clonePatch := client.MergeFrom(c.cloneSet.DeepCopy())
|
||||
c.cloneSet.Spec.UpdateStrategy.Partition = &intstr.IntOrString{Type: intstr.Int,
|
||||
IntVal: cloneSetSize - int32(newPodTarget)}
|
||||
// patch the Cloneset
|
||||
if err = c.client.Patch(ctx, c.cloneSet, clonePatch, client.FieldOwner(c.parentController.GetUID())); err != nil {
|
||||
c.recorder.Event(c.parentController, event.Warning("Failed to update the cloneset to upgrade", err))
|
||||
c.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false, nil
|
||||
}
|
||||
// record the upgrade
|
||||
klog.InfoS("upgraded one batch", "current batch", c.rolloutStatus.CurrentBatch)
|
||||
c.recorder.Event(c.parentController, event.Normal("Batch Rollout",
|
||||
fmt.Sprintf("Submitted upgrade quest for batch %d", c.rolloutStatus.CurrentBatch)))
|
||||
c.rolloutStatus.UpgradedReplicas = int32(newPodTarget)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// CheckOneBatchPods checks to see if enough pods are upgraded according to the rollout plan
|
||||
func (c *CloneSetRolloutController) CheckOneBatchPods(ctx context.Context) (bool, error) {
|
||||
cloneSetSize, err := c.size(ctx)
|
||||
if err != nil {
|
||||
c.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false, nil
|
||||
}
|
||||
newPodTarget := calculateNewBatchTarget(c.rolloutSpec, 0, int(cloneSetSize), int(c.rolloutStatus.CurrentBatch))
|
||||
// get the number of ready pod from cloneset
|
||||
readyPodCount := int(c.cloneSet.Status.UpdatedReadyReplicas)
|
||||
if len(c.rolloutSpec.RolloutBatches) <= int(c.rolloutStatus.CurrentBatch) {
|
||||
err = errors.New("somehow, currentBatch number exceeded the rolloutBatches spec")
|
||||
klog.ErrorS(err, "total batch", len(c.rolloutSpec.RolloutBatches), "current batch",
|
||||
c.rolloutStatus.CurrentBatch)
|
||||
return false, err
|
||||
}
|
||||
currentBatch := c.rolloutSpec.RolloutBatches[c.rolloutStatus.CurrentBatch]
|
||||
unavail := 0
|
||||
if currentBatch.MaxUnavailable != nil {
|
||||
unavail, _ = intstr.GetValueFromIntOrPercent(currentBatch.MaxUnavailable, int(cloneSetSize), true)
|
||||
}
|
||||
klog.InfoS("checking the rolling out progress", "current batch", c.rolloutStatus.CurrentBatch,
|
||||
"new pod count target", newPodTarget, "new ready pod count", readyPodCount,
|
||||
"max unavailable pod allowed", unavail)
|
||||
c.rolloutStatus.UpgradedReadyReplicas = int32(readyPodCount)
|
||||
// we could overshoot in the revert case when many pods are already upgraded
|
||||
if unavail+readyPodCount >= newPodTarget {
|
||||
// record the successful upgrade
|
||||
klog.InfoS("all pods in current batch are ready", "current batch", c.rolloutStatus.CurrentBatch)
|
||||
c.recorder.Event(c.parentController, event.Normal("Batch Available",
|
||||
fmt.Sprintf("Batch %d is available", c.rolloutStatus.CurrentBatch)))
|
||||
return true, nil
|
||||
}
|
||||
// continue to verify
|
||||
klog.InfoS("the batch is not ready yet", "current batch", c.rolloutStatus.CurrentBatch)
|
||||
c.rolloutStatus.RolloutRetry("the batch is not ready yet")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// FinalizeOneBatch makes sure that the upgradedReplicas and current batch in the status are valid according to the spec
|
||||
func (c *CloneSetRolloutController) FinalizeOneBatch(ctx context.Context) (bool, error) {
|
||||
status := c.rolloutStatus
|
||||
spec := c.rolloutSpec
|
||||
if spec.BatchPartition != nil && *spec.BatchPartition < status.CurrentBatch {
|
||||
err := fmt.Errorf("the current batch value in the status is greater than the batch partition")
|
||||
klog.ErrorS(err, "we have moved past the user defined partition", "user specified batch partition",
|
||||
*spec.BatchPartition, "current batch we are working on", status.CurrentBatch)
|
||||
return false, err
|
||||
}
|
||||
upgradedReplicas := int(status.UpgradedReplicas)
|
||||
currentBatch := int(status.CurrentBatch)
|
||||
// calculate the lower bound of the possible pod count just before the current batch
|
||||
podCount := calculateNewBatchTarget(c.rolloutSpec, 0, int(c.rolloutStatus.RolloutTargetSize), currentBatch-1)
|
||||
// the recorded number should be at least as much as the all the pods before the current batch
|
||||
if podCount > upgradedReplicas {
|
||||
err := fmt.Errorf("the upgraded replica in the status is less than all the pods in the previous batch")
|
||||
klog.ErrorS(err, "rollout status inconsistent", "upgraded num status", upgradedReplicas,
|
||||
"pods in all the previous batches", podCount)
|
||||
return false, err
|
||||
}
|
||||
// calculate the upper bound with the current batch
|
||||
podCount = calculateNewBatchTarget(c.rolloutSpec, 0, int(c.rolloutStatus.RolloutTargetSize), currentBatch)
|
||||
// the recorded number should be not as much as the all the pods including the active batch
|
||||
if podCount < upgradedReplicas {
|
||||
err := fmt.Errorf("the upgraded replica in the status is greater than all the pods in the current batch")
|
||||
klog.ErrorS(err, "rollout status inconsistent", "total target size", c.rolloutStatus.RolloutTargetSize,
|
||||
"upgraded num status", upgradedReplicas, "pods in the batches including the current batch", podCount)
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Finalize makes sure the Cloneset is all upgraded
|
||||
func (c *CloneSetRolloutController) Finalize(ctx context.Context, succeed bool) bool {
|
||||
if err := c.fetchCloneSet(ctx); err != nil {
|
||||
c.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false
|
||||
}
|
||||
clonePatch := client.MergeFrom(c.cloneSet.DeepCopy())
|
||||
// remove the parent controller from the resources' owner list
|
||||
var newOwnerList []metav1.OwnerReference
|
||||
isOwner := false
|
||||
for _, owner := range c.cloneSet.GetOwnerReferences() {
|
||||
if owner.Kind == c.parentController.GetObjectKind().GroupVersionKind().Kind &&
|
||||
owner.APIVersion == c.parentController.GetObjectKind().GroupVersionKind().GroupVersion().String() &&
|
||||
owner.Controller != nil && *owner.Controller {
|
||||
isOwner = true
|
||||
continue
|
||||
}
|
||||
newOwnerList = append(newOwnerList, owner)
|
||||
}
|
||||
if !isOwner {
|
||||
// nothing to do if we are already not the owner
|
||||
klog.InfoS("the cloneset is already released and not controlled by rollout", "cloneSet", c.cloneSet.Name)
|
||||
return true
|
||||
}
|
||||
c.cloneSet.SetOwnerReferences(newOwnerList)
|
||||
// pause the resource when the rollout failed so we can try again next time
|
||||
if !succeed {
|
||||
c.cloneSet.Spec.UpdateStrategy.Paused = true
|
||||
}
|
||||
// patch the CloneSet
|
||||
if err := c.client.Patch(ctx, c.cloneSet, clonePatch, client.FieldOwner(c.parentController.GetUID())); err != nil {
|
||||
c.recorder.Event(c.parentController, event.Warning("Failed to the finalize the cloneset", err))
|
||||
c.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false
|
||||
}
|
||||
// mark the resource finalized
|
||||
c.recorder.Event(c.parentController, event.Normal("Rollout Finalized",
|
||||
fmt.Sprintf("Rollout resource are finalized, succeed := %t", succeed)))
|
||||
c.rolloutStatus.LastAppliedPodTemplateIdentifier = c.rolloutStatus.NewPodTemplateIdentifier
|
||||
return true
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
// The functions below are helper functions
|
||||
// ---------------------------------------------
|
||||
|
||||
// check if the replicas in all the rollout batches add up to the right number
|
||||
func (c *CloneSetRolloutController) verifyRolloutBatchReplicaValue(currentReplicas int32) error {
|
||||
// the target size has to be the same as the cloneset size
|
||||
if c.rolloutSpec.TargetSize != nil && *c.rolloutSpec.TargetSize != currentReplicas {
|
||||
return fmt.Errorf("the rollout plan is attempting to scale the cloneset, target = %d, cloneset size = %d",
|
||||
*c.rolloutSpec.TargetSize, currentReplicas)
|
||||
}
|
||||
// use a common function to check if the sum of all the batches can match the cloneset size
|
||||
err := verifyBatchesWithRollout(c.rolloutSpec, currentReplicas)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,472 +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 workloads
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
kruise "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
var _ = Describe("cloneset controller", func() {
|
||||
var (
|
||||
c CloneSetRolloutController
|
||||
ns corev1.Namespace
|
||||
name string
|
||||
namespace string
|
||||
cloneSet kruise.CloneSet
|
||||
namespacedName client.ObjectKey
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
namespace = "rollout-ns"
|
||||
name = "rollout1"
|
||||
appRollout := v1alpha1.Rollout{TypeMeta: metav1.TypeMeta{APIVersion: v1alpha1.SchemeGroupVersion.String(), Kind: v1alpha1.RolloutKind}, ObjectMeta: metav1.ObjectMeta{Name: name}}
|
||||
namespacedName = client.ObjectKey{Name: name, Namespace: namespace}
|
||||
c = CloneSetRolloutController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
client: k8sClient,
|
||||
rolloutSpec: &v1alpha1.RolloutPlan{
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{
|
||||
{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
rolloutStatus: &v1alpha1.RolloutStatus{RollingState: v1alpha1.RolloutSucceedState},
|
||||
parentController: &appRollout,
|
||||
recorder: event.NewAPIRecorder(mgr.GetEventRecorderFor("Rollout")).
|
||||
WithAnnotations("controller", "Rollout"),
|
||||
},
|
||||
targetNamespacedName: namespacedName,
|
||||
},
|
||||
}
|
||||
|
||||
cloneSet = kruise.CloneSet{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: kruise.GroupVersion.String(), Kind: "CloneSet"},
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name},
|
||||
Spec: kruise.CloneSetSpec{
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"env": "staging"},
|
||||
},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"env": "staging"}},
|
||||
Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: name, Image: "nginx"}}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ns = corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
},
|
||||
}
|
||||
By("Create a namespace")
|
||||
Expect(k8sClient.Create(ctx, &ns)).Should(SatisfyAny(Succeed(), &util.AlreadyExistMatcher{}))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
By("clean up")
|
||||
k8sClient.Delete(ctx, &cloneSet)
|
||||
})
|
||||
|
||||
Context("TestNewCloneSetRolloutController", func() {
|
||||
It("init a CloneSet Rollout Controller", func() {
|
||||
recorder := event.NewAPIRecorder(mgr.GetEventRecorderFor("AppRollout")).
|
||||
WithAnnotations("controller", "AppRollout")
|
||||
parentController := &v1alpha1.Rollout{ObjectMeta: metav1.ObjectMeta{Name: name}}
|
||||
rolloutSpec := &v1alpha1.RolloutPlan{
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
},
|
||||
}
|
||||
rolloutStatus := &v1alpha1.RolloutStatus{RollingState: v1alpha1.RolloutSucceedState}
|
||||
workloadNamespacedName := client.ObjectKey{Name: name, Namespace: namespace}
|
||||
got := NewCloneSetRolloutController(k8sClient, recorder, parentController, rolloutSpec, rolloutStatus, workloadNamespacedName)
|
||||
c := &CloneSetRolloutController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
client: k8sClient,
|
||||
recorder: recorder,
|
||||
parentController: parentController,
|
||||
rolloutSpec: rolloutSpec,
|
||||
rolloutStatus: rolloutStatus,
|
||||
},
|
||||
targetNamespacedName: workloadNamespacedName,
|
||||
},
|
||||
}
|
||||
Expect(got).Should(Equal(c))
|
||||
})
|
||||
})
|
||||
|
||||
Context("VerifySpec", func() {
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
consistent, err := c.VerifySpec(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("verify rollout spec hash", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.Spec.UpdateStrategy.Paused = true
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
consistent, err := c.VerifySpec(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("the cloneset is in the middle of updating", func() {
|
||||
By("Create a CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("setting a dummy pod identifier so it's different")
|
||||
c.rolloutStatus.LastAppliedPodTemplateIdentifier = "abc"
|
||||
|
||||
By("verify should fail because it's not paused")
|
||||
consistent, err := c.VerifySpec(ctx)
|
||||
Expect(err).Should(Equal(fmt.Errorf("the cloneset rollout1 is in the middle of updating, need to be paused first")))
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("spec is valid", func() {
|
||||
By("Create a CloneSet and set as paused")
|
||||
cloneSet.Spec.UpdateStrategy.Paused = true
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("setting a dummy pod identifier so it's different")
|
||||
c.rolloutStatus.LastAppliedPodTemplateIdentifier = "abc"
|
||||
|
||||
By("verify should pass and record the size")
|
||||
consistent, err := c.VerifySpec(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeTrue())
|
||||
Expect(c.rolloutStatus.RolloutTargetSize).Should(BeEquivalentTo(1))
|
||||
Expect(c.rolloutStatus.RolloutOriginalSize).Should(BeEquivalentTo(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestInitialize", func() {
|
||||
BeforeEach(func() {
|
||||
cloneSet.Spec.UpdateStrategy.Paused = true
|
||||
})
|
||||
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
consistent, err := c.Initialize(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("failed to patch the owner of CloneSet", func() {
|
||||
By("Create a CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("initialize will fail because cloneset has wrong owner reference")
|
||||
initialized, err := c.Initialize(ctx)
|
||||
Expect(initialized).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
|
||||
It("workload CloneSet is controlled by appRollout already", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.SetOwnerReferences([]metav1.OwnerReference{{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: v1alpha1.RolloutKind,
|
||||
Name: "def",
|
||||
UID: "123456",
|
||||
Controller: pointer.Bool(true),
|
||||
}})
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("initialize succeed without patching")
|
||||
initialized, err := c.Initialize(ctx)
|
||||
Expect(initialized).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(k8sClient.Get(ctx, c.targetNamespacedName, &cloneSet)).Should(Succeed())
|
||||
Expect(len(cloneSet.GetOwnerReferences())).Should(BeEquivalentTo(1))
|
||||
})
|
||||
|
||||
It("successfully initialized CloneSet", func() {
|
||||
By("create cloneset")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("initialize succeeds")
|
||||
c.parentController.SetUID("1231586900")
|
||||
initialized, err := c.Initialize(ctx)
|
||||
Expect(initialized).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(k8sClient.Get(ctx, c.targetNamespacedName, &cloneSet)).Should(Succeed())
|
||||
Expect(len(cloneSet.GetOwnerReferences())).Should(BeEquivalentTo(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestRolloutOneBatchPods", func() {
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
consistent, err := c.RolloutOneBatchPods(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("successfully rollout, current batch number is not equal to the expected one", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.Spec.Replicas = pointer.Int32(10)
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("rollout the second batch of current cloneset")
|
||||
c.rolloutStatus.CurrentBatch = 1
|
||||
c.rolloutSpec.RolloutBatches = []v1alpha1.RolloutBatch{
|
||||
{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("20%"),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("80%"),
|
||||
},
|
||||
}
|
||||
done, err := c.RolloutOneBatchPods(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(c.rolloutStatus.UpgradedReplicas).Should(BeEquivalentTo(3))
|
||||
Expect(k8sClient.Get(ctx, c.targetNamespacedName, &cloneSet)).Should(Succeed())
|
||||
Expect(cloneSet.Spec.UpdateStrategy.Partition.IntValue()).Should(BeEquivalentTo(7))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestCheckOneBatchPods", func() {
|
||||
BeforeEach(func() {
|
||||
cloneSet.Spec.Replicas = pointer.Int32(10)
|
||||
c.rolloutSpec.RolloutBatches = []v1alpha1.RolloutBatch{
|
||||
{
|
||||
Replicas: intstr.FromInt(2),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("20%"),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("80%"),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
consistent, err := c.CheckOneBatchPods(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("current ready Pod is less than expected", func() {
|
||||
By("Create the CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.UpdatedReadyReplicas = 3
|
||||
cloneSet.Status.UpdatedReplicas = 4
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("checking should fail as not enough pod ready")
|
||||
c.rolloutStatus.CurrentBatch = 1
|
||||
done, err := c.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(c.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.UpdatedReadyReplicas))
|
||||
})
|
||||
|
||||
It("failed to check batch Pod when current batch number exceeds the expected ones", func() {
|
||||
By("Create a CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("checking")
|
||||
c.rolloutStatus.CurrentBatch = 3
|
||||
done, err := c.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("currentBatch number exceeded the rolloutBatches spec"))
|
||||
})
|
||||
|
||||
It("there are enough pods counting the unavailable", func() {
|
||||
By("Create the CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.UpdatedReadyReplicas = 3
|
||||
cloneSet.Status.UpdatedReplicas = 4
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
c.rolloutStatus.CurrentBatch = 1
|
||||
// set the rollout batch spec allow unavailable
|
||||
perc := intstr.FromString("20%")
|
||||
c.rolloutSpec.RolloutBatches = []v1alpha1.RolloutBatch{
|
||||
{
|
||||
Replicas: intstr.FromInt(2),
|
||||
},
|
||||
{
|
||||
Replicas: perc,
|
||||
MaxUnavailable: &perc,
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("80%"),
|
||||
},
|
||||
}
|
||||
By("checking one batch")
|
||||
done, err := c.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(c.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.UpdatedReadyReplicas))
|
||||
})
|
||||
|
||||
It("there are enough pods ready", func() {
|
||||
By("Create the CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.UpdatedReadyReplicas = 10
|
||||
cloneSet.Status.UpdatedReplicas = 10
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("the second batch should pass when there are more pods upgraded already")
|
||||
c.rolloutStatus.CurrentBatch = 1
|
||||
done, err := c.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(c.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.UpdatedReadyReplicas))
|
||||
|
||||
By("checking the last batch")
|
||||
c.rolloutStatus.CurrentBatch = 2
|
||||
done, err = c.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(c.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.UpdatedReadyReplicas))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestFinalizeOneBatch", func() {
|
||||
BeforeEach(func() {
|
||||
c.rolloutStatus.RolloutTargetSize = 10
|
||||
c.rolloutSpec.RolloutBatches = []v1alpha1.RolloutBatch{
|
||||
{
|
||||
Replicas: intstr.FromInt(2),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("20%"),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("80%"),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
It("test illegal batch partition", func() {
|
||||
By("finalizing one batch")
|
||||
c.rolloutSpec.BatchPartition = pointer.Int32(2)
|
||||
c.rolloutStatus.CurrentBatch = 3
|
||||
done, err := c.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("the current batch value in the status is greater than the batch partition"))
|
||||
})
|
||||
|
||||
It("test too few upgraded", func() {
|
||||
By("finalizing one batch")
|
||||
c.rolloutStatus.UpgradedReplicas = 2
|
||||
c.rolloutStatus.CurrentBatch = 2
|
||||
done, err := c.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("is less than all the pods in the previous batch"))
|
||||
})
|
||||
|
||||
It("test too many upgraded", func() {
|
||||
By("finalizing one batch")
|
||||
c.rolloutStatus.UpgradedReplicas = 5
|
||||
c.rolloutStatus.CurrentBatch = 1
|
||||
done, err := c.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("is greater than all the pods in the current batch"))
|
||||
})
|
||||
|
||||
It("test upgraded in the range", func() {
|
||||
By("finalizing one batch")
|
||||
c.rolloutStatus.UpgradedReplicas = 3
|
||||
c.rolloutStatus.CurrentBatch = 1
|
||||
done, err := c.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestFinalize", func() {
|
||||
It("failed to fetch CloneSet", func() {
|
||||
By("finalizing")
|
||||
finalized := c.Finalize(ctx, true)
|
||||
Expect(finalized).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("Already finalize CloneSet", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.SetOwnerReferences([]metav1.OwnerReference{{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: "notRollout",
|
||||
Name: "def",
|
||||
UID: "123456",
|
||||
}})
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("finalizing without patch")
|
||||
finalized := c.Finalize(ctx, true)
|
||||
Expect(finalized).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("successfully to finalize CloneSet", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.SetOwnerReferences([]metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: v1alpha1.RolloutKind,
|
||||
Name: "def",
|
||||
UID: "123456",
|
||||
Controller: pointer.Bool(true),
|
||||
},
|
||||
{
|
||||
APIVersion: corev1.SchemeGroupVersion.String(),
|
||||
Kind: "Deployment",
|
||||
Name: "def",
|
||||
UID: "998877745",
|
||||
},
|
||||
})
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("finalizing with patch")
|
||||
finalized := c.Finalize(ctx, false)
|
||||
Expect(finalized).Should(BeTrue())
|
||||
Expect(k8sClient.Get(ctx, c.targetNamespacedName, &cloneSet)).Should(Succeed())
|
||||
Expect(len(cloneSet.GetOwnerReferences())).Should(BeEquivalentTo(1))
|
||||
Expect(cloneSet.GetOwnerReferences()[0].Kind).Should(Equal("Deployment"))
|
||||
Expect(cloneSet.Spec.UpdateStrategy.Paused).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,101 +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 workloads
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/test"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
func TestVerifyRolloutBatchReplicaValue4CloneSet(t *testing.T) {
|
||||
// Compared to `deployment_controller_test.go`, there is one case less as common is already 100% covered, so only an
|
||||
// error and nil error for `err := VerifySumOfBatchSizes(c.rolloutSpec, totalReplicas)` is enough.
|
||||
var int2 int32 = 2
|
||||
cases := map[string]struct {
|
||||
c *CloneSetRolloutController
|
||||
totalReplicas int32
|
||||
want error
|
||||
}{
|
||||
"ClonsetTargetSizeIsNotAvaialbe": {
|
||||
c: &CloneSetRolloutController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
rolloutSpec: &v1alpha1.RolloutPlan{
|
||||
TargetSize: &int2,
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
totalReplicas: 3,
|
||||
want: fmt.Errorf("the rollout plan is attempting to scale the cloneset, target = 2, cloneset size = 3"),
|
||||
},
|
||||
"BatchSizeMismatchesClonesetSize": {
|
||||
c: &CloneSetRolloutController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
rolloutSpec: &v1alpha1.RolloutPlan{
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
totalReplicas: 3,
|
||||
want: fmt.Errorf("the rollout plan batch size mismatch, total batch size = 1, totalReplicas size = 3"),
|
||||
},
|
||||
"BatchSizeMatchesCloneSetSize": {
|
||||
c: &CloneSetRolloutController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
rolloutSpec: &v1alpha1.RolloutPlan{
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{
|
||||
{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromInt(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
totalReplicas: 3,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
err := tc.c.verifyRolloutBatchReplicaValue(tc.totalReplicas)
|
||||
if diff := cmp.Diff(tc.want, err, test.EquateErrors()); diff != "" {
|
||||
t.Errorf("\n%s\nverifyRolloutBatchReplicaValue(...): -want error, +got error:\n%s", name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,304 +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 workloads
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
// CloneSetScaleController is responsible for handle scale Cloneset type of workloads
|
||||
type CloneSetScaleController struct {
|
||||
cloneSetController
|
||||
}
|
||||
|
||||
// NewCloneSetScaleController creates CloneSet scale controller
|
||||
func NewCloneSetScaleController(client client.Client, recorder event.Recorder, parentController oam.Object, rolloutSpec *v1alpha1.RolloutPlan, rolloutStatus *v1alpha1.RolloutStatus, workloadName types.NamespacedName) *CloneSetScaleController {
|
||||
return &CloneSetScaleController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
client: client,
|
||||
recorder: recorder,
|
||||
parentController: parentController,
|
||||
rolloutSpec: rolloutSpec,
|
||||
rolloutStatus: rolloutStatus,
|
||||
},
|
||||
targetNamespacedName: workloadName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VerifySpec verifies that the cloneset is stable and can be scaled
|
||||
func (s *CloneSetScaleController) VerifySpec(ctx context.Context) (bool, error) {
|
||||
var verifyErr error
|
||||
defer func() {
|
||||
if verifyErr != nil {
|
||||
klog.Error(verifyErr)
|
||||
s.recorder.Event(s.parentController, event.Warning("VerifyFailed", verifyErr))
|
||||
}
|
||||
}()
|
||||
|
||||
// the rollout has to have a target size in the scale case
|
||||
if s.rolloutSpec.TargetSize == nil {
|
||||
return false, fmt.Errorf("the rollout plan is attempting to scale the cloneset %s without a target",
|
||||
s.targetNamespacedName.Name)
|
||||
}
|
||||
// record the target size
|
||||
s.rolloutStatus.RolloutTargetSize = *s.rolloutSpec.TargetSize
|
||||
klog.InfoS("record the target size", "target size", *s.rolloutSpec.TargetSize)
|
||||
|
||||
// fetch the cloneset and get its current size
|
||||
originalSize, verifyErr := s.size(ctx)
|
||||
if verifyErr != nil {
|
||||
// do not fail the rollout because we can't get the resource
|
||||
s.rolloutStatus.RolloutRetry(verifyErr.Error())
|
||||
// nolint: nilerr
|
||||
return false, nil
|
||||
}
|
||||
s.rolloutStatus.RolloutOriginalSize = originalSize
|
||||
klog.InfoS("record the original size", "original size", originalSize)
|
||||
|
||||
// check if the rollout batch replicas scale up/down to the replicas target
|
||||
if verifyErr = verifyBatchesWithScale(s.rolloutSpec, int(originalSize),
|
||||
int(s.rolloutStatus.RolloutTargetSize)); verifyErr != nil {
|
||||
return false, verifyErr
|
||||
}
|
||||
|
||||
// check if the cloneset is scaling
|
||||
if originalSize != s.cloneSet.Status.Replicas {
|
||||
verifyErr = fmt.Errorf("the cloneset %s is in the middle of scaling, target size = %d, real size = %d",
|
||||
s.cloneSet.GetName(), originalSize, s.cloneSet.Status.Replicas)
|
||||
// do not fail the rollout, we can wait
|
||||
s.rolloutStatus.RolloutRetry(verifyErr.Error())
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// check if the cloneset is upgrading
|
||||
if !s.cloneSet.Spec.UpdateStrategy.Paused && s.cloneSet.Status.UpdatedReplicas != originalSize {
|
||||
verifyErr = fmt.Errorf("the cloneset %s is in the middle of updating, target size = %d, updated pod = %d",
|
||||
s.cloneSet.GetName(), originalSize, s.cloneSet.Status.UpdatedReplicas)
|
||||
// do not fail the rollout, we can wait
|
||||
s.rolloutStatus.RolloutRetry(verifyErr.Error())
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// check if the cloneset has any controller
|
||||
if controller := metav1.GetControllerOf(s.cloneSet); controller != nil {
|
||||
return false, fmt.Errorf("the cloneset %s has a controller owner %s",
|
||||
s.cloneSet.GetName(), controller.String())
|
||||
}
|
||||
|
||||
// mark the scale verified
|
||||
s.recorder.Event(s.parentController, event.Normal("Scale Verified",
|
||||
"Rollout spec and the CloneSet resource are verified"))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Initialize makes sure that the cloneset is under our control
|
||||
func (s *CloneSetScaleController) Initialize(ctx context.Context) (bool, error) {
|
||||
err := s.fetchCloneSet(ctx)
|
||||
if err != nil {
|
||||
s.rolloutStatus.RolloutRetry(err.Error())
|
||||
// nolint: nilerr
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if controller := metav1.GetControllerOf(s.cloneSet); controller != nil {
|
||||
if controller.Kind == v1alpha1.RolloutKind && controller.APIVersion == v1alpha1.SchemeGroupVersion.String() {
|
||||
|
||||
// it's already there
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
// add the parent controller to the owner of the cloneset
|
||||
clonePatch := client.MergeFrom(s.cloneSet.DeepCopy())
|
||||
ref := metav1.NewControllerRef(s.parentController, s.parentController.GetObjectKind().GroupVersionKind())
|
||||
s.cloneSet.SetOwnerReferences(append(s.cloneSet.GetOwnerReferences(), *ref))
|
||||
s.cloneSet.Spec.UpdateStrategy.Paused = false
|
||||
|
||||
// patch the CloneSet
|
||||
if err := s.client.Patch(ctx, s.cloneSet, clonePatch, client.FieldOwner(s.parentController.GetUID())); err != nil {
|
||||
s.recorder.Event(s.parentController, event.Warning("Failed to the start the cloneset update", err))
|
||||
s.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false, nil
|
||||
}
|
||||
// mark the rollout initialized
|
||||
s.recorder.Event(s.parentController, event.Normal("Scale Initialized", "Cloneset is initialized"))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// RolloutOneBatchPods calculates the number of pods we can scale to according to the rollout spec
|
||||
func (s *CloneSetScaleController) RolloutOneBatchPods(ctx context.Context) (bool, error) {
|
||||
err := s.fetchCloneSet(ctx)
|
||||
if err != nil {
|
||||
s.rolloutStatus.RolloutRetry(err.Error())
|
||||
// nolint: nilerr
|
||||
return false, nil
|
||||
}
|
||||
|
||||
clonePatch := client.MergeFrom(s.cloneSet.DeepCopy())
|
||||
// set the replica according to the batch
|
||||
newPodTarget := calculateNewBatchTarget(s.rolloutSpec, int(s.rolloutStatus.RolloutOriginalSize),
|
||||
int(s.rolloutStatus.RolloutTargetSize), int(s.rolloutStatus.CurrentBatch))
|
||||
s.cloneSet.Spec.Replicas = pointer.Int32(int32(newPodTarget))
|
||||
// patch the Cloneset
|
||||
if err := s.client.Patch(ctx, s.cloneSet, clonePatch, client.FieldOwner(s.parentController.GetUID())); err != nil {
|
||||
s.recorder.Event(s.parentController, event.Warning("Failed to update the cloneset to upgrade", err))
|
||||
s.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false, nil
|
||||
}
|
||||
// record the scale
|
||||
klog.InfoS("scale one batch", "current batch", s.rolloutStatus.CurrentBatch)
|
||||
s.recorder.Event(s.parentController, event.Normal("Batch Rollout",
|
||||
fmt.Sprintf("Submitted scale quest for batch %d", s.rolloutStatus.CurrentBatch)))
|
||||
s.rolloutStatus.UpgradedReplicas = int32(newPodTarget)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// CheckOneBatchPods checks to see if the pods are scaled according to the rollout plan
|
||||
func (s *CloneSetScaleController) CheckOneBatchPods(ctx context.Context) (bool, error) {
|
||||
err := s.fetchCloneSet(ctx)
|
||||
if err != nil {
|
||||
s.rolloutStatus.RolloutRetry(err.Error())
|
||||
// nolint:nilerr
|
||||
return false, nil
|
||||
}
|
||||
newPodTarget := calculateNewBatchTarget(s.rolloutSpec, int(s.rolloutStatus.RolloutOriginalSize),
|
||||
int(s.rolloutStatus.RolloutTargetSize), int(s.rolloutStatus.CurrentBatch))
|
||||
// get the number of ready pod from cloneset
|
||||
// TODO: should we use the replica number when we shrink?
|
||||
readyPodCount := int(s.cloneSet.Status.ReadyReplicas)
|
||||
currentBatch := s.rolloutSpec.RolloutBatches[s.rolloutStatus.CurrentBatch]
|
||||
unavail := 0
|
||||
if currentBatch.MaxUnavailable != nil {
|
||||
unavail, _ = intstr.GetValueFromIntOrPercent(currentBatch.MaxUnavailable,
|
||||
util.Abs(int(s.rolloutStatus.RolloutTargetSize-s.rolloutStatus.RolloutOriginalSize)), true)
|
||||
}
|
||||
klog.InfoS("checking the scaling progress", "current batch", s.rolloutStatus.CurrentBatch,
|
||||
"new pod count target", newPodTarget, "new ready pod count", readyPodCount,
|
||||
"max unavailable pod allowed", unavail)
|
||||
s.rolloutStatus.UpgradedReadyReplicas = int32(readyPodCount)
|
||||
targetReached := false
|
||||
// nolint
|
||||
if s.rolloutStatus.RolloutOriginalSize <= s.rolloutStatus.RolloutTargetSize && unavail+readyPodCount >= newPodTarget {
|
||||
targetReached = true
|
||||
} else if s.rolloutStatus.RolloutOriginalSize > s.rolloutStatus.RolloutTargetSize && readyPodCount <= newPodTarget {
|
||||
targetReached = true
|
||||
}
|
||||
if targetReached {
|
||||
// record the successful upgrade
|
||||
klog.InfoS("the current batch is ready", "current batch", s.rolloutStatus.CurrentBatch,
|
||||
"target", newPodTarget, "readyPodCount", readyPodCount, "max unavailable allowed", unavail)
|
||||
s.recorder.Event(s.parentController, event.Normal("Batch Available",
|
||||
fmt.Sprintf("Batch %d is available", s.rolloutStatus.CurrentBatch)))
|
||||
return true, nil
|
||||
}
|
||||
// continue to verify
|
||||
klog.InfoS("the batch is not ready yet", "current batch", s.rolloutStatus.CurrentBatch,
|
||||
"target", newPodTarget, "readyPodCount", readyPodCount, "max unavailable allowed", unavail)
|
||||
s.rolloutStatus.RolloutRetry("the batch is not ready yet")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// FinalizeOneBatch makes sure that the current batch and replica count in the status are validate
|
||||
func (s *CloneSetScaleController) FinalizeOneBatch(ctx context.Context) (bool, error) {
|
||||
status := s.rolloutStatus
|
||||
spec := s.rolloutSpec
|
||||
if spec.BatchPartition != nil && *spec.BatchPartition < status.CurrentBatch {
|
||||
err := fmt.Errorf("the current batch value in the status is greater than the batch partition")
|
||||
klog.ErrorS(err, "we have moved past the user defined partition", "user specified batch partition",
|
||||
*spec.BatchPartition, "current batch we are working on", status.CurrentBatch)
|
||||
return false, err
|
||||
}
|
||||
// special case the equal case
|
||||
if s.rolloutStatus.RolloutOriginalSize == s.rolloutStatus.RolloutTargetSize {
|
||||
return true, nil
|
||||
}
|
||||
// we just make sure the target is right
|
||||
finishedPodCount := int(status.UpgradedReplicas)
|
||||
currentBatch := int(status.CurrentBatch)
|
||||
// calculate the pod target just before the current batch
|
||||
preBatchTarget := calculateNewBatchTarget(s.rolloutSpec, int(s.rolloutStatus.RolloutOriginalSize),
|
||||
int(s.rolloutStatus.RolloutTargetSize), currentBatch-1)
|
||||
// calculate the pod target with the current batch
|
||||
curBatchTarget := calculateNewBatchTarget(s.rolloutSpec, int(s.rolloutStatus.RolloutOriginalSize),
|
||||
int(s.rolloutStatus.RolloutTargetSize), currentBatch)
|
||||
// the recorded number should be at least as much as the all the pods before the current batch
|
||||
if finishedPodCount < util.Min(preBatchTarget, curBatchTarget) {
|
||||
err := fmt.Errorf("the upgraded replica in the status is less than the lower bound")
|
||||
klog.ErrorS(err, "rollout status inconsistent", "existing pod target", finishedPodCount,
|
||||
"the lower bound", util.Min(preBatchTarget, curBatchTarget))
|
||||
return false, err
|
||||
}
|
||||
// the recorded number should be not as much as the all the pods including the active batch
|
||||
if finishedPodCount > util.Max(preBatchTarget, curBatchTarget) {
|
||||
err := fmt.Errorf("the upgraded replica in the status is greater than the upper bound")
|
||||
klog.ErrorS(err, "rollout status inconsistent", "existing pod target", finishedPodCount,
|
||||
"the upper bound", util.Max(preBatchTarget, curBatchTarget))
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Finalize makes sure the Cloneset is scaled and ready to use
|
||||
func (s *CloneSetScaleController) Finalize(ctx context.Context, succeed bool) bool {
|
||||
if err := s.fetchCloneSet(ctx); err != nil {
|
||||
s.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false
|
||||
}
|
||||
clonePatch := client.MergeFrom(s.cloneSet.DeepCopy())
|
||||
// remove the parent controller from the resources' owner list
|
||||
var newOwnerList []metav1.OwnerReference
|
||||
isOwner := false
|
||||
for _, owner := range s.cloneSet.GetOwnerReferences() {
|
||||
if owner.Kind == s.parentController.GetObjectKind().GroupVersionKind().Kind &&
|
||||
owner.APIVersion == s.parentController.GetObjectKind().GroupVersionKind().GroupVersion().String() {
|
||||
isOwner = true
|
||||
continue
|
||||
}
|
||||
newOwnerList = append(newOwnerList, owner)
|
||||
}
|
||||
if !isOwner {
|
||||
// nothing to do if we are already not the owner
|
||||
klog.InfoS("the cloneset is already released and not controlled by rollout", "cloneSet", s.cloneSet.Name)
|
||||
return true
|
||||
}
|
||||
|
||||
s.cloneSet.SetOwnerReferences(newOwnerList)
|
||||
// patch the CloneSet
|
||||
if err := s.client.Patch(ctx, s.cloneSet, clonePatch, client.FieldOwner(s.parentController.GetUID())); err != nil {
|
||||
s.recorder.Event(s.parentController, event.Warning("Failed to the finalize the cloneset", err))
|
||||
s.rolloutStatus.RolloutRetry(err.Error())
|
||||
return false
|
||||
}
|
||||
// mark the resource finalized
|
||||
s.recorder.Event(s.parentController, event.Normal("Scale Finalized",
|
||||
fmt.Sprintf("Scale resource are finalized, succeed := %t", succeed)))
|
||||
return true
|
||||
}
|
||||
@@ -1,483 +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 workloads
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
kruise "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
var _ = Describe("cloneset controller", func() {
|
||||
var (
|
||||
s CloneSetScaleController
|
||||
ns corev1.Namespace
|
||||
name string
|
||||
namespace string
|
||||
cloneSet kruise.CloneSet
|
||||
namespacedName client.ObjectKey
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
namespace = "rollout-ns"
|
||||
name = "rollout1"
|
||||
appRollout := v1alpha1.Rollout{TypeMeta: metav1.TypeMeta{APIVersion: v1alpha1.SchemeGroupVersion.String(), Kind: v1alpha1.RolloutKind}, ObjectMeta: metav1.ObjectMeta{Name: name}}
|
||||
namespacedName = client.ObjectKey{Name: name, Namespace: namespace}
|
||||
s = CloneSetScaleController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
client: k8sClient,
|
||||
rolloutSpec: &v1alpha1.RolloutPlan{
|
||||
TargetSize: pointer.Int32(10),
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{
|
||||
{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("20%"),
|
||||
},
|
||||
{
|
||||
Replicas: intstr.FromString("80%"),
|
||||
},
|
||||
},
|
||||
},
|
||||
rolloutStatus: &v1alpha1.RolloutStatus{RollingState: v1alpha1.RolloutSucceedState},
|
||||
parentController: &appRollout,
|
||||
recorder: event.NewAPIRecorder(mgr.GetEventRecorderFor("AppRollout")).
|
||||
WithAnnotations("controller", "AppRollout"),
|
||||
},
|
||||
targetNamespacedName: namespacedName,
|
||||
},
|
||||
}
|
||||
|
||||
cloneSet = kruise.CloneSet{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: kruise.GroupVersion.String(), Kind: "CloneSet"},
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name},
|
||||
Spec: kruise.CloneSetSpec{
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"env": "staging"},
|
||||
},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"env": "staging"}},
|
||||
Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: name, Image: "nginx"}}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ns = corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
},
|
||||
}
|
||||
By("Create a namespace")
|
||||
Expect(k8sClient.Create(ctx, &ns)).Should(SatisfyAny(Succeed(), &util.AlreadyExistMatcher{}))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
By("clean up")
|
||||
k8sClient.Delete(ctx, &cloneSet)
|
||||
})
|
||||
|
||||
Context("TestNewCloneSetScaleController", func() {
|
||||
It("init a CloneSet Scale Controller", func() {
|
||||
recorder := event.NewAPIRecorder(mgr.GetEventRecorderFor("AppRollout")).
|
||||
WithAnnotations("controller", "AppRollout")
|
||||
parentController := &v1alpha1.Rollout{ObjectMeta: metav1.ObjectMeta{Name: name}}
|
||||
rolloutSpec := &v1alpha1.RolloutPlan{
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{{
|
||||
Replicas: intstr.FromInt(1),
|
||||
},
|
||||
},
|
||||
}
|
||||
rolloutStatus := &v1alpha1.RolloutStatus{RollingState: v1alpha1.RolloutSucceedState}
|
||||
workloadNamespacedName := client.ObjectKey{Name: name, Namespace: namespace}
|
||||
got := NewCloneSetScaleController(k8sClient, recorder, parentController, rolloutSpec, rolloutStatus, workloadNamespacedName)
|
||||
controller := &CloneSetScaleController{
|
||||
cloneSetController: cloneSetController{
|
||||
workloadController: workloadController{
|
||||
client: k8sClient,
|
||||
recorder: recorder,
|
||||
parentController: parentController,
|
||||
rolloutSpec: rolloutSpec,
|
||||
rolloutStatus: rolloutStatus,
|
||||
},
|
||||
targetNamespacedName: workloadNamespacedName,
|
||||
}}
|
||||
Expect(got).Should(Equal(controller))
|
||||
})
|
||||
})
|
||||
|
||||
Context("VerifySpec", func() {
|
||||
It("rollout need a target size", func() {
|
||||
s.rolloutSpec.TargetSize = nil
|
||||
ligit, err := s.VerifySpec(ctx)
|
||||
Expect(ligit).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("without a target"))
|
||||
})
|
||||
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
ligit, err := s.VerifySpec(ctx)
|
||||
Expect(ligit).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
|
||||
It("rollout batch doesn't fit scale target", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.Spec.Replicas = pointer.Int32(15)
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("Verify should fail as the scale batches don't match")
|
||||
s.rolloutSpec.RolloutBatches[2].Replicas = intstr.FromInt(10)
|
||||
consistent, err := s.VerifySpec(ctx)
|
||||
Expect(err).ShouldNot(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("the cloneset is in the middle of scaling", func() {
|
||||
By("Create a CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("verify should fail because replica does not match")
|
||||
consistent, err := s.VerifySpec(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("the cloneset is in the middle of updating", func() {
|
||||
By("Create a CloneSet and set as paused")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.Replicas = 1
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("verify should fail because replica are not upgraded")
|
||||
consistent, err := s.VerifySpec(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("spec is valid", func() {
|
||||
By("Create a CloneSet and set as paused")
|
||||
cloneSet.Spec.UpdateStrategy.Paused = true
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.Replicas = 1
|
||||
cloneSet.Status.UpdatedReplicas = 1
|
||||
cloneSet.Status.UpdatedReadyReplicas = 1
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("verify should pass and record the size")
|
||||
consistent, err := s.VerifySpec(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeTrue())
|
||||
Expect(s.rolloutStatus.RolloutTargetSize).Should(BeEquivalentTo(10))
|
||||
Expect(s.rolloutStatus.RolloutOriginalSize).Should(BeEquivalentTo(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestInitialize", func() {
|
||||
BeforeEach(func() {
|
||||
cloneSet.Spec.UpdateStrategy.Paused = true
|
||||
})
|
||||
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
consistent, err := s.Initialize(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("failed to patch the owner of CloneSet", func() {
|
||||
By("Create a CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("initialize will fail because cloneset has wrong owner reference")
|
||||
initialized, err := s.Initialize(ctx)
|
||||
Expect(initialized).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
|
||||
It("workload CloneSet is controlled by appRollout already", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.SetOwnerReferences([]metav1.OwnerReference{{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: v1alpha1.RolloutKind,
|
||||
Name: "def",
|
||||
UID: "123456",
|
||||
Controller: pointer.Bool(true),
|
||||
}})
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("initialize succeed without patching")
|
||||
initialized, err := s.Initialize(ctx)
|
||||
Expect(initialized).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
|
||||
It("successfully initialized CloneSet", func() {
|
||||
By("create cloneset")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("initialize succeeds")
|
||||
s.parentController.SetUID("1231586900")
|
||||
initialized, err := s.Initialize(ctx)
|
||||
Expect(initialized).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestRolloutOneBatchPods", func() {
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
consistent, err := s.RolloutOneBatchPods(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("successfully rollout, current batch number is not equal to the expected one", func() {
|
||||
By("Create a CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("rollout the second batch of current cloneset")
|
||||
s.rolloutStatus.CurrentBatch = 1
|
||||
s.rolloutStatus.RolloutOriginalSize = 0
|
||||
s.rolloutStatus.RolloutTargetSize = 10
|
||||
done, err := s.RolloutOneBatchPods(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(s.rolloutStatus.UpgradedReplicas).Should(BeEquivalentTo(3))
|
||||
Expect(k8sClient.Get(ctx, s.targetNamespacedName, &cloneSet)).Should(Succeed())
|
||||
Expect(*cloneSet.Spec.Replicas).Should(BeEquivalentTo(3))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestCheckOneBatchPods", func() {
|
||||
It("could not fetch CloneSet workload", func() {
|
||||
consistent, err := s.CheckOneBatchPods(ctx)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("current ready Pod is less than expected during increase", func() {
|
||||
By("Create the CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.ReadyReplicas = 3
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("checking should fail as not enough pod ready")
|
||||
s.rolloutStatus.CurrentBatch = 1
|
||||
s.rolloutStatus.RolloutOriginalSize = 2
|
||||
s.rolloutStatus.RolloutTargetSize = 10
|
||||
done, err := s.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(s.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.ReadyReplicas))
|
||||
|
||||
// set the rollout batch spec allow unavailable
|
||||
perc := intstr.FromString("20%")
|
||||
s.rolloutSpec.RolloutBatches[1] = v1alpha1.RolloutBatch{
|
||||
Replicas: perc,
|
||||
MaxUnavailable: &perc,
|
||||
}
|
||||
By("checking one batch should succeed with unavailble allowed")
|
||||
done, err = s.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(s.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.ReadyReplicas))
|
||||
})
|
||||
|
||||
It("current ready Pod is more than expected during decrease", func() {
|
||||
By("Create the CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.ReadyReplicas = 10
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("checking should fail as not enough pod ready")
|
||||
s.rolloutStatus.CurrentBatch = 1
|
||||
s.rolloutStatus.RolloutOriginalSize = 12
|
||||
s.rolloutStatus.RolloutTargetSize = 5
|
||||
done, err := s.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(s.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.ReadyReplicas))
|
||||
|
||||
// set the rollout batch spec allow unavailable
|
||||
perc := intstr.FromString("20%")
|
||||
s.rolloutSpec.RolloutBatches[1] = v1alpha1.RolloutBatch{
|
||||
Replicas: perc,
|
||||
MaxUnavailable: &perc,
|
||||
}
|
||||
By("checking one batch should still fail even with unavailble allowed")
|
||||
done, err = s.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(s.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.ReadyReplicas))
|
||||
})
|
||||
|
||||
It("there are more pods shrunk during decrease", func() {
|
||||
By("Create the CloneSet")
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
By("Update the CloneSet status")
|
||||
cloneSet.Status.ReadyReplicas = 8
|
||||
Expect(k8sClient.Status().Update(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("checking should pass even with not enough pod ready")
|
||||
s.rolloutStatus.CurrentBatch = 1
|
||||
s.rolloutStatus.RolloutOriginalSize = 12
|
||||
s.rolloutStatus.RolloutTargetSize = 5
|
||||
done, err := s.CheckOneBatchPods(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(s.rolloutStatus.UpgradedReadyReplicas).Should(BeEquivalentTo(cloneSet.Status.ReadyReplicas))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestFinalizeOneBatch", func() {
|
||||
BeforeEach(func() {
|
||||
s.rolloutSpec.RolloutBatches[0] = v1alpha1.RolloutBatch{
|
||||
Replicas: intstr.FromInt(2),
|
||||
}
|
||||
})
|
||||
|
||||
It("test illegal batch partition", func() {
|
||||
By("finalizing one batch")
|
||||
s.rolloutSpec.BatchPartition = pointer.Int32(2)
|
||||
s.rolloutStatus.CurrentBatch = 3
|
||||
done, err := s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("the current batch value in the status is greater than the batch partition"))
|
||||
})
|
||||
|
||||
It("test finalize during increase", func() {
|
||||
By("finalizing one batch with not enough")
|
||||
s.rolloutStatus.UpgradedReplicas = 6
|
||||
s.rolloutStatus.CurrentBatch = 1
|
||||
s.rolloutStatus.RolloutOriginalSize = 5
|
||||
s.rolloutStatus.RolloutTargetSize = 12
|
||||
done, err := s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring(" upgraded replica in the status is less than the lower bound"))
|
||||
|
||||
By("finalizing one batch with just enough")
|
||||
s.rolloutStatus.UpgradedReplicas = 7
|
||||
done, err = s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
By("finalizing one batch with all")
|
||||
s.rolloutStatus.UpgradedReplicas = 9
|
||||
done, err = s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
By("finalizing one batch with more than")
|
||||
s.rolloutStatus.UpgradedReplicas = 12
|
||||
done, err = s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("upgraded replica in the status is greater than the upper bound"))
|
||||
})
|
||||
|
||||
It("test finalize during decrease", func() {
|
||||
By("finalizing one batch with too many")
|
||||
s.rolloutStatus.UpgradedReplicas = 13
|
||||
s.rolloutStatus.CurrentBatch = 1
|
||||
s.rolloutStatus.RolloutOriginalSize = 14
|
||||
s.rolloutStatus.RolloutTargetSize = 2
|
||||
done, err := s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring("upgraded replica in the status is greater than the upper bound"))
|
||||
|
||||
By("finalizing one batch with just enough")
|
||||
s.rolloutStatus.UpgradedReplicas = 12
|
||||
done, err = s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
By("finalizing one batch with all")
|
||||
s.rolloutStatus.UpgradedReplicas = 9
|
||||
done, err = s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
By("finalizing one batch with not enough")
|
||||
s.rolloutStatus.UpgradedReplicas = 8
|
||||
done, err = s.FinalizeOneBatch(ctx)
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(err.Error()).Should(ContainSubstring(" upgraded replica in the status is less than the lower bound"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("TestFinalize", func() {
|
||||
It("failed to fetch CloneSet", func() {
|
||||
By("finalizing")
|
||||
finalized := s.Finalize(ctx, true)
|
||||
Expect(finalized).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("Already finalize CloneSet", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.SetOwnerReferences([]metav1.OwnerReference{{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: "notRollout",
|
||||
Name: "def",
|
||||
UID: "123456",
|
||||
}})
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("finalizing without patch")
|
||||
finalized := s.Finalize(ctx, true)
|
||||
Expect(finalized).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("successfully to finalize CloneSet", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.SetOwnerReferences([]metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: v1alpha1.RolloutKind,
|
||||
Name: "def",
|
||||
UID: "123456",
|
||||
},
|
||||
{
|
||||
APIVersion: corev1.SchemeGroupVersion.String(),
|
||||
Kind: "Deployment",
|
||||
Name: "def",
|
||||
UID: "998877745",
|
||||
},
|
||||
})
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("finalizing with patch")
|
||||
finalized := s.Finalize(ctx, false)
|
||||
Expect(finalized).Should(BeTrue())
|
||||
Expect(k8sClient.Get(ctx, s.targetNamespacedName, &cloneSet)).Should(Succeed())
|
||||
Expect(len(cloneSet.GetOwnerReferences())).Should(BeEquivalentTo(1))
|
||||
Expect(cloneSet.GetOwnerReferences()[0].Kind).Should(Equal("Deployment"))
|
||||
})
|
||||
})
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user