mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-25 23:33:58 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f95ff4f06e | ||
|
|
e30876e4d2 | ||
|
|
141c6bb2ef | ||
|
|
bdfd8e1f8d | ||
|
|
cfbaf38715 | ||
|
|
d3006f2d9e | ||
|
|
8f7aa9b746 | ||
|
|
8431cdb10d | ||
|
|
66013a9607 | ||
|
|
1d133df1dd | ||
|
|
c66f5f103f | ||
|
|
e6779f6906 | ||
|
|
a48b74d4be | ||
|
|
2da80af3c4 | ||
|
|
7bf5e17262 | ||
|
|
53a6d54b73 | ||
|
|
bcd072507b | ||
|
|
ae075e6cb6 | ||
|
|
b2127ee4fa |
@@ -17,9 +17,13 @@ limitations under the License.
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
types "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
@@ -109,6 +113,9 @@ type Terraform struct {
|
||||
// +kubebuilder:default:=hcl
|
||||
// +kubebuilder:validation:Enum:=hcl;json;remote
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
// ProviderReference specifies the reference to Provider
|
||||
ProviderReference *types.Reference `json:"providerRef,omitempty"`
|
||||
}
|
||||
|
||||
// A WorkloadTypeDescriptor refer to a Workload Type
|
||||
@@ -369,7 +376,7 @@ type AppRolloutStatus struct {
|
||||
type ApplicationTrait struct {
|
||||
Type string `json:"type"`
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Properties runtime.RawExtension `json:"properties,omitempty"`
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationComponent describe the component of application
|
||||
@@ -379,7 +386,7 @@ type ApplicationComponent struct {
|
||||
// ExternalRevision specified the component revisionName
|
||||
ExternalRevision string `json:"externalRevision,omitempty"`
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Properties runtime.RawExtension `json:"properties,omitempty"`
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
|
||||
DependsOn []string `json:"dependsOn,omitempty"`
|
||||
Inputs StepInputs `json:"inputs,omitempty"`
|
||||
@@ -452,3 +459,29 @@ type ClusterObjectReference struct {
|
||||
Creator ResourceCreatorRole `json:"creator,omitempty"`
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
// RawExtensionPointer is the pointer of raw extension
|
||||
type RawExtensionPointer struct {
|
||||
RawExtension *runtime.RawExtension
|
||||
}
|
||||
|
||||
// MarshalJSON may get called on pointers or values, so implement MarshalJSON on value.
|
||||
// http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go
|
||||
func (re RawExtensionPointer) MarshalJSON() ([]byte, error) {
|
||||
if re.RawExtension == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if re.RawExtension.Raw == nil {
|
||||
// TODO: this is to support legacy behavior of JSONPrinter and YAMLPrinter, which
|
||||
// expect to call json.Marshal on arbitrary versioned objects (even those not in
|
||||
// the scheme). pkg/kubectl/resource#AsVersionedObjects and its interaction with
|
||||
// kubectl get on objects not in the scheme needs to be updated to ensure that the
|
||||
// objects that are not part of the scheme are correctly put into the right form.
|
||||
if re.RawExtension.Object != nil {
|
||||
return json.Marshal(re.RawExtension.Object)
|
||||
}
|
||||
return []byte("null"), nil
|
||||
}
|
||||
// TODO: Check whether ContentType is actually JSON before returning it.
|
||||
return re.RawExtension.Raw, nil
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@ limitations under the License.
|
||||
package common
|
||||
|
||||
import (
|
||||
crossplane_runtime "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
@@ -92,7 +94,11 @@ func (in *AppStatus) DeepCopy() *AppStatus {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationComponent) DeepCopyInto(out *ApplicationComponent) {
|
||||
*out = *in
|
||||
in.Properties.DeepCopyInto(&out.Properties)
|
||||
if in.Properties != nil {
|
||||
in, out := &in.Properties, &out.Properties
|
||||
*out = new(runtime.RawExtension)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.DependsOn != nil {
|
||||
in, out := &in.DependsOn, &out.DependsOn
|
||||
*out = make([]string, len(*in))
|
||||
@@ -163,7 +169,11 @@ func (in *ApplicationComponentStatus) DeepCopy() *ApplicationComponentStatus {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationTrait) DeepCopyInto(out *ApplicationTrait) {
|
||||
*out = *in
|
||||
in.Properties.DeepCopyInto(&out.Properties)
|
||||
if in.Properties != nil {
|
||||
in, out := &in.Properties, &out.Properties
|
||||
*out = new(runtime.RawExtension)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationTrait.
|
||||
@@ -403,6 +413,26 @@ func (in *RawComponent) DeepCopy() *RawComponent {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RawExtensionPointer) DeepCopyInto(out *RawExtensionPointer) {
|
||||
*out = *in
|
||||
if in.RawExtension != nil {
|
||||
in, out := &in.RawExtension, &out.RawExtension
|
||||
*out = new(runtime.RawExtension)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RawExtensionPointer.
|
||||
func (in *RawExtensionPointer) DeepCopy() *RawExtensionPointer {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RawExtensionPointer)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Revision) DeepCopyInto(out *Revision) {
|
||||
*out = *in
|
||||
@@ -439,7 +469,7 @@ func (in *Schematic) DeepCopyInto(out *Schematic) {
|
||||
if in.Terraform != nil {
|
||||
in, out := &in.Terraform, &out.Terraform
|
||||
*out = new(Terraform)
|
||||
**out = **in
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,6 +559,11 @@ func (in *SubStepsStatus) DeepCopy() *SubStepsStatus {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Terraform) DeepCopyInto(out *Terraform) {
|
||||
*out = *in
|
||||
if in.ProviderReference != nil {
|
||||
in, out := &in.ProviderReference, &out.ProviderReference
|
||||
*out = new(crossplane_runtime.Reference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Terraform.
|
||||
|
||||
@@ -1,116 +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 v1alpha1
|
||||
|
||||
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/core.oam.dev/condition"
|
||||
)
|
||||
|
||||
// WorkflowStepPhase describes the phase of a workflow step.
|
||||
type WorkflowStepPhase string
|
||||
|
||||
const (
|
||||
// WorkflowStepPhaseSucceeded will make the controller run the next step.
|
||||
WorkflowStepPhaseSucceeded WorkflowStepPhase = "succeeded"
|
||||
// WorkflowStepPhaseFailed will make the controller stop the workflow and report error in `message`.
|
||||
WorkflowStepPhaseFailed WorkflowStepPhase = "failed"
|
||||
// WorkflowStepPhaseTerminated will make the controller terminate the workflow.
|
||||
WorkflowStepPhaseTerminated WorkflowStepPhase = "terminated"
|
||||
// WorkflowStepPhaseSuspending will make the controller suspend the workflow.
|
||||
WorkflowStepPhaseSuspending WorkflowStepPhase = "suspending"
|
||||
// WorkflowStepPhaseRunning will make the controller continue the workflow.
|
||||
WorkflowStepPhaseRunning WorkflowStepPhase = "running"
|
||||
)
|
||||
|
||||
// WorkflowStep defines how to execute a workflow step.
|
||||
type WorkflowStep struct {
|
||||
// Name is the unique name of the workflow step.
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Properties runtime.RawExtension `json:"properties,omitempty"`
|
||||
Inputs common.StepInputs `json:"inputs,omitempty"`
|
||||
Outputs common.StepOutputs `json:"outputs,omitempty"`
|
||||
}
|
||||
|
||||
// A WorkflowSpec defines the desired state of a Workflow.
|
||||
type WorkflowSpec struct {
|
||||
Steps []WorkflowStep `json:"steps,omitempty"`
|
||||
}
|
||||
|
||||
// A WorkflowStatus is the status of Workflow
|
||||
type WorkflowStatus struct {
|
||||
// ConditionedStatus reflects the observed status of a resource
|
||||
condition.ConditionedStatus `json:",inline"`
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
StepIndex int `json:"stepIndex,omitempty"`
|
||||
Suspend bool `json:"suspend"`
|
||||
Terminated bool `json:"terminated"`
|
||||
ContextBackend *corev1.ObjectReference `json:"contextBackend"`
|
||||
Steps []WorkflowStepStatus `json:"steps,omitempty"`
|
||||
}
|
||||
|
||||
// WorkflowStepStatus record the status of a workflow step
|
||||
type WorkflowStepStatus struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Phase WorkflowStepPhase `json:"phase,omitempty"`
|
||||
// A human readable message indicating details about why the workflowStep is in this state.
|
||||
Message string `json:"message,omitempty"`
|
||||
// A brief CamelCase message indicating details about why the workflowStep is in this state.
|
||||
Reason string `json:"reason,omitempty"`
|
||||
ResourceRef corev1.ObjectReference `json:"resourceRef,omitempty"`
|
||||
}
|
||||
|
||||
// Workflow is the Schema for the Workflow API
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Namespaced,categories={oam},shortName=workflow
|
||||
// +kubebuilder:printcolumn:name="PHASE",type=string,JSONPath=`.status.phase`
|
||||
// +kubebuilder:printcolumn:name="AGE",type=date,JSONPath=".metadata.creationTimestamp"
|
||||
type Workflow struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec WorkflowSpec `json:"spec,omitempty"`
|
||||
Status WorkflowStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// WorkflowList contains a list of Workflow.
|
||||
type WorkflowList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Workflow `json:"items"`
|
||||
}
|
||||
|
||||
// SetConditions set condition for Workflow
|
||||
func (w *Workflow) SetConditions(c ...condition.Condition) {
|
||||
w.Status.SetConditions(c...)
|
||||
}
|
||||
|
||||
// GetCondition gets condition from Workflow
|
||||
func (w *Workflow) GetCondition(conditionType condition.ConditionType) condition.Condition {
|
||||
return w.Status.GetCondition(conditionType)
|
||||
}
|
||||
@@ -296,152 +296,3 @@ func (in *NamespaceSelector) DeepCopy() *NamespaceSelector {
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Workflow) DeepCopyInto(out *Workflow) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workflow.
|
||||
func (in *Workflow) DeepCopy() *Workflow {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Workflow)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Workflow) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkflowList) DeepCopyInto(out *WorkflowList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Workflow, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowList.
|
||||
func (in *WorkflowList) DeepCopy() *WorkflowList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkflowList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WorkflowList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkflowSpec) DeepCopyInto(out *WorkflowSpec) {
|
||||
*out = *in
|
||||
if in.Steps != nil {
|
||||
in, out := &in.Steps, &out.Steps
|
||||
*out = make([]WorkflowStep, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowSpec.
|
||||
func (in *WorkflowSpec) DeepCopy() *WorkflowSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkflowSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkflowStatus) DeepCopyInto(out *WorkflowStatus) {
|
||||
*out = *in
|
||||
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
|
||||
if in.ContextBackend != nil {
|
||||
in, out := &in.ContextBackend, &out.ContextBackend
|
||||
*out = new(v1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.Steps != nil {
|
||||
in, out := &in.Steps, &out.Steps
|
||||
*out = make([]WorkflowStepStatus, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowStatus.
|
||||
func (in *WorkflowStatus) DeepCopy() *WorkflowStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkflowStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkflowStep) DeepCopyInto(out *WorkflowStep) {
|
||||
*out = *in
|
||||
in.Properties.DeepCopyInto(&out.Properties)
|
||||
if in.Inputs != nil {
|
||||
in, out := &in.Inputs, &out.Inputs
|
||||
*out = make(common.StepInputs, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Outputs != nil {
|
||||
in, out := &in.Outputs, &out.Outputs
|
||||
*out = make(common.StepOutputs, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowStep.
|
||||
func (in *WorkflowStep) DeepCopy() *WorkflowStep {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkflowStep)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkflowStepStatus) DeepCopyInto(out *WorkflowStepStatus) {
|
||||
*out = *in
|
||||
out.ResourceRef = in.ResourceRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowStepStatus.
|
||||
func (in *WorkflowStepStatus) DeepCopy() *WorkflowStepStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkflowStepStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ type AppStatus struct {
|
||||
type ApplicationTrait struct {
|
||||
Name string `json:"name"`
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Properties runtime.RawExtension `json:"properties,omitempty"`
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationComponent describe the component of application
|
||||
|
||||
@@ -44,7 +44,7 @@ func ApplicationV1alpha2ToV1beta1(v1a2 *Application, v1b1 *v1beta1.Application)
|
||||
for j, trait := range comp.Traits {
|
||||
traits[j] = common.ApplicationTrait{
|
||||
Type: trait.Name,
|
||||
Properties: *trait.Properties.DeepCopy(),
|
||||
Properties: trait.Properties.DeepCopy(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func ApplicationV1alpha2ToV1beta1(v1a2 *Application, v1b1 *v1beta1.Application)
|
||||
v1b1.Spec.Components = append(v1b1.Spec.Components, common.ApplicationComponent{
|
||||
Name: comp.Name,
|
||||
Type: comp.WorkloadType,
|
||||
Properties: *comp.Settings.DeepCopy(),
|
||||
Properties: comp.Settings.DeepCopy(),
|
||||
Traits: traits,
|
||||
Scopes: scopes,
|
||||
})
|
||||
@@ -104,7 +104,7 @@ func (app *Application) ConvertFrom(src conversion.Hub) error {
|
||||
for j, trait := range comp.Traits {
|
||||
traits[j] = ApplicationTrait{
|
||||
Name: trait.Type,
|
||||
Properties: *trait.Properties.DeepCopy(),
|
||||
Properties: trait.Properties.DeepCopy(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -600,7 +600,11 @@ func (in *ApplicationSpec) DeepCopy() *ApplicationSpec {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationTrait) DeepCopyInto(out *ApplicationTrait) {
|
||||
*out = *in
|
||||
in.Properties.DeepCopyInto(&out.Properties)
|
||||
if in.Properties != nil {
|
||||
in, out := &in.Properties, &out.Properties
|
||||
*out = new(runtime.RawExtension)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationTrait.
|
||||
|
||||
@@ -44,7 +44,7 @@ type AppPolicy struct {
|
||||
|
||||
Type string `json:"type"`
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Properties runtime.RawExtension `json:"properties,omitempty"`
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// WorkflowStep defines how to execute a workflow step.
|
||||
@@ -55,7 +55,7 @@ type WorkflowStep struct {
|
||||
Type string `json:"type"`
|
||||
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
Properties runtime.RawExtension `json:"properties,omitempty"`
|
||||
Properties *runtime.RawExtension `json:"properties,omitempty"`
|
||||
|
||||
DependsOn []string `json:"dependsOn,omitempty"`
|
||||
|
||||
|
||||
@@ -141,7 +141,11 @@ func (in *AppDeploymentStatus) DeepCopy() *AppDeploymentStatus {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppPolicy) DeepCopyInto(out *AppPolicy) {
|
||||
*out = *in
|
||||
in.Properties.DeepCopyInto(&out.Properties)
|
||||
if in.Properties != nil {
|
||||
in, out := &in.Properties, &out.Properties
|
||||
*out = new(runtime.RawExtension)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppPolicy.
|
||||
@@ -1450,7 +1454,11 @@ func (in *Workflow) DeepCopy() *Workflow {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkflowStep) DeepCopyInto(out *WorkflowStep) {
|
||||
*out = *in
|
||||
in.Properties.DeepCopyInto(&out.Properties)
|
||||
if in.Properties != nil {
|
||||
in, out := &in.Properties, &out.Properties
|
||||
*out = new(runtime.RawExtension)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.DependsOn != nil {
|
||||
in, out := &in.DependsOn, &out.DependsOn
|
||||
*out = make([]string, len(*in))
|
||||
|
||||
@@ -47,12 +47,13 @@ const (
|
||||
StatusStaging = "Staging"
|
||||
)
|
||||
|
||||
// EnvMeta stores the info for app environment
|
||||
// Config contains key/value pairs
|
||||
type Config map[string]string
|
||||
|
||||
// EnvMeta stores the namespace for app environment
|
||||
type EnvMeta struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
|
||||
Current string `json:"current,omitempty"`
|
||||
}
|
||||
|
||||
@@ -188,6 +188,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -454,6 +468,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -193,6 +193,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -440,6 +454,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -19,3 +19,6 @@ 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
|
||||
|
||||
home: https://kubevela.io
|
||||
icon: https://kubevela.io/img/logo.jpg
|
||||
|
||||
@@ -1232,6 +1232,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -1621,6 +1635,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -1908,6 +1936,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3318,6 +3360,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3600,6 +3656,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3971,6 +4041,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -4221,6 +4305,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -4487,6 +4585,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -179,6 +179,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -449,6 +463,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -222,6 +222,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -492,6 +506,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -755,6 +783,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -999,6 +1041,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -151,6 +151,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -188,6 +188,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -454,6 +468,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.6.2
|
||||
name: workflows.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: Workflow
|
||||
listKind: WorkflowList
|
||||
plural: workflows
|
||||
shortNames:
|
||||
- workflow
|
||||
singular: workflow
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.phase
|
||||
name: PHASE
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: AGE
|
||||
type: date
|
||||
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
|
||||
spec:
|
||||
description: A WorkflowSpec defines the desired state of a Workflow.
|
||||
properties:
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStep defines how to execute a workflow step.
|
||||
properties:
|
||||
inputs:
|
||||
description: StepInputs defines variable input of WorkflowStep
|
||||
items:
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
parameterKey:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- parameterKey
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
description: Name is the unique name of the workflow step.
|
||||
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
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
status:
|
||||
description: A WorkflowStatus is the status of Workflow
|
||||
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
|
||||
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.
|
||||
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
|
||||
observedGeneration:
|
||||
format: int64
|
||||
type: integer
|
||||
stepIndex:
|
||||
type: integer
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStepStatus record the status of a workflow
|
||||
step
|
||||
properties:
|
||||
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
|
||||
resourceRef:
|
||||
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. 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
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- suspend
|
||||
- terminated
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
- name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Workflow defines workflow steps and other attributes
|
||||
properties:
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStep defines how to execute a workflow step.
|
||||
properties:
|
||||
dependsOn:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
inputs:
|
||||
description: StepInputs defines variable input of WorkflowStep
|
||||
items:
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
parameterKey:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- parameterKey
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
description: Name is the unique name of the workflow step.
|
||||
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
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -148,6 +148,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -193,6 +193,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -440,6 +454,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
apiVersion: v1
|
||||
data:
|
||||
initializer: |
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Initializer
|
||||
metadata:
|
||||
annotations:
|
||||
addons.oam.dev/description: Kubernetes Terraform Controller for Azure
|
||||
addons.oam.dev/name: terraform/provider-azure
|
||||
name: terraform-provider-azure
|
||||
namespace: default
|
||||
spec:
|
||||
appTemplate:
|
||||
spec:
|
||||
components:
|
||||
- name: azure-account-creds
|
||||
properties:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: azure-account-creds
|
||||
namespace: vela-system
|
||||
stringData:
|
||||
credentials: |
|
||||
armClientID: [[ index .Args "ARM_CLIENT_ID" ]]
|
||||
armClientSecret: [[ index .Args "ARM_CLIENT_SECRET" ]]
|
||||
armSubscriptionID: [[ index .Args "ARM_SUBSCRIPTION_ID" ]]
|
||||
armTenantID: [[ index .Args "ARM_TENANT_ID" ]]
|
||||
type: Opaque
|
||||
type: raw
|
||||
- name: azure
|
||||
properties:
|
||||
apiVersion: terraform.core.oam.dev/v1beta1
|
||||
kind: Provider
|
||||
metadata:
|
||||
name: azure
|
||||
namespace: default
|
||||
spec:
|
||||
credentials:
|
||||
secretRef:
|
||||
key: credentials
|
||||
name: azure-account-creds
|
||||
namespace: vela-system
|
||||
source: Secret
|
||||
provider: azure
|
||||
type: raw
|
||||
status:
|
||||
rollout:
|
||||
batchRollingState: ""
|
||||
currentBatch: 0
|
||||
lastTargetAppRevision: ""
|
||||
rollingState: ""
|
||||
upgradedReadyReplicas: 0
|
||||
upgradedReplicas: 0
|
||||
status:
|
||||
observedGeneration: 0
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
annotations:
|
||||
addons.oam.dev/description: Kubernetes Terraform Controller for Azure
|
||||
addons.oam.dev/name: terraform/provider-azure
|
||||
labels:
|
||||
addons.oam.dev/type: terraform-provider-azure
|
||||
name: terraform-provider-azure
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
@@ -354,6 +354,83 @@ data:
|
||||
apiVersion: terraform.core.oam.dev/v1beta1
|
||||
kind: Configuration
|
||||
type: raw
|
||||
- name: azure-database-mariadb
|
||||
properties:
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Terraform configuration for Azure Database
|
||||
Mariadb
|
||||
provider: azure
|
||||
labels:
|
||||
type: terraform
|
||||
name: azure-database-mariadb
|
||||
namespace: vela-system
|
||||
spec:
|
||||
schematic:
|
||||
terraform:
|
||||
configuration: |
|
||||
# Configure the Microsoft Azure Provider
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
|
||||
resource "azurerm_resource_group" "example" {
|
||||
name = "tfex-mariadb-database-RG"
|
||||
location = "West Europe"
|
||||
}
|
||||
|
||||
resource "azurerm_mariadb_server" "example" {
|
||||
name = "mariadb-svr-sample"
|
||||
location = azurerm_resource_group.example.location
|
||||
resource_group_name = azurerm_resource_group.example.name
|
||||
|
||||
sku_name = "B_Gen5_2"
|
||||
|
||||
storage_mb = 51200
|
||||
backup_retention_days = 7
|
||||
geo_redundant_backup_enabled = false
|
||||
|
||||
administrator_login = var.username
|
||||
administrator_login_password = var.password
|
||||
version = "10.2"
|
||||
ssl_enforcement_enabled = true
|
||||
}
|
||||
|
||||
resource "azurerm_mariadb_database" "example" {
|
||||
name = var.name
|
||||
resource_group_name = azurerm_resource_group.example.name
|
||||
server_name = azurerm_mariadb_server.example.name
|
||||
charset = "utf8"
|
||||
collation = "utf8_general_ci"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
default = "mariadb_database"
|
||||
type = string
|
||||
description = "Database instance name"
|
||||
}
|
||||
|
||||
variable "username" {
|
||||
default = "acctestun"
|
||||
type = string
|
||||
description = "Database instance username"
|
||||
}
|
||||
|
||||
variable "password" {
|
||||
default = "H@Sh1CoR3!faked"
|
||||
type = string
|
||||
description = "Database instance password"
|
||||
}
|
||||
providerRef:
|
||||
name: azure
|
||||
namespace: default
|
||||
workload:
|
||||
definition:
|
||||
apiVersion: terraform.core.oam.dev/v1beta1
|
||||
kind: Configuration
|
||||
type: raw
|
||||
status:
|
||||
rollout:
|
||||
batchRollingState: ""
|
||||
|
||||
@@ -32,12 +32,28 @@ spec:
|
||||
- "--secure-port={{ .Values.multicluster.clusterGateway.port }}"
|
||||
- "--secret-namespace={{ .Release.Namespace }}"
|
||||
- "--feature-gates=APIPriorityAndFairness=false"
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
- "--cert-dir={{ .Values.multicluster.clusterGateway.secureTLS.certPath }}"
|
||||
{{ end }}
|
||||
image: {{ .Values.multicluster.clusterGateway.image.repository }}:{{ .Values.multicluster.clusterGateway.image.tag }}
|
||||
imagePullPolicy: {{ .Values.multicluster.clusterGateway.image.pullPolicy }}
|
||||
resources:
|
||||
{{- toYaml .Values.multicluster.clusterGateway.resources | nindent 12 }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.multicluster.clusterGateway.port }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
volumeMounts:
|
||||
- mountPath: {{ .Values.multicluster.clusterGateway.secureTLS.certPath }}
|
||||
name: tls-cert-vol
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
volumes:
|
||||
- name: tls-cert-vol
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: {{ template "kubevela.fullname" . }}-cluster-gateway-tls
|
||||
{{ end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
@@ -84,5 +100,92 @@ spec:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
port: {{ .Values.multicluster.clusterGateway.port }}
|
||||
versionPriority: 10
|
||||
insecureSkipTLSVerify: true
|
||||
insecureSkipTLSVerify: {{ not .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
caBundle: Cg==
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
{{- include "kubevela.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
|
||||
# Alpha feature since k8s 1.12
|
||||
ttlSecondsAfterFinished: 0
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: create
|
||||
image: {{ .Values.admissionWebhooks.patch.image.repository }}:{{ .Values.admissionWebhooks.patch.image.tag }}
|
||||
imagePullPolicy: {{ .Values.admissionWebhooks.patch.image.pullPolicy }}
|
||||
args:
|
||||
- create
|
||||
- --host={{ .Release.Name }}-cluster-gateway-service,{{ .Release.Name }}-cluster-gateway-service.{{ .Release.Namespace }}.svc
|
||||
- --namespace={{ .Release.Namespace }}
|
||||
- --secret-name={{ template "kubevela.fullname" . }}-cluster-gateway-tls
|
||||
- --key-name=apiserver.key
|
||||
- --cert-name=apiserver.crt
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: {{ template "kubevela.fullname" . }}-admission
|
||||
securityContext:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,post-upgrade
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
{{- include "kubevela.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
|
||||
# Alpha feature since k8s 1.12
|
||||
ttlSecondsAfterFinished: 0
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: patch
|
||||
image: {{ .Values.multicluster.clusterGateway.image.repository }}:{{ .Values.multicluster.clusterGateway.image.tag }}
|
||||
imagePullPolicy: {{ .Values.multicluster.clusterGateway.image.pullPolicy }}
|
||||
command:
|
||||
- /patch
|
||||
args:
|
||||
- --secret-namespace={{ .Release.Namespace }}
|
||||
- --secret-name={{ template "kubevela.fullname" . }}-cluster-gateway-tls
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: {{ include "kubevela.serviceAccountName" . }}
|
||||
securityContext:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{ end }}
|
||||
22
charts/vela-core/templates/defwithtemplate/apply-object.yaml
Normal file
22
charts/vela-core/templates/defwithtemplate/apply-object.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/apply-object.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Apply raw kubernetes objects for your workflow steps
|
||||
name: apply-object
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"vela/op"
|
||||
)
|
||||
|
||||
apply: op.#Apply & {
|
||||
value: parameter
|
||||
}
|
||||
parameter: {}
|
||||
|
||||
@@ -27,7 +27,7 @@ spec:
|
||||
}
|
||||
}
|
||||
load: op.#Steps & {
|
||||
if dependsOn.err != _|_ {
|
||||
if dependsOn.err != _|_ && dependsOn.value == _|_ {
|
||||
configMap: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
@@ -43,18 +43,16 @@ spec:
|
||||
yaml.Unmarshal(configMap.value.data[parameter.name])
|
||||
}
|
||||
}
|
||||
}
|
||||
if dependsOn.err == _|_ {
|
||||
apply: op.#Apply & {
|
||||
value: {
|
||||
dependsOn.value
|
||||
}
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: load.apply.value.status.status == "running"
|
||||
}
|
||||
}
|
||||
|
||||
if dependsOn.value != _|_ {
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: dependsOn.value.status.status == "running"
|
||||
}
|
||||
}
|
||||
}
|
||||
phase: load.apply.value.status.status
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: phase == "running"
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the name of the dependent Application
|
||||
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
// +patchKey=name
|
||||
containers: [{
|
||||
name: context.name
|
||||
// +patchKey=name
|
||||
// +patchStrategy=retainKeys
|
||||
env: [
|
||||
for k, v in parameter.env {
|
||||
name: k
|
||||
|
||||
@@ -30,7 +30,10 @@ spec:
|
||||
outputs: ingress: {
|
||||
apiVersion: "networking.k8s.io/v1"
|
||||
kind: "Ingress"
|
||||
metadata: name: context.name
|
||||
metadata: {
|
||||
name: context.name
|
||||
annotations: "kubernetes.io/ingress.class": parameter.class
|
||||
}
|
||||
spec: rules: [{
|
||||
host: parameter.domain
|
||||
http: paths: [
|
||||
@@ -51,6 +54,9 @@ spec:
|
||||
|
||||
// +usage=Specify the mapping relationship between the http path and the workload port
|
||||
http: [string]: int
|
||||
|
||||
// +usage=Specify the class of ingress to use
|
||||
class: *"nginx" | string
|
||||
}
|
||||
status:
|
||||
customStatus: |-
|
||||
|
||||
@@ -50,7 +50,7 @@ spec:
|
||||
},
|
||||
]
|
||||
}
|
||||
outputs: pvc: {
|
||||
outputs: "\(parameter.claimName)": {
|
||||
apiVersion: "v1"
|
||||
kind: "PersistentVolumeClaim"
|
||||
metadata: name: parameter.claimName
|
||||
|
||||
@@ -29,9 +29,9 @@ spec:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
args:
|
||||
- "apiserver"
|
||||
- "--bind-addr=0.0.0.0:{{ .Values.apiServer.port }}"
|
||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
|
||||
- "--port={{ .Values.apiServer.port }}"
|
||||
image: {{ .Values.apiserverImage.repository }}:{{ .Values.apiserverImage.tag }}
|
||||
imagePullPolicy: {{ quote .Values.apiserverImage.pullPolicy }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
ports:
|
||||
|
||||
@@ -11,6 +11,10 @@ image:
|
||||
repository: oamdev/vela-core
|
||||
tag: latest
|
||||
pullPolicy: Always
|
||||
apiserverImage:
|
||||
repository: oamdev/vela-apiserver
|
||||
tag: v1.1.2
|
||||
pullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
@@ -118,9 +122,12 @@ multicluster:
|
||||
port: 9443
|
||||
image:
|
||||
repository: oamdev/cluster-gateway
|
||||
tag: v1.1.1
|
||||
tag: v1.1.3
|
||||
pullPolicy: Always
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 200Mi
|
||||
memory: 200Mi
|
||||
secureTLS:
|
||||
enabled: true
|
||||
certPath: /etc/k8s-cluster-gateway-certs
|
||||
@@ -19,3 +19,6 @@ 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
|
||||
|
||||
home: https://kubevela.io
|
||||
icon: https://kubevela.io/img/logo.jpg
|
||||
@@ -1232,6 +1232,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -1621,6 +1635,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -1908,6 +1936,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3318,6 +3360,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3600,6 +3656,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3971,6 +4041,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -4221,6 +4305,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -4487,6 +4585,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -222,6 +222,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -492,6 +506,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -755,6 +783,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -999,6 +1041,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -151,6 +151,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -188,6 +188,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -454,6 +468,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -148,6 +148,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -193,6 +193,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -440,6 +454,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -32,12 +32,28 @@ spec:
|
||||
- "--secure-port={{ .Values.multicluster.clusterGateway.port }}"
|
||||
- "--secret-namespace={{ .Release.Namespace }}"
|
||||
- "--feature-gates=APIPriorityAndFairness=false"
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
- "--cert-dir={{ .Values.multicluster.clusterGateway.secureTLS.certPath }}"
|
||||
{{ end }}
|
||||
image: {{ .Values.multicluster.clusterGateway.image.repository }}:{{ .Values.multicluster.clusterGateway.image.tag }}
|
||||
imagePullPolicy: {{ .Values.multicluster.clusterGateway.image.pullPolicy }}
|
||||
resources:
|
||||
{{- toYaml .Values.multicluster.clusterGateway.resources | nindent 12 }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.multicluster.clusterGateway.port }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
volumeMounts:
|
||||
- mountPath: {{ .Values.multicluster.clusterGateway.secureTLS.certPath }}
|
||||
name: tls-cert-vol
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
volumes:
|
||||
- name: tls-cert-vol
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: {{ template "kubevela.fullname" . }}-cluster-gateway-tls
|
||||
{{ end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
@@ -50,9 +66,9 @@ spec:
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
---
|
||||
{{ if .Values.multicluster.enabled }}
|
||||
{{ if .Values.multicluster.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -65,9 +81,9 @@ spec:
|
||||
- protocol: TCP
|
||||
port: {{ .Values.multicluster.clusterGateway.port }}
|
||||
targetPort: {{ .Values.multicluster.clusterGateway.port }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
---
|
||||
{{ if .Values.multicluster.enabled }}
|
||||
{{ if .Values.multicluster.enabled }}
|
||||
apiVersion: apiregistration.k8s.io/v1
|
||||
kind: APIService
|
||||
metadata:
|
||||
@@ -84,5 +100,92 @@ spec:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
port: {{ .Values.multicluster.clusterGateway.port }}
|
||||
versionPriority: 10
|
||||
insecureSkipTLSVerify: true
|
||||
{{ end }}
|
||||
insecureSkipTLSVerify: {{ not .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
caBundle: Cg==
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
{{- include "kubevela.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
|
||||
# Alpha feature since k8s 1.12
|
||||
ttlSecondsAfterFinished: 0
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-create
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: create
|
||||
image: {{ .Values.admissionWebhooks.patch.image.repository }}:{{ .Values.admissionWebhooks.patch.image.tag }}
|
||||
imagePullPolicy: {{ .Values.admissionWebhooks.patch.image.pullPolicy }}
|
||||
args:
|
||||
- create
|
||||
- --host={{ .Release.Name }}-cluster-gateway-service,{{ .Release.Name }}-cluster-gateway-service.{{ .Release.Namespace }}.svc
|
||||
- --namespace={{ .Release.Namespace }}
|
||||
- --secret-name={{ template "kubevela.fullname" . }}-cluster-gateway-tls
|
||||
- --key-name=apiserver.key
|
||||
- --cert-name=apiserver.crt
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: {{ template "kubevela.fullname" . }}-admission
|
||||
securityContext:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{ end }}
|
||||
---
|
||||
{{ if and .Values.multicluster.enabled .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-install,post-upgrade
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
{{- include "kubevela.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
|
||||
# Alpha feature since k8s 1.12
|
||||
ttlSecondsAfterFinished: 0
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
labels:
|
||||
app: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-secret-patch
|
||||
{{- include "kubevela.labels" . | nindent 8 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: patch
|
||||
image: {{ .Values.multicluster.clusterGateway.image.repository }}:{{ .Values.multicluster.clusterGateway.image.tag }}
|
||||
imagePullPolicy: {{ .Values.multicluster.clusterGateway.image.pullPolicy }}
|
||||
command:
|
||||
- /patch
|
||||
args:
|
||||
- --secret-namespace={{ .Release.Namespace }}
|
||||
- --secret-name={{ template "kubevela.fullname" . }}-cluster-gateway-tls
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: {{ include "kubevela.serviceAccountName" . }}
|
||||
securityContext:
|
||||
runAsGroup: 2000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 2000
|
||||
{{ end }}
|
||||
@@ -0,0 +1,22 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/apply-object.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Apply raw kubernetes objects for your workflow steps
|
||||
name: apply-object
|
||||
namespace: {{.Values.systemDefinitionNamespace}}
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"vela/op"
|
||||
)
|
||||
|
||||
apply: op.#Apply & {
|
||||
value: parameter
|
||||
}
|
||||
parameter: {}
|
||||
|
||||
@@ -27,7 +27,7 @@ spec:
|
||||
}
|
||||
}
|
||||
load: op.#Steps & {
|
||||
if dependsOn.err != _|_ {
|
||||
if dependsOn.err != _|_ && dependsOn.value == _|_ {
|
||||
configMap: op.#Read & {
|
||||
value: {
|
||||
apiVersion: "v1"
|
||||
@@ -43,18 +43,16 @@ spec:
|
||||
yaml.Unmarshal(configMap.value.data[parameter.name])
|
||||
}
|
||||
}
|
||||
}
|
||||
if dependsOn.err == _|_ {
|
||||
apply: op.#Apply & {
|
||||
value: {
|
||||
dependsOn.value
|
||||
}
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: load.apply.value.status.status == "running"
|
||||
}
|
||||
}
|
||||
|
||||
if dependsOn.value != _|_ {
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: dependsOn.value.status.status == "running"
|
||||
}
|
||||
}
|
||||
}
|
||||
phase: load.apply.value.status.status
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: phase == "running"
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the name of the dependent Application
|
||||
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
// +patchKey=name
|
||||
containers: [{
|
||||
name: context.name
|
||||
// +patchKey=name
|
||||
// +patchStrategy=retainKeys
|
||||
env: [
|
||||
for k, v in parameter.env {
|
||||
name: k
|
||||
|
||||
@@ -30,7 +30,10 @@ spec:
|
||||
outputs: ingress: {
|
||||
apiVersion: "networking.k8s.io/v1"
|
||||
kind: "Ingress"
|
||||
metadata: name: context.name
|
||||
metadata: {
|
||||
name: context.name
|
||||
annotations: "kubernetes.io/ingress.class": parameter.class
|
||||
}
|
||||
spec: rules: [{
|
||||
host: parameter.domain
|
||||
http: paths: [
|
||||
@@ -51,6 +54,9 @@ spec:
|
||||
|
||||
// +usage=Specify the mapping relationship between the http path and the workload port
|
||||
http: [string]: int
|
||||
|
||||
// +usage=Specify the class of ingress to use
|
||||
class: *"nginx" | string
|
||||
}
|
||||
status:
|
||||
customStatus: |-
|
||||
|
||||
@@ -50,7 +50,7 @@ spec:
|
||||
},
|
||||
]
|
||||
}
|
||||
outputs: pvc: {
|
||||
outputs: "\(parameter.claimName)": {
|
||||
apiVersion: "v1"
|
||||
kind: "PersistentVolumeClaim"
|
||||
metadata: name: parameter.claimName
|
||||
|
||||
@@ -117,9 +117,12 @@ multicluster:
|
||||
port: 9443
|
||||
image:
|
||||
repository: oamdev/cluster-gateway
|
||||
tag: v1.1.1
|
||||
tag: v1.1.3
|
||||
pullPolicy: Always
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 200Mi
|
||||
memory: 200Mi
|
||||
secureTLS:
|
||||
enabled: true
|
||||
certPath: /etc/k8s-cluster-gateway-certs
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/klog/v2"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -206,7 +207,7 @@ func main() {
|
||||
LeaseDuration: &leaseDuration,
|
||||
RenewDeadline: &renewDeadline,
|
||||
RetryPeriod: &retryPeriod,
|
||||
ClientDisableCacheFor: []client.Object{&v1beta1.ResourceTracker{}},
|
||||
ClientDisableCacheFor: []client.Object{&v1beta1.ResourceTracker{}, &appsv1.ControllerRevision{}},
|
||||
})
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Unable to create a controller manager")
|
||||
@@ -325,8 +326,11 @@ func waitWebhookSecretVolume(certDir string, timeout, interval time.Duration) er
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// nolint
|
||||
defer f.Close()
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
klog.Error(err, "Failed to close file")
|
||||
}
|
||||
}()
|
||||
// check if dir is empty
|
||||
if _, err := f.Readdir(1); errors.Is(err, io.EOF) {
|
||||
return false
|
||||
|
||||
54
docs/examples/advanced-cue/mysql-pvc.yaml
Normal file
54
docs/examples/advanced-cue/mysql-pvc.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: mysql-pvc
|
||||
spec:
|
||||
components:
|
||||
- name: mysql
|
||||
type: webservice
|
||||
properties:
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
value: root
|
||||
image: mysql:5.7
|
||||
port: 3306
|
||||
cpu: 1000m
|
||||
memory: 500M
|
||||
traits:
|
||||
- type: ingress
|
||||
properties:
|
||||
http:
|
||||
/: 13666
|
||||
domain: com.zdww1
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
- type: cpuscaler
|
||||
properties:
|
||||
cpuUtil: 70
|
||||
min: 1
|
||||
max: 3
|
||||
- type: pvc
|
||||
properties:
|
||||
claimName: aaa
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: nfs-dynamic-sc
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
volumesToMount:
|
||||
- mountPath: /aaa
|
||||
name: aaa
|
||||
- type: pvc
|
||||
properties:
|
||||
claimName: bbb
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: nfs-dynamic-sc
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
volumesToMount:
|
||||
- mountPath: /bbb
|
||||
name: bbb
|
||||
78
docs/examples/envbinding/example.yaml
Normal file
78
docs/examples/envbinding/example.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: example-app
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: hello-world-server
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
port: 8000
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
- name: data-worker
|
||||
type: worker
|
||||
properties:
|
||||
image: busybox
|
||||
cmd:
|
||||
- sleep
|
||||
- '1000000'
|
||||
policies:
|
||||
- name: example-multi-env-policy
|
||||
type: env-binding
|
||||
properties:
|
||||
envs:
|
||||
- name: test
|
||||
placement: # selecting the namespace (in local cluster) to deploy to
|
||||
namespaceSelector:
|
||||
name: test
|
||||
selector:
|
||||
components:
|
||||
- data-worker
|
||||
|
||||
- name: staging
|
||||
placement: # selecting the cluster to deploy to
|
||||
clusterSelector:
|
||||
name: cluster-worker
|
||||
|
||||
- name: prod
|
||||
placement: # selecting both namespace and cluster to deploy to
|
||||
clusterSelector:
|
||||
name: cluster-worker
|
||||
namespaceSelector:
|
||||
name: prod
|
||||
patch: # overlay patch on above components
|
||||
components:
|
||||
- name: hello-world-server
|
||||
type: webservice
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 3
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
# deploy to test env
|
||||
- name: deploy-test
|
||||
type: deploy2env
|
||||
properties:
|
||||
policy: example-multi-env-policy
|
||||
env: test
|
||||
|
||||
# deploy to staging env
|
||||
- name: deploy-staging
|
||||
type: deploy2env
|
||||
properties:
|
||||
policy: example-multi-env-policy
|
||||
env: staging
|
||||
|
||||
# deploy to prod env
|
||||
- name: deploy-prod
|
||||
type: deploy2env
|
||||
properties:
|
||||
policy: example-multi-env-policy
|
||||
env: prod
|
||||
39
docs/examples/workflow/apply-object/app.yaml
Normal file
39
docs/examples/workflow/apply-object/app.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: server-with-pvc
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: express-server
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
port: 8000
|
||||
volumes:
|
||||
- name: "my-pvc"
|
||||
type: "pvc"
|
||||
mountPath: "/test"
|
||||
claimName: "myclaim"
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: apply-pvc
|
||||
type: apply-object
|
||||
properties:
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: myclaim
|
||||
namespace: default
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 8Gi
|
||||
storageClassName: standard
|
||||
- name: apply-server
|
||||
type: apply-component
|
||||
properties:
|
||||
component: express-server
|
||||
@@ -1,56 +0,0 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
name: apply-component
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import ("vela/op")
|
||||
parameter: {
|
||||
component: string
|
||||
prefixIP?: string
|
||||
}
|
||||
|
||||
load: op.#Load
|
||||
|
||||
// apply workload to kubernetes cluster
|
||||
apply: op.#ApplyComponent & {
|
||||
value: load.value[parameter.component]
|
||||
}
|
||||
|
||||
// wait until workload.status equal "Running"
|
||||
wait: op.#ConditionalWait & {
|
||||
continue: apply.output.status.phase =="Running"
|
||||
}
|
||||
|
||||
// export podIP
|
||||
myIP: apply.output.status.podIP
|
||||
---
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
name: apply-remaining
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import ("vela/op")
|
||||
parameter: {
|
||||
exceptions?: [componentName=string]: {
|
||||
// skipApplyWorkload indicates whether to skip apply the workload resource
|
||||
skipApplyWorkload: *true | bool
|
||||
|
||||
// skipAllTraits indicates to skip apply all resources of the traits.
|
||||
// If this is true, skipApplyTraits will be ignored
|
||||
skipAllTraits: *true| bool
|
||||
|
||||
// skipApplyTraits specifies the names of the traits to skip apply
|
||||
skipApplyTraits: [...string]
|
||||
}
|
||||
}
|
||||
|
||||
apply: op.#ApplyRemaining & {
|
||||
parameter
|
||||
}
|
||||
|
||||
26
docs/examples/workflow/depends-on-app/app.yaml
Normal file
26
docs/examples/workflow/depends-on-app/app.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: kruise
|
||||
namespace: vela-system
|
||||
spec:
|
||||
components:
|
||||
- name: kruise
|
||||
type: helm
|
||||
properties:
|
||||
branch: master
|
||||
chart: ./charts/kruise/v0.9.0
|
||||
version: "*"
|
||||
repoType: git
|
||||
url: https://github.com/openkruise/kruise
|
||||
workflow:
|
||||
steps:
|
||||
- name: check-flux
|
||||
type: depends-on-app
|
||||
properties:
|
||||
name: fluxcd
|
||||
namespace: vela-system
|
||||
- name: apply-kruise
|
||||
type: apply-component
|
||||
properties:
|
||||
component: kruise
|
||||
@@ -111,7 +111,7 @@ var ApplicationExecContext = func(context string, appName string) bool {
|
||||
|
||||
var ApplicationPortForwardContext = func(context string, appName string) bool {
|
||||
return ginkgo.Context(context, func() {
|
||||
ginkgo.It("should get output of portward successfully", func() {
|
||||
ginkgo.It("should get output of port-forward successfully", func() {
|
||||
cli := fmt.Sprintf("vela port-forward %s 80:80 ", appName)
|
||||
output, err := e2e.ExecAndTerminate(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
@@ -128,14 +128,6 @@ var ApplicationInitIntercativeCliContext = func(context string, appName string,
|
||||
data := []struct {
|
||||
q, a string
|
||||
}{
|
||||
{
|
||||
q: "What is the domain of your application service (optional): ",
|
||||
a: "testdomain",
|
||||
},
|
||||
{
|
||||
q: "What is your email (optional, used to generate certification): ",
|
||||
a: "test@mail",
|
||||
},
|
||||
{
|
||||
q: "What would you like to name your application (required): ",
|
||||
a: appName,
|
||||
|
||||
@@ -100,8 +100,14 @@ func InteractiveExec(cli string, consoleFn func(*expect.Console)) (string, error
|
||||
command.Stdin = console.Tty()
|
||||
|
||||
session, err := gexec.Start(command, console.Tty(), console.Tty())
|
||||
if err != nil {
|
||||
return string(output), err
|
||||
}
|
||||
s := session.Wait(300 * time.Second)
|
||||
console.Tty().Close()
|
||||
err = console.Tty().Close()
|
||||
if err != nil {
|
||||
return string(output), err
|
||||
}
|
||||
<-doneC
|
||||
if err != nil {
|
||||
return string(output), err
|
||||
|
||||
@@ -33,7 +33,7 @@ var (
|
||||
cli := fmt.Sprintf("vela env init %s", envName)
|
||||
output, err := Exec(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
expectedOutput := fmt.Sprintf("environment %s created,", envName)
|
||||
expectedOutput := fmt.Sprintf("environment %s created", envName)
|
||||
gomega.Expect(output).To(gomega.ContainSubstring(expectedOutput))
|
||||
})
|
||||
})
|
||||
@@ -45,7 +45,7 @@ var (
|
||||
cli := fmt.Sprintf("vela env init %s --namespace %s", envName, namespace)
|
||||
output, err := Exec(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
expectedOutput := fmt.Sprintf("environment %s created,", envName)
|
||||
expectedOutput := fmt.Sprintf("environment %s created", envName)
|
||||
gomega.Expect(output).To(gomega.ContainSubstring(expectedOutput))
|
||||
})
|
||||
})
|
||||
|
||||
2
e2e/env/env_test.go
vendored
2
e2e/env/env_test.go
vendored
@@ -32,7 +32,7 @@ var _ = ginkgo.Describe("Env", func() {
|
||||
e2e.EnvInitContext("env init", envName)
|
||||
e2e.EnvInitContext("env init another one", envName2)
|
||||
e2e.EnvShowContext("env show", envName)
|
||||
e2e.EnvSetContext("env sw", envName)
|
||||
e2e.EnvSetContext("env set", envName)
|
||||
|
||||
ginkgo.Context("env list", func() {
|
||||
ginkgo.It("should list all envs", func() {
|
||||
|
||||
6
go.mod
6
go.mod
@@ -10,7 +10,7 @@ require (
|
||||
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869
|
||||
github.com/briandowns/spinner v1.11.1
|
||||
github.com/containerd/containerd v1.4.8
|
||||
github.com/containerd/containerd v1.4.11
|
||||
github.com/coreos/prometheus-operator v0.41.1
|
||||
github.com/crossplane/crossplane-runtime v0.14.1-0.20210722005935-0b469fcc77cd
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
@@ -32,9 +32,9 @@ require (
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1
|
||||
github.com/oam-dev/cluster-gateway v0.0.0-20210907072424-2f8720b116f8
|
||||
github.com/oam-dev/cluster-gateway v1.1.2
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28
|
||||
github.com/oam-dev/terraform-controller v0.2.0
|
||||
github.com/oam-dev/terraform-controller v0.2.1
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/onsi/ginkgo v1.16.4
|
||||
github.com/onsi/gomega v1.16.0
|
||||
|
||||
17
go.sum
17
go.sum
@@ -307,8 +307,8 @@ github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on
|
||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.8 h1:H0wkS4AbVKTg9vyvBdCBrxoax8AMObKbNz9Fl2N0i4Y=
|
||||
github.com/containerd/containerd v1.4.8/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.11 h1:QCGOUN+i70jEEL/A6JVIbhy4f4fanzAzSR4kNG7SlcE=
|
||||
github.com/containerd/containerd v1.4.11/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7 h1:6ejg6Lkk8dskcM7wQ28gONkukbQkM4qpj4RnYbpFzrI=
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||
@@ -580,7 +580,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||
github.com/go-openapi/swag v0.19.6/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
||||
github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
||||
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
|
||||
github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
|
||||
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/validate v0.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
@@ -1201,14 +1200,14 @@ github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oam-dev/cluster-gateway v0.0.0-20210907072424-2f8720b116f8 h1:aTfUhMr6DC+jTiBvCzv+fcgqBvIoGLvrnmXjIUgib7I=
|
||||
github.com/oam-dev/cluster-gateway v0.0.0-20210907072424-2f8720b116f8/go.mod h1:ZB7/tubU3MtdQ9bzQjksjO8UK+9e0Wrw3HAqKdY/lZY=
|
||||
github.com/oam-dev/cluster-gateway v1.1.2 h1:sxC8Uyx/d3Yu8nIFSz31i+4JKhJfDAS9XVIPEWa1y+Q=
|
||||
github.com/oam-dev/cluster-gateway v1.1.2/go.mod h1:EjPUZwTYBe+gFtPV/yGohLE19fDr3CUg4tfSRY72fkM=
|
||||
github.com/oam-dev/stern v1.13.0-alpha h1:EVjM8Qvh6LssB6t4RZrjf9DtCq1cz+/cy6OF7fpy9wk=
|
||||
github.com/oam-dev/stern v1.13.0-alpha/go.mod h1:AOkvfFUv0Arz7GBi0jz7S0Jsu4K/kdvSjNsnRt1+BIg=
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28 h1:tD8HiFKnt0jnwdTWjeqUnfnUYLD/+Nsmj8ZGIxqDWiU=
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28/go.mod h1:Mu8i0/DdplvnjwRbAYPsc8+LRR27n/mp8VWdkN10GzE=
|
||||
github.com/oam-dev/terraform-controller v0.2.0 h1:GBQ+CvXtY9bcRkwGaPYHbYFkbVWzDExc05hz0NL0rqs=
|
||||
github.com/oam-dev/terraform-controller v0.2.0/go.mod h1:wd4rnqnJzz274Sg1/qoeIhBx1rvTZ/ECzXoMff0ucR0=
|
||||
github.com/oam-dev/terraform-controller v0.2.1 h1:gGXcUDBMWKfWet84STm99RX6gXo89pyTRsgQSLq2mog=
|
||||
github.com/oam-dev/terraform-controller v0.2.1/go.mod h1:5Vy6jLx9fjotEd6E005Ve1f0x3fEpVlG/DVjmqLjAq0=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
@@ -2523,8 +2522,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyz
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22 h1:fmRfl9WJ4ApJn7LxNuED4m0t18qivVQOxP6aAYG9J6c=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-runtime v1.0.3-0.20210906132642-810075b08b5f h1:RM+QxWPIZi3mo3i4fiUSvyFELyKr7jjMSJ5EEmt+i6M=
|
||||
sigs.k8s.io/apiserver-runtime v1.0.3-0.20210906132642-810075b08b5f/go.mod h1:ynhMgoDTl6cihO5OpeV95iG+3bzKfHwWQU2VSbmoNmk=
|
||||
sigs.k8s.io/apiserver-runtime v1.0.3-0.20210913073608-0663f60bfee2 h1:c6RYHA1wUg9IEsfjnxg0WsPwvDC2Qw2eryXKXgSEF1c=
|
||||
sigs.k8s.io/apiserver-runtime v1.0.3-0.20210913073608-0663f60bfee2/go.mod h1:gvPfh5FX3Wi3kIRpkh7qvY0i/DQl3SDpRtvqMGZE3Vo=
|
||||
sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
|
||||
sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E=
|
||||
sigs.k8s.io/controller-runtime v0.9.2/go.mod h1:TxzMCHyEUpaeuOiZx/bIdc2T81vfs/aKdvJt9wuu0zk=
|
||||
|
||||
@@ -1232,6 +1232,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -1621,6 +1635,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -1908,6 +1936,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3318,6 +3360,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3600,6 +3656,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -3971,6 +4041,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -4221,6 +4305,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -4487,6 +4585,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -179,6 +179,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -449,6 +463,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -222,6 +222,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -492,6 +506,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -755,6 +783,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -999,6 +1041,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -151,6 +151,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -188,6 +188,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -454,6 +468,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.6.2
|
||||
name: workflows.core.oam.dev
|
||||
spec:
|
||||
group: core.oam.dev
|
||||
names:
|
||||
categories:
|
||||
- oam
|
||||
kind: Workflow
|
||||
listKind: WorkflowList
|
||||
plural: workflows
|
||||
shortNames:
|
||||
- workflow
|
||||
singular: workflow
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.phase
|
||||
name: PHASE
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: AGE
|
||||
type: date
|
||||
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
|
||||
spec:
|
||||
description: A WorkflowSpec defines the desired state of a Workflow.
|
||||
properties:
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStep defines how to execute a workflow step.
|
||||
properties:
|
||||
inputs:
|
||||
description: StepInputs defines variable input of WorkflowStep
|
||||
items:
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
parameterKey:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- parameterKey
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
description: Name is the unique name of the workflow step.
|
||||
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
|
||||
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
status:
|
||||
description: A WorkflowStatus is the status of Workflow
|
||||
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
|
||||
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.
|
||||
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
|
||||
observedGeneration:
|
||||
format: int64
|
||||
type: integer
|
||||
stepIndex:
|
||||
type: integer
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStepStatus record the status of a workflow
|
||||
step
|
||||
properties:
|
||||
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
|
||||
resourceRef:
|
||||
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. 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
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
suspend:
|
||||
type: boolean
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- suspend
|
||||
- terminated
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
- name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Workflow defines workflow steps and other attributes
|
||||
properties:
|
||||
steps:
|
||||
items:
|
||||
description: WorkflowStep defines how to execute a workflow step.
|
||||
properties:
|
||||
dependsOn:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
inputs:
|
||||
description: StepInputs defines variable input of WorkflowStep
|
||||
items:
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
parameterKey:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- parameterKey
|
||||
type: object
|
||||
type: array
|
||||
name:
|
||||
description: Name is the unique name of the workflow step.
|
||||
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
|
||||
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
served: true
|
||||
storage: false
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -148,6 +148,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -193,6 +193,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
@@ -440,6 +454,20 @@ spec:
|
||||
configuration:
|
||||
description: Configuration is Terraform Configuration
|
||||
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 secret.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type:
|
||||
default: hcl
|
||||
description: Type specifies which Terraform configuration
|
||||
|
||||
@@ -649,7 +649,7 @@ func generateComponentFromKubeModule(wl *Workload, appName, revision, ns string)
|
||||
}
|
||||
|
||||
func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructured.Unstructured, error) {
|
||||
if wl.FullTemplate.Terraform.Configuration == "" {
|
||||
if wl.FullTemplate == nil || wl.FullTemplate.Terraform == nil || wl.FullTemplate.Terraform.Configuration == "" {
|
||||
return nil, errors.New(errTerraformConfigurationIsNotSet)
|
||||
}
|
||||
params, err := json.Marshal(wl.Params)
|
||||
@@ -671,6 +671,10 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
|
||||
configuration.Spec.Remote = wl.FullTemplate.Terraform.Configuration
|
||||
}
|
||||
|
||||
if wl.FullTemplate.Terraform.ProviderReference != nil {
|
||||
configuration.Spec.ProviderReference = wl.FullTemplate.Terraform.ProviderReference
|
||||
}
|
||||
|
||||
// 1. parse writeConnectionSecretToRef
|
||||
if err := json.Unmarshal(params, &configuration.Spec); err != nil {
|
||||
return nil, errors.Wrap(err, errFailToConvertTerraformComponentProperties)
|
||||
@@ -704,7 +708,7 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
|
||||
}
|
||||
configuration.Spec.Variable = &runtime.RawExtension{Raw: data}
|
||||
raw := util.Object2RawExtension(&configuration)
|
||||
return util.RawExtension2Unstructured(&raw)
|
||||
return util.RawExtension2Unstructured(raw)
|
||||
}
|
||||
|
||||
// a helper map whose key is parameter name
|
||||
|
||||
@@ -103,7 +103,7 @@ var _ = Describe("Test Helm schematic appfile", func() {
|
||||
},
|
||||
},
|
||||
Helm: &common.Helm{
|
||||
Release: util.Object2RawExtension(map[string]interface{}{
|
||||
Release: *util.Object2RawExtension(map[string]interface{}{
|
||||
"chart": map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"chart": "podinfo",
|
||||
@@ -111,7 +111,7 @@ var _ = Describe("Test Helm schematic appfile", func() {
|
||||
},
|
||||
},
|
||||
}),
|
||||
Repository: util.Object2RawExtension(map[string]interface{}{
|
||||
Repository: *util.Object2RawExtension(map[string]interface{}{
|
||||
"url": "http://oam.dev/catalog/",
|
||||
}),
|
||||
},
|
||||
@@ -909,6 +909,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
hcl string
|
||||
remote string
|
||||
params map[string]interface{}
|
||||
providerRef *terraformtypes.Reference
|
||||
}
|
||||
|
||||
type want struct {
|
||||
@@ -967,7 +968,18 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
params: badParam,
|
||||
hcl: "abc",
|
||||
},
|
||||
want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)}},
|
||||
want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)},
|
||||
},
|
||||
|
||||
"terraform workload has a provider reference": {
|
||||
|
||||
args: args{
|
||||
params: badParam,
|
||||
hcl: "abc",
|
||||
providerRef: &terraformtypes.Reference{Name: "azure", Namespace: "default"},
|
||||
},
|
||||
want: want{err: errors.Wrap(badParamMarshalError, errFailToConvertTerraformComponentProperties)},
|
||||
},
|
||||
}
|
||||
|
||||
for tcName, tc := range testcases {
|
||||
@@ -1027,6 +1039,9 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
WriteConnectionSecretToReference: tc.args.writeConnectionSecretToRef,
|
||||
}
|
||||
}
|
||||
if tc.args.providerRef != nil {
|
||||
template.Terraform.ProviderReference = tc.args.providerRef
|
||||
}
|
||||
|
||||
wl := &Workload{
|
||||
FullTemplate: template,
|
||||
@@ -1046,7 +1061,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
Spec: configSpec,
|
||||
}
|
||||
rawConf := util.Object2RawExtension(tfConfiguration)
|
||||
wantWL, _ := util.RawExtension2Unstructured(&rawConf)
|
||||
wantWL, _ := util.RawExtension2Unstructured(rawConf)
|
||||
|
||||
if diff := cmp.Diff(wantWL, got); diff != "" {
|
||||
t.Errorf("\n%s\ngenerateTerraformConfigurationWorkload(...): -want, +got:\n%s\n", tcName, diff)
|
||||
|
||||
@@ -1,96 +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 config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
const (
|
||||
// Splitter is a splitter for configmap name generation
|
||||
Splitter = "-"
|
||||
|
||||
// TypeConfigMap defines the type of Configmap
|
||||
TypeConfigMap = "configmap"
|
||||
)
|
||||
|
||||
// ToConfigMap will get the data of the store and upload to configmap.
|
||||
// Serverside Application controller can only use the config in appfile context by configmap.
|
||||
func ToConfigMap(s Store, name, envName string, configData map[string]string) (*v1.ConfigMap, error) {
|
||||
namespace, err := s.Namespace(envName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var cm = v1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
}
|
||||
cm.SetName(name)
|
||||
cm.SetNamespace(namespace)
|
||||
cm.Data = configData
|
||||
return &cm, nil
|
||||
}
|
||||
|
||||
// GenConfigMapName is a fixed way to name the configmap name for appfile config
|
||||
func GenConfigMapName(appName, serviceName, configName string) string {
|
||||
return strings.Join([]string{"kubevela", appName, serviceName, configName}, Splitter)
|
||||
}
|
||||
|
||||
var _ Store = &Configmap{}
|
||||
|
||||
// Configmap is the configmap implementation of config store
|
||||
type Configmap struct {
|
||||
Client client.Client
|
||||
}
|
||||
|
||||
// GetConfigData will get config data from configmap
|
||||
func (f *Configmap) GetConfigData(name, envName string) ([]map[string]string, error) {
|
||||
|
||||
namespace, err := f.Namespace(envName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cm v1.ConfigMap
|
||||
err = f.Client.Get(context.Background(), client.ObjectKey{Name: name, Namespace: namespace}, &cm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var data []map[string]string
|
||||
for k, v := range cm.Data {
|
||||
data = append(data, EncodeConfigFormat(k, v))
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Namespace returns the namespace of the config store from env
|
||||
func (f *Configmap) Namespace(envName string) (string, error) {
|
||||
// TODO(wonderflow): now we regard env as namespace, it should be fixed when env is store serverside as configmap
|
||||
return envName, nil
|
||||
}
|
||||
|
||||
// Type returns the type of the config store
|
||||
func (Configmap) Type() string {
|
||||
return TypeConfigMap
|
||||
}
|
||||
@@ -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 config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/utils/config"
|
||||
env2 "github.com/oam-dev/kubevela/pkg/utils/env"
|
||||
)
|
||||
|
||||
// TypeLocal defines the local config store type
|
||||
const TypeLocal = "local"
|
||||
|
||||
// Local is the local implementation of config store
|
||||
type Local struct{}
|
||||
|
||||
var _ Store = &Local{}
|
||||
|
||||
// GetConfigData will return config data from local
|
||||
func (l *Local) GetConfigData(configName, envName string) ([]map[string]string, error) {
|
||||
cfgData, err := config.ReadConfig(envName, configName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scanner := bufio.NewScanner(bytes.NewReader(cfgData))
|
||||
var data []map[string]string
|
||||
for scanner.Scan() {
|
||||
k, v, err := config.ReadConfigLine(scanner.Text())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = append(data, EncodeConfigFormat(k, v))
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Namespace return namespace from env
|
||||
func (l *Local) Namespace(envName string) (string, error) {
|
||||
env, err := env2.GetEnvByName(envName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return env.Namespace, nil
|
||||
}
|
||||
|
||||
// Type returns the type of this config store implementation
|
||||
func (l *Local) Type() string {
|
||||
return TypeLocal
|
||||
}
|
||||
@@ -1,76 +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 config
|
||||
|
||||
import "errors"
|
||||
|
||||
// Store will get config data
|
||||
type Store interface {
|
||||
GetConfigData(configName, envName string) ([]map[string]string, error)
|
||||
Type() string
|
||||
Namespace(envName string) (string, error)
|
||||
}
|
||||
|
||||
// TypeFake is a fake type
|
||||
const TypeFake = "fake"
|
||||
|
||||
var _ Store = &Fake{}
|
||||
|
||||
// Fake is a fake implementation of config store, help for test
|
||||
type Fake struct {
|
||||
Data []map[string]string
|
||||
}
|
||||
|
||||
// GetConfigData get data
|
||||
func (f *Fake) GetConfigData(_ string, _ string) ([]map[string]string, error) {
|
||||
return f.Data, nil
|
||||
}
|
||||
|
||||
// Type return the type
|
||||
func (Fake) Type() string {
|
||||
return TypeFake
|
||||
}
|
||||
|
||||
// Namespace return the Namespace
|
||||
func (Fake) Namespace(_ string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// EncodeConfigFormat will encode key-value to config{name: key, value: value} format
|
||||
func EncodeConfigFormat(key, value string) map[string]string {
|
||||
return map[string]string{
|
||||
"name": key,
|
||||
"value": value,
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeConfigFormat will decode config{name: key, value: value} format to key-value mode.
|
||||
func DecodeConfigFormat(data []map[string]string) (map[string]string, error) {
|
||||
var res = make(map[string]string)
|
||||
for _, d := range data {
|
||||
key, ok := d["name"]
|
||||
if !ok {
|
||||
return nil, errors.New("invalid data format, no 'name' found")
|
||||
}
|
||||
value, ok := d["value"]
|
||||
if !ok {
|
||||
return nil, errors.New("invalid data format, no 'value' found")
|
||||
}
|
||||
res[key] = value
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
@@ -251,7 +251,7 @@ func (p *Parser) parsePoliciesFromRevision(policies []v1beta1.AppPolicy, appRev
|
||||
return ws, nil
|
||||
}
|
||||
|
||||
func (p *Parser) makeWorkload(ctx context.Context, name, typ string, capType types.CapType, props runtime.RawExtension) (*Workload, error) {
|
||||
func (p *Parser) makeWorkload(ctx context.Context, name, typ string, capType types.CapType, props *runtime.RawExtension) (*Workload, error) {
|
||||
templ, err := p.tmplLoader.LoadTemplate(ctx, p.dm, p.client, typ, capType)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "fetch component/policy type of %s", name)
|
||||
@@ -259,7 +259,7 @@ func (p *Parser) makeWorkload(ctx context.Context, name, typ string, capType typ
|
||||
return p.convertTemplate2Workload(name, typ, props, templ)
|
||||
}
|
||||
|
||||
func (p *Parser) makeWorkloadFromRevision(name, typ string, capType types.CapType, props runtime.RawExtension, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
|
||||
func (p *Parser) makeWorkloadFromRevision(name, typ string, capType types.CapType, props *runtime.RawExtension, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
|
||||
templ, err := LoadTemplateFromRevision(typ, capType, appRev, p.dm)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "fetch component/policy type of %s from revision", name)
|
||||
@@ -268,8 +268,8 @@ func (p *Parser) makeWorkloadFromRevision(name, typ string, capType types.CapTyp
|
||||
return p.convertTemplate2Workload(name, typ, props, templ)
|
||||
}
|
||||
|
||||
func (p *Parser) convertTemplate2Workload(name, typ string, props runtime.RawExtension, templ *Template) (*Workload, error) {
|
||||
settings, err := util.RawExtension2Map(&props)
|
||||
func (p *Parser) convertTemplate2Workload(name, typ string, props *runtime.RawExtension, templ *Template) (*Workload, error) {
|
||||
settings, err := util.RawExtension2Map(props)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "fail to parse settings for %s", name)
|
||||
}
|
||||
@@ -299,7 +299,7 @@ func (p *Parser) parseWorkload(ctx context.Context, comp common.ApplicationCompo
|
||||
workload.ExternalRevision = comp.ExternalRevision
|
||||
|
||||
for _, traitValue := range comp.Traits {
|
||||
properties, err := util.RawExtension2Map(&traitValue.Properties)
|
||||
properties, err := util.RawExtension2Map(traitValue.Properties)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
|
||||
}
|
||||
@@ -335,7 +335,7 @@ func (p *Parser) ParseWorkloadFromRevision(comp common.ApplicationComponent, app
|
||||
workload.ExternalRevision = comp.ExternalRevision
|
||||
|
||||
for _, traitValue := range comp.Traits {
|
||||
properties, err := util.RawExtension2Map(&traitValue.Properties)
|
||||
properties, err := util.RawExtension2Map(traitValue.Properties)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/kind/pkg/cluster"
|
||||
"sigs.k8s.io/kind/pkg/cluster/nodes"
|
||||
"sigs.k8s.io/kind/pkg/cluster/nodeutils"
|
||||
@@ -137,7 +138,11 @@ func loadImage(imageTarName string, node nodes.Node) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to open image")
|
||||
}
|
||||
defer f.Close()
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
klog.Error(err, "Failed to close file")
|
||||
}
|
||||
}()
|
||||
return nodeutils.LoadImageArchive(node, f)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -84,7 +85,14 @@ func (c *CloneSetRolloutController) VerifySpec(ctx context.Context) (bool, error
|
||||
}
|
||||
|
||||
// make sure that the updateRevision is different from what we have already done
|
||||
targetHash := c.cloneSet.Status.UpdateRevision
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -137,14 +137,14 @@ var _ = Describe("cloneset controller", func() {
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("there is no difference between the source and target", func() {
|
||||
It("verify rollout spec hash", func() {
|
||||
By("Create a CloneSet")
|
||||
cloneSet.Spec.UpdateStrategy.Paused = true
|
||||
Expect(k8sClient.Create(ctx, &cloneSet)).Should(Succeed())
|
||||
|
||||
By("Verify should fail because the cloneset hash is not computed without kruise controller")
|
||||
consistent, err := c.VerifySpec(ctx)
|
||||
Expect(err).Should(Equal(fmt.Errorf("there is no difference between the source and target, hash = ")))
|
||||
Expect(consistent).Should(BeFalse())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("the cloneset is in the middle of updating", func() {
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
"github.com/pkg/errors"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
@@ -80,7 +82,14 @@ func (s *StatefulSetRolloutController) VerifySpec(ctx context.Context) (bool, er
|
||||
s.rolloutStatus.RolloutOriginalSize = currentReplicas
|
||||
|
||||
// make sure that the updateRevision is different from what we have already done
|
||||
targetHash := s.statefulSet.Status.UpdateRevision
|
||||
targetHash, verifyErr := utils.ComputeSpecHash(s.statefulSet.Spec)
|
||||
if verifyErr != nil {
|
||||
// do not fail the rollout because we can't compute the hash value for some reason
|
||||
s.rolloutStatus.RolloutRetry(verifyErr.Error())
|
||||
// nolint:nilerr
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if targetHash == s.rolloutStatus.LastAppliedPodTemplateIdentifier {
|
||||
return false, fmt.Errorf("there is no difference between the source and target, hash = %s", targetHash)
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ var _ = Describe("StatefulSet controller", func() {
|
||||
targetHash := statefulSet.Status.UpdateRevision
|
||||
c.rolloutStatus.LastAppliedPodTemplateIdentifier = targetHash
|
||||
consistent, err := c.VerifySpec(ctx)
|
||||
Expect(err).Should(Equal(fmt.Errorf("there is no difference between the source and target, hash = ")))
|
||||
Expect(err).ShouldNot(Equal(fmt.Errorf("there is no difference between the source and target, hash = ")))
|
||||
Expect(consistent).Should(BeFalse())
|
||||
})
|
||||
|
||||
@@ -203,7 +203,8 @@ var _ = Describe("StatefulSet controller", func() {
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(consistent).Should(BeTrue())
|
||||
Expect(c.rolloutStatus.RolloutTargetSize).Should(BeEquivalentTo(*statefulSet.Spec.Replicas))
|
||||
Expect(c.rolloutStatus.NewPodTemplateIdentifier).Should(BeEmpty())
|
||||
// NewPodTemplateIdenifier should be fill with computed hash
|
||||
Expect(c.rolloutStatus.NewPodTemplateIdentifier).ShouldNot(BeEmpty())
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -260,12 +260,12 @@ func PatchComponent(baseComponent *common.ApplicationComponent, patchComponent *
|
||||
}
|
||||
|
||||
// PatchProperties merge patch parameter for dst parameter
|
||||
func PatchProperties(dst runtime.RawExtension, patch runtime.RawExtension) (map[string]interface{}, error) {
|
||||
patchParameter, err := util.RawExtension2Map(&patch)
|
||||
func PatchProperties(dst *runtime.RawExtension, patch *runtime.RawExtension) (map[string]interface{}, error) {
|
||||
patchParameter, err := util.RawExtension2Map(patch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
baseParameter, err := util.RawExtension2Map(&dst)
|
||||
baseParameter, err := util.RawExtension2Map(dst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
@@ -31,6 +32,11 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
)
|
||||
|
||||
const (
|
||||
// OverrideNamespaceLabelKey identifies the override namespace for patched Application
|
||||
OverrideNamespaceLabelKey = "envbinding.oam.dev/override-namespace"
|
||||
)
|
||||
|
||||
// ClusterGatewayEngine construct the multicluster engine of using cluster-gateway
|
||||
type ClusterGatewayEngine struct {
|
||||
client.Client
|
||||
@@ -46,63 +52,64 @@ func NewClusterGatewayEngine(cli client.Client, envBindingName string) ClusterMa
|
||||
}
|
||||
}
|
||||
|
||||
// TODO only support cluster name now, should support selector and namespace later
|
||||
// TODO only support single cluster name and namespace name now, should support label selector
|
||||
func (engine *ClusterGatewayEngine) prepare(ctx context.Context, configs []v1alpha1.EnvConfig) error {
|
||||
engine.clusterDecisions = make(map[string]v1alpha1.ClusterDecision)
|
||||
clusterNameToConfig := make(map[string]string)
|
||||
locationToConfig := make(map[string]string)
|
||||
for _, config := range configs {
|
||||
var namespace, clusterName string
|
||||
// check if namespace selector is valid
|
||||
if config.Placement.NamespaceSelector != nil {
|
||||
return errors.Errorf("invalid env %s: namespace selector in cluster-gateway is not supported now", config.Name)
|
||||
if len(config.Placement.NamespaceSelector.Labels) != 0 {
|
||||
return errors.Errorf("invalid env %s: namespace selector in cluster-gateway does not support label selector for now", config.Name)
|
||||
}
|
||||
namespace = config.Placement.NamespaceSelector.Name
|
||||
}
|
||||
if config.Placement.ClusterSelector == nil {
|
||||
return errors.Errorf("invalid env %s: cluster selector must be set for now", config.Name)
|
||||
// check if cluster selector is valid
|
||||
if config.Placement.ClusterSelector != nil {
|
||||
if len(config.Placement.ClusterSelector.Labels) != 0 {
|
||||
return errors.Errorf("invalid env %s: cluster selector does not support label selector for now", config.Name)
|
||||
}
|
||||
clusterName = config.Placement.ClusterSelector.Name
|
||||
}
|
||||
if len(config.Placement.ClusterSelector.Labels) != 0 {
|
||||
return errors.Errorf("invalid env %s: cluster selector does not support label selector for now", config.Name)
|
||||
// set fallback cluster
|
||||
if clusterName == "" {
|
||||
clusterName = multicluster.ClusterLocalName
|
||||
}
|
||||
if len(config.Placement.ClusterSelector.Name) == 0 {
|
||||
return errors.Errorf("invalid env %s: cluster selector must set cluster name for now", config.Name)
|
||||
// check if current environment uses the same cluster and namespace as resource destination with other environment, if yes, a conflict occurs
|
||||
location := clusterName + "/" + namespace
|
||||
if dupConfigName, ok := locationToConfig[location]; ok {
|
||||
return errors.Errorf("invalid env %s: location %s conflict with env %s", config.Name, location, dupConfigName)
|
||||
}
|
||||
clusterName := config.Placement.ClusterSelector.Name
|
||||
if dupConfigName, ok := clusterNameToConfig[clusterName]; ok {
|
||||
return errors.Errorf("invalid env %s: cluster name %s is conflict with env %s", config.Name, clusterName, dupConfigName)
|
||||
}
|
||||
clusterNameToConfig[clusterName] = config.Name
|
||||
locationToConfig[clusterName] = config.Name
|
||||
// check if target cluster exists
|
||||
if clusterName != multicluster.ClusterLocalName {
|
||||
if err := engine.Get(ctx, types.NamespacedName{Namespace: multicluster.ClusterGatewaySecretNamespace, Name: clusterName}, &v1.Secret{}); err != nil {
|
||||
return errors.Wrapf(err, "failed to get cluster %s for env %s", clusterName, config.Name)
|
||||
}
|
||||
}
|
||||
engine.clusterDecisions[config.Name] = v1alpha1.ClusterDecision{Env: config.Name, Cluster: clusterName}
|
||||
engine.clusterDecisions[config.Name] = v1alpha1.ClusterDecision{Env: config.Name, Cluster: clusterName, Namespace: namespace}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (engine *ClusterGatewayEngine) initEnvBindApps(ctx context.Context, envBinding *v1alpha1.EnvBinding, baseApp *v1beta1.Application, appParser *appfile.Parser) ([]*EnvBindApp, error) {
|
||||
envBindApps, err := CreateEnvBindApps(envBinding, baseApp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = RenderEnvBindApps(ctx, envBindApps, appParser); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = AssembleEnvBindApps(envBindApps); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return envBindApps, nil
|
||||
return CreateEnvBindApps(envBinding, baseApp)
|
||||
}
|
||||
|
||||
func (engine *ClusterGatewayEngine) schedule(ctx context.Context, apps []*EnvBindApp) ([]v1alpha1.ClusterDecision, error) {
|
||||
for _, app := range apps {
|
||||
app.ScheduledManifests = make(map[string]*unstructured.Unstructured)
|
||||
clusterName := engine.clusterDecisions[app.envConfig.Name].Cluster
|
||||
for _, component := range app.PatchedApp.Spec.Components {
|
||||
for _, manifest := range app.assembledManifests[component.Name] {
|
||||
manifestName := component.Name + "/" + manifest.GetName()
|
||||
multicluster.SetClusterName(manifest, clusterName)
|
||||
app.ScheduledManifests[manifestName] = manifest
|
||||
}
|
||||
namespace := engine.clusterDecisions[app.envConfig.Name].Namespace
|
||||
raw, err := runtime.DefaultUnstructuredConverter.ToUnstructured(app.PatchedApp)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to convert app [Env: %s](%s/%s) into unstructured", app.envConfig.Name, app.PatchedApp.Namespace, app.PatchedApp.Name)
|
||||
}
|
||||
patchedApp := &unstructured.Unstructured{Object: raw}
|
||||
multicluster.SetClusterName(patchedApp, clusterName)
|
||||
SetOverrideNamespace(patchedApp, namespace)
|
||||
app.ScheduledManifests[patchedApp.GetName()] = patchedApp
|
||||
}
|
||||
var decisions []v1alpha1.ClusterDecision
|
||||
for _, decision := range engine.clusterDecisions {
|
||||
@@ -110,3 +117,15 @@ func (engine *ClusterGatewayEngine) schedule(ctx context.Context, apps []*EnvBin
|
||||
}
|
||||
return decisions, nil
|
||||
}
|
||||
|
||||
// SetOverrideNamespace set the override namespace for object in its label
|
||||
func SetOverrideNamespace(obj *unstructured.Unstructured, overrideNamespace string) {
|
||||
if overrideNamespace != "" {
|
||||
labels := obj.GetLabels()
|
||||
if labels == nil {
|
||||
labels = map[string]string{}
|
||||
}
|
||||
labels[OverrideNamespaceLabelKey] = overrideNamespace
|
||||
obj.SetLabels(labels)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ func (o *OCMEngine) schedule(ctx context.Context, apps []*EnvBindApp) ([]v1alpha
|
||||
manifest := app.assembledManifests[component.Name]
|
||||
for j := range manifest {
|
||||
workloads = append(workloads, ocmworkv1.Manifest{
|
||||
RawExtension: util.Object2RawExtension(manifest[j]),
|
||||
RawExtension: *util.Object2RawExtension(manifest[j]),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ func (r *Reconciler) handleFinalizers(ctx context.Context, envBinding *v1alpha1.
|
||||
func (r *Reconciler) endWithNegativeCondition(ctx context.Context, envBinding *v1alpha1.EnvBinding, cond condition.Condition) (ctrl.Result, error) {
|
||||
envBinding.SetConditions(cond)
|
||||
if err := r.Client.Status().Patch(ctx, envBinding, client.Merge); err != nil {
|
||||
return ctrl.Result{}, errors.WithMessage(err, "cannot update initializer status")
|
||||
return ctrl.Result{}, errors.WithMessage(err, "cannot update envbinding status")
|
||||
}
|
||||
// if any condition is changed, patching status can trigger requeue the resource and we should return nil to
|
||||
// avoid requeue it again
|
||||
|
||||
@@ -182,7 +182,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-select-cluster-by-name")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Envs[0].Placement.ClusterSelector.Name = spokeClusterName
|
||||
envBinding.Spec.OutputResourcesTo = &v1alpha1.ConfigMapReference{
|
||||
@@ -229,7 +229,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-select-cluster-by-label")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Envs[0].Placement.ClusterSelector.Labels = map[string]string{
|
||||
"purpose": "test",
|
||||
@@ -277,7 +277,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-with-two-env-config")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Envs[0].Placement.ClusterSelector.Name = spokeClusterName
|
||||
|
||||
@@ -361,7 +361,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-with-app-has-helm")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
|
||||
envBinding.Spec.Envs = []v1alpha1.EnvConfig{{
|
||||
@@ -416,7 +416,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-apply-resources-with-ocm")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Envs[0].Placement.ClusterSelector.Name = spokeClusterName
|
||||
envBinding.Spec.Engine = v1alpha1.OCMEngine
|
||||
@@ -458,7 +458,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-apply-resources")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Engine = v1alpha1.SingleClusterEngine
|
||||
|
||||
@@ -494,7 +494,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-store2configmap")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Engine = v1alpha1.SingleClusterEngine
|
||||
envBinding.Spec.OutputResourcesTo = &v1alpha1.ConfigMapReference{
|
||||
@@ -538,7 +538,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-specify-ns")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Engine = v1alpha1.SingleClusterEngine
|
||||
envBinding.Spec.Envs[0].Placement = v1alpha1.EnvPlacement{
|
||||
@@ -579,7 +579,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.SetName("envbinding-select-ns-label")
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Engine = v1alpha1.SingleClusterEngine
|
||||
envBinding.Spec.Envs[0].Placement = v1alpha1.EnvPlacement{
|
||||
@@ -624,7 +624,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetName("test-envbinding-gc-single-cluster")
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Engine = v1alpha1.SingleClusterEngine
|
||||
envBinding.Spec.Envs[0].Placement = v1alpha1.EnvPlacement{
|
||||
@@ -663,7 +663,6 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
By("Create envBinding")
|
||||
Expect(k8sClient.Create(ctx, envBinding)).Should(BeNil())
|
||||
|
||||
testutil.ReconcileOnce(&r, req)
|
||||
testutil.ReconcileRetry(&r, req)
|
||||
|
||||
By("Check the Application created by EnvBinding Controller")
|
||||
@@ -743,7 +742,7 @@ var _ = Describe("EnvBinding Normal tests", func() {
|
||||
envBinding.SetName("test-envbinding-gc-multi-cluster")
|
||||
envBinding.SetNamespace(namespace)
|
||||
envBinding.Spec.AppTemplate = v1alpha1.AppTemplate{
|
||||
RawExtension: util.Object2RawExtension(appTemplate),
|
||||
RawExtension: *util.Object2RawExtension(appTemplate),
|
||||
}
|
||||
envBinding.Spec.Envs[0].Placement.ClusterSelector.Name = spokeClusterName
|
||||
|
||||
@@ -1008,7 +1007,7 @@ var podInfo = &v1beta1.ComponentDefinition{
|
||||
},
|
||||
Schematic: &commontype.Schematic{
|
||||
HELM: &commontype.Helm{
|
||||
Release: util.Object2RawExtension(map[string]interface{}{
|
||||
Release: *util.Object2RawExtension(map[string]interface{}{
|
||||
"chart": map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"chart": "podinfo",
|
||||
@@ -1016,7 +1015,7 @@ var podInfo = &v1beta1.ComponentDefinition{
|
||||
},
|
||||
},
|
||||
}),
|
||||
Repository: util.Object2RawExtension(map[string]interface{}{
|
||||
Repository: *util.Object2RawExtension(map[string]interface{}{
|
||||
"url": "http://oam.dev/catalog/",
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -137,7 +137,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedRevision, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Revision", err), common.ApplicationRendering)
|
||||
}
|
||||
klog.Info("Successfully prepare current app revision", "revisionName", handler.currentAppRev.Name,
|
||||
klog.InfoS("Successfully prepare current app revision", "revisionName", handler.currentAppRev.Name,
|
||||
"revisionHash", handler.currentRevHash, "isNewRevision", handler.isNewRevision)
|
||||
app.Status.SetConditions(condition.ReadyCondition("Revision"))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonRevisoned, velatypes.MessageRevisioned))
|
||||
@@ -146,7 +146,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
klog.ErrorS(err, "Failed to update application status", "application", klog.KObj(app))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err), common.ApplicationRendering)
|
||||
}
|
||||
klog.Info("Successfully apply application revision", "application", klog.KObj(app))
|
||||
klog.InfoS("Successfully apply application revision", "application", klog.KObj(app))
|
||||
|
||||
policies, err := appFile.PrepareWorkflowAndPolicy()
|
||||
if err != nil {
|
||||
|
||||
@@ -73,7 +73,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","config":"myconfig"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","config":"myconfig"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -91,7 +91,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -103,7 +103,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
|
||||
appFailRender := appwithNoTrait.DeepCopy()
|
||||
appFailRender.SetName("app-fail-to-render")
|
||||
appFailRender.Spec.Components[0].Properties = runtime.RawExtension{
|
||||
appFailRender.Spec.Components[0].Properties = &runtime.RawExtension{
|
||||
Raw: []byte(`{"cmd1":["sleep","1000"],"image1":"busybox"}`),
|
||||
}
|
||||
|
||||
@@ -120,11 +120,11 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb",
|
||||
Type: "worker-import",
|
||||
Properties: runtime.RawExtension{Raw: []byte("{\"cmd\":[\"sleep\",\"1000\"],\"image\":\"busybox\"}")},
|
||||
Properties: &runtime.RawExtension{Raw: []byte("{\"cmd\":[\"sleep\",\"1000\"],\"image\":\"busybox\"}")},
|
||||
Traits: []common.ApplicationTrait{
|
||||
{
|
||||
Type: "ingress-import",
|
||||
Properties: runtime.RawExtension{Raw: []byte("{\"http\":{\"/\":80},\"domain\":\"abc.com\"}")},
|
||||
Properties: &runtime.RawExtension{Raw: []byte("{\"http\":{\"/\":80},\"domain\":\"abc.com\"}")},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -176,7 +176,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
appWithTrait.Spec.Components[0].Traits = []common.ApplicationTrait{
|
||||
{
|
||||
Type: "scaler",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"replicas":2}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"replicas":2}`)},
|
||||
},
|
||||
}
|
||||
appWithTrait.Spec.Components[0].Name = "myweb3"
|
||||
@@ -220,7 +220,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
appWithTwoComp.Spec.Components = append(appWithTwoComp.Spec.Components, common.ApplicationComponent{
|
||||
Name: "myweb6",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox2","config":"myconfig"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox2","config":"myconfig"}`)},
|
||||
Scopes: map[string]string{"healthscopes.core.oam.dev": "app-with-two-comp-default-health"},
|
||||
})
|
||||
|
||||
@@ -457,7 +457,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
appWithComposedWorkload.Spec.Components[0].Traits = []common.ApplicationTrait{
|
||||
{
|
||||
Type: "scaler",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"replicas":2}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"replicas":2}`)},
|
||||
},
|
||||
}
|
||||
appWithComposedWorkload.Spec.Components[0].Name = compName
|
||||
@@ -702,13 +702,13 @@ var _ = Describe("Test Application Controller", func() {
|
||||
curApp.Spec.Components[0] = common.ApplicationComponent{
|
||||
Name: "myweb5",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox3"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox3"}`)},
|
||||
Scopes: map[string]string{"healthscopes.core.oam.dev": "app-with-two-comp-default-health"},
|
||||
}
|
||||
curApp.Spec.Components[1] = common.ApplicationComponent{
|
||||
Name: "myweb7",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Scopes: map[string]string{"healthscopes.core.oam.dev": "app-with-two-comp-default-health"},
|
||||
}
|
||||
Expect(k8sClient.Update(ctx, curApp)).Should(BeNil())
|
||||
@@ -1029,9 +1029,9 @@ var _ = Describe("Test Application Controller", func() {
|
||||
app := appWithTraitHealthStatus.DeepCopy()
|
||||
app.Spec.Components[0].Name = compName
|
||||
app.Spec.Components[0].Type = "nworker"
|
||||
app.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox3","lives":"3","enemies":"alien"}`)}
|
||||
app.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox3","lives":"3","enemies":"alien"}`)}
|
||||
app.Spec.Components[0].Traits[0].Type = "ingress"
|
||||
app.Spec.Components[0].Traits[0].Properties = runtime.RawExtension{Raw: []byte(`{"domain":"example.com","http":{"/":80}}`)}
|
||||
app.Spec.Components[0].Traits[0].Properties = &runtime.RawExtension{Raw: []byte(`{"domain":"example.com","http":{"/":80}}`)}
|
||||
|
||||
expDeployment.Name = app.Name
|
||||
expDeployment.Namespace = ns.Name
|
||||
@@ -1167,7 +1167,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
appRefertoWd.Spec.Components[0] = common.ApplicationComponent{
|
||||
Name: "mytask",
|
||||
Type: "task",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"image":"busybox", "cmd":["sleep","1000"]}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"image":"busybox", "cmd":["sleep","1000"]}`)},
|
||||
}
|
||||
ns := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -1217,7 +1217,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
appMix.Spec.Components[1] = common.ApplicationComponent{
|
||||
Name: "mytask",
|
||||
Type: "task",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"image":"busybox", "cmd":["sleep","1000"]}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"image":"busybox", "cmd":["sleep","1000"]}`)},
|
||||
}
|
||||
ns := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -1438,11 +1438,10 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Traits: []common.ApplicationTrait{
|
||||
{
|
||||
Type: "rollout",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
Type: "rollout",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1463,7 +1462,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: "myweb1", Namespace: ns.Name}, deploy)).Should(util.NotFoundMatcher{})
|
||||
|
||||
By("update component targetComponentRev will change")
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","2000"],"image":"nginx"}`)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","2000"],"image":"nginx"}`)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnce(reconciler, reconcile.Request{NamespacedName: appKey})
|
||||
checkApp = &v1beta1.Application{}
|
||||
@@ -1478,7 +1477,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
|
||||
By("check update rollout trait won't generate new appRevision")
|
||||
appRevName := checkApp.Status.LatestRevision.Name
|
||||
checkApp.Spec.Components[0].Traits[0].Properties.Raw = []byte(`{"targetRevision":"myweb1-v3"}`)
|
||||
checkApp.Spec.Components[0].Traits[0].Properties = &runtime.RawExtension{Raw: []byte(`{"targetRevision":"myweb1-v3"}`)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnce(reconciler, reconcile.Request{NamespacedName: appKey})
|
||||
checkApp = &v1beta1.Application{}
|
||||
@@ -1518,11 +1517,10 @@ var _ = Describe("Test Application Controller", func() {
|
||||
Name: "myweb1",
|
||||
Type: "worker",
|
||||
ExternalRevision: externalRevision,
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Traits: []common.ApplicationTrait{
|
||||
{
|
||||
Type: "rollout",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
Type: "rollout",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1570,7 +1568,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-revision",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1619,7 +1617,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
Name: "myweb1",
|
||||
Type: "worker-revision",
|
||||
ExternalRevision: externalRevision,
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1676,11 +1674,10 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Traits: []common.ApplicationTrait{
|
||||
{
|
||||
Type: "rollout",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
Type: "rollout",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1690,7 +1687,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "apply",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component" : "myweb1"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component" : "myweb1"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1742,7 +1739,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep"],"image":"busybox"}`)},
|
||||
Inputs: common.StepInputs{
|
||||
{
|
||||
From: "message",
|
||||
@@ -1761,7 +1758,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Outputs: common.StepOutputs{
|
||||
{Name: "message", ValueFrom: "output.status.conditions[0].message+\",\"+outputs.gameconfig.data.lives"},
|
||||
{Name: "sleepTime", ValueFrom: "\"100\""},
|
||||
@@ -1842,13 +1839,13 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
DependsOn: []string{"myweb2"},
|
||||
},
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1917,7 +1914,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
DependsOn: []string{"myweb2"},
|
||||
Inputs: common.StepInputs{
|
||||
{
|
||||
@@ -1933,7 +1930,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Outputs: common.StepOutputs{
|
||||
{Name: "message", ValueFrom: "output.status.conditions[0].message+\",\"+outputs.gameconfig.data.lives"},
|
||||
},
|
||||
@@ -2016,12 +2013,12 @@ var _ = Describe("Test Application Controller", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
},
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -107,7 +107,7 @@ var _ = Describe("Test application controller finalizer logic", func() {
|
||||
updateApp.Spec.Components[0].Traits = []common.ApplicationTrait{
|
||||
{
|
||||
Type: "cross-scaler",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"replicas": 1}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"replicas": 1}`)},
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Update(ctx, updateApp)).Should(BeNil())
|
||||
@@ -236,7 +236,7 @@ var _ = Describe("Test application controller finalizer logic", func() {
|
||||
app.Spec.Components[0].Traits = []common.ApplicationTrait{
|
||||
{
|
||||
Type: "cross-scaler",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"replicas": 1}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"replicas": 1}`)},
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, app)).Should(BeNil())
|
||||
@@ -284,7 +284,7 @@ func getApp(appName, namespace, comptype string) *v1beta1.Application {
|
||||
{
|
||||
Name: "comp1",
|
||||
Type: comptype,
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -113,7 +113,7 @@ var _ = Describe("Test Application apply", func() {
|
||||
Components: []common.ApplicationComponent{{
|
||||
Type: "test-worker",
|
||||
Name: "test-app",
|
||||
Properties: runtime.RawExtension{
|
||||
Properties: &runtime.RawExtension{
|
||||
Raw: []byte(`{"image": "oamdev/testapp:v1", "cmd": ["node", "server.js"]}`),
|
||||
},
|
||||
}},
|
||||
|
||||
@@ -199,10 +199,29 @@ func (a *AppManifestsDispatcher) retrieveLegacyResourceTrackers(ctx context.Cont
|
||||
}
|
||||
for _, rt := range rtList.Items {
|
||||
if rt.Name != a.currentRTName &&
|
||||
(a.previousRT != nil && rt.Name != a.previousRT.Name) {
|
||||
(a.previousRT != nil && rt.Name != a.previousRT.Name) && !IsLifeLongResourceTracker(rt) {
|
||||
a.legacyRTs = append(a.legacyRTs, rt.DeepCopy())
|
||||
}
|
||||
}
|
||||
|
||||
// compatibility code for label typo. more info: https://github.com/oam-dev/kubevela/issues/2464
|
||||
// TODO(wangyikewxgm) delete after appRollout deprecated.
|
||||
oldRtList := &v1beta1.ResourceTrackerList{}
|
||||
if err := a.c.List(ctx, oldRtList, client.MatchingLabels{
|
||||
oam.LabelAppName: ExtractAppName(a.currentRTName, a.namespace),
|
||||
"app.oam.dev/namesapce": a.namespace,
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "cannot retrieve legacy resource trackers with miss-spell label")
|
||||
}
|
||||
if len(oldRtList.Items) != 0 {
|
||||
for _, rt := range oldRtList.Items {
|
||||
if rt.Name != a.currentRTName &&
|
||||
(a.previousRT != nil && rt.Name != a.previousRT.Name) && !IsLifeLongResourceTracker(rt) {
|
||||
a.legacyRTs = append(a.legacyRTs, rt.DeepCopy())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -357,3 +376,9 @@ func setOrOverrideOAMControllerOwner(obj ObjectOwner, controllerOwner metav1.Own
|
||||
}
|
||||
obj.SetOwnerReferences(newOwnerRefs)
|
||||
}
|
||||
|
||||
// IsLifeLongResourceTracker check if resourcetracker shares the same whole life with the entire application
|
||||
func IsLifeLongResourceTracker(rt v1beta1.ResourceTracker) bool {
|
||||
_, ok := rt.GetAnnotations()[oam.AnnotationResourceTrackerLifeLong]
|
||||
return ok
|
||||
}
|
||||
|
||||
@@ -465,6 +465,59 @@ var _ = Describe("Test handleSkipGC func", func() {
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("Test compatibility code", func() {
|
||||
var namespaceName string
|
||||
var appName string
|
||||
ctx := context.Background()
|
||||
BeforeEach(func() {
|
||||
namespaceName = fmt.Sprintf("%s-%s", "compatibility-code-test", strconv.FormatInt(rand.Int63(), 16))
|
||||
appName = "test-app"
|
||||
Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespaceName}}))
|
||||
})
|
||||
|
||||
It("Test GC skip func ", func() {
|
||||
a := AppManifestsDispatcher{c: k8sClient, currentRTName: appName + "-v4-" + namespaceName, namespace: namespaceName}
|
||||
resourceTracker_old := v1beta1.ResourceTracker{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: appName + "-v1-" + namespaceName,
|
||||
Labels: map[string]string{
|
||||
oam.LabelAppNamespace: namespaceName,
|
||||
oam.LabelAppName: appName,
|
||||
},
|
||||
},
|
||||
}
|
||||
resourceTracker_new := v1beta1.ResourceTracker{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: appName + "-v2-" + namespaceName,
|
||||
Labels: map[string]string{
|
||||
"app.oam.dev/namesapce": namespaceName,
|
||||
oam.LabelAppName: appName,
|
||||
},
|
||||
},
|
||||
}
|
||||
resourceTracker_previous := v1beta1.ResourceTracker{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: appName + "-v3-" + namespaceName,
|
||||
Labels: map[string]string{
|
||||
oam.LabelAppNamespace: namespaceName,
|
||||
oam.LabelAppName: appName,
|
||||
},
|
||||
},
|
||||
}
|
||||
a.previousRT = &resourceTracker_previous
|
||||
Expect(a.c.Create(ctx, &resourceTracker_old)).Should(BeNil())
|
||||
Expect(a.c.Create(ctx, &resourceTracker_new)).Should(BeNil())
|
||||
Expect(a.retrieveLegacyResourceTrackers(ctx)).Should(BeNil())
|
||||
Expect(len(a.legacyRTs)).Should(BeEquivalentTo(2))
|
||||
res := map[types.UID]bool{}
|
||||
for _, rt := range a.legacyRTs {
|
||||
res[rt.UID] = true
|
||||
}
|
||||
Expect(res[resourceTracker_old.UID]).Should(BeTrue())
|
||||
Expect(res[resourceTracker_new.UID]).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
// in envtest, no gc controller can delete PersistentVolume because of its finalizer
|
||||
// so we just use deletion timestamp to verify its deletion
|
||||
func persistentVolumeIsDeleted(pv *corev1.PersistentVolume) bool {
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/application/assemble"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/model/value"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/packages"
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
@@ -91,7 +92,7 @@ func convertStepProperties(step *v1beta1.WorkflowStep, app *v1beta1.Application)
|
||||
o := struct {
|
||||
Component string `json:"component"`
|
||||
}{}
|
||||
js, err := step.Properties.MarshalJSON()
|
||||
js, err := common.RawExtensionPointer{RawExtension: step.Properties}.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -123,7 +124,8 @@ func convertStepProperties(step *v1beta1.WorkflowStep, app *v1beta1.Application)
|
||||
}
|
||||
|
||||
func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1beta1.ApplicationRevision, af *appfile.Appfile, cli client.Client) oamProvider.ComponentApply {
|
||||
return func(comp common.ApplicationComponent, patcher *value.Value) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
|
||||
return func(comp common.ApplicationComponent, patcher *value.Value, clusterName string, overrideNamespace string) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
|
||||
ctx := multicluster.ContextWithClusterName(context.Background(), clusterName)
|
||||
|
||||
wl, err := appParser.ParseWorkloadFromRevision(comp, appRev)
|
||||
if err != nil {
|
||||
@@ -137,11 +139,11 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
|
||||
if err := af.SetOAMContract(manifest); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "SetOAMContract")
|
||||
}
|
||||
if err := h.HandleComponentsRevision(context.TODO(), []*types.ComponentManifest{manifest}); err != nil {
|
||||
if err := h.HandleComponentsRevision(ctx, []*types.ComponentManifest{manifest}); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "HandleComponentsRevision")
|
||||
}
|
||||
if len(manifest.PackagedWorkloadResources) != 0 {
|
||||
if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, manifest.PackagedWorkloadResources...); err != nil {
|
||||
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, manifest.PackagedWorkloadResources...); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "cannot dispatch packaged workload resources")
|
||||
}
|
||||
}
|
||||
@@ -149,15 +151,20 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
|
||||
if err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "assemble resources before apply fail")
|
||||
}
|
||||
|
||||
if overrideNamespace != "" {
|
||||
readyWorkload.SetNamespace(overrideNamespace)
|
||||
for _, readyTrait := range readyTraits {
|
||||
readyTrait.SetNamespace(overrideNamespace)
|
||||
}
|
||||
}
|
||||
skipStandardWorkload := skipApplyWorkload(wl)
|
||||
if !skipStandardWorkload {
|
||||
if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, readyWorkload); err != nil {
|
||||
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, readyWorkload); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "DispatchStandardWorkload")
|
||||
}
|
||||
}
|
||||
|
||||
if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, readyTraits...); err != nil {
|
||||
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, readyTraits...); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "DispatchTraits")
|
||||
}
|
||||
|
||||
@@ -169,7 +176,7 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
|
||||
if !isHealth {
|
||||
return nil, nil, false, nil
|
||||
}
|
||||
workload, traits, err := getComponentResources(manifest, skipStandardWorkload, cli)
|
||||
workload, traits, err := getComponentResources(ctx, manifest, skipStandardWorkload, cli)
|
||||
return workload, traits, true, err
|
||||
}
|
||||
}
|
||||
@@ -183,14 +190,14 @@ func skipApplyWorkload(wl *appfile.Workload) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func getComponentResources(manifest *types.ComponentManifest, skipStandardWorkload bool, cli client.Client) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
func getComponentResources(ctx context.Context, manifest *types.ComponentManifest, skipStandardWorkload bool, cli client.Client) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
var (
|
||||
workload *unstructured.Unstructured
|
||||
traits []*unstructured.Unstructured
|
||||
)
|
||||
if !skipStandardWorkload {
|
||||
v := manifest.StandardWorkload.DeepCopy()
|
||||
if err := cli.Get(context.Background(), client.ObjectKeyFromObject(manifest.StandardWorkload), v); err != nil {
|
||||
if err := cli.Get(ctx, client.ObjectKeyFromObject(manifest.StandardWorkload), v); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
workload = v
|
||||
@@ -198,7 +205,7 @@ func getComponentResources(manifest *types.ComponentManifest, skipStandardWorklo
|
||||
|
||||
for _, trait := range manifest.Traits {
|
||||
v := trait.DeepCopy()
|
||||
if err := cli.Get(context.Background(), client.ObjectKeyFromObject(trait), v); err != nil {
|
||||
if err := cli.Get(ctx, client.ObjectKeyFromObject(trait), v); err != nil {
|
||||
return workload, nil, err
|
||||
}
|
||||
traits = append(traits, v)
|
||||
|
||||
@@ -81,7 +81,7 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Inputs: common.StepInputs{
|
||||
{
|
||||
From: "message",
|
||||
@@ -96,7 +96,7 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Outputs: common.StepOutputs{
|
||||
{
|
||||
Name: "message",
|
||||
@@ -145,12 +145,12 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
},
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -582,6 +582,27 @@ func ComputeComponentRevisionHash(comp *types.ComponentManifest) (string, error)
|
||||
return utils.ComputeSpecHash(&compRevisionHash)
|
||||
}
|
||||
|
||||
// createOrGetResourceTracker create or get a resource tracker to manage all componentRevisions
|
||||
func (h *AppHandler) createOrGetResourceTracker(ctx context.Context) (*v1beta1.ResourceTracker, error) {
|
||||
rt := &v1beta1.ResourceTracker{}
|
||||
rtName := h.app.Name + "-" + h.app.Namespace
|
||||
if err := h.r.Get(ctx, ktypes.NamespacedName{Name: rtName}, rt); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
rt.SetName(rtName)
|
||||
rt.SetLabels(map[string]string{
|
||||
oam.LabelAppName: h.app.Name,
|
||||
oam.LabelAppNamespace: h.app.Namespace,
|
||||
})
|
||||
rt.SetAnnotations(map[string]string{oam.AnnotationResourceTrackerLifeLong: "true"})
|
||||
if err = h.r.Create(ctx, rt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return rt, nil
|
||||
}
|
||||
|
||||
// createControllerRevision records snapshot of a component
|
||||
func (h *AppHandler) createControllerRevision(ctx context.Context, cm *types.ComponentManifest) error {
|
||||
comp, err := componentManifest2Component(cm)
|
||||
@@ -589,6 +610,10 @@ func (h *AppHandler) createControllerRevision(ctx context.Context, cm *types.Com
|
||||
return err
|
||||
}
|
||||
revision, _ := utils.ExtractRevision(cm.RevisionName)
|
||||
rt, err := h.createOrGetResourceTracker(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cr := &appsv1.ControllerRevision{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cm.RevisionName,
|
||||
@@ -596,9 +621,9 @@ func (h *AppHandler) createControllerRevision(ctx context.Context, cm *types.Com
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: v1beta1.SchemeGroupVersion.String(),
|
||||
Kind: v1beta1.ApplicationKind,
|
||||
Name: h.app.Name,
|
||||
UID: h.app.UID,
|
||||
Kind: v1beta1.ResourceTrackerKind,
|
||||
Name: rt.GetName(),
|
||||
UID: rt.GetUID(),
|
||||
Controller: pointer.BoolPtr(true),
|
||||
},
|
||||
},
|
||||
@@ -608,7 +633,7 @@ func (h *AppHandler) createControllerRevision(ctx context.Context, cm *types.Com
|
||||
},
|
||||
},
|
||||
Revision: int64(revision),
|
||||
Data: util.Object2RawExtension(comp),
|
||||
Data: *util.Object2RawExtension(comp),
|
||||
}
|
||||
return h.r.Create(ctx, cr)
|
||||
}
|
||||
@@ -626,15 +651,15 @@ func componentManifest2Component(cm *types.ComponentManifest) (*v1alpha2.Compone
|
||||
wl = cm.StandardWorkload.DeepCopy()
|
||||
util.RemoveLabels(wl, []string{oam.LabelAppRevision})
|
||||
}
|
||||
component.Spec.Workload = util.Object2RawExtension(wl)
|
||||
component.Spec.Workload = *util.Object2RawExtension(wl)
|
||||
if len(cm.PackagedWorkloadResources) > 0 {
|
||||
helm := &common.Helm{}
|
||||
for _, helmResource := range cm.PackagedWorkloadResources {
|
||||
if helmResource.GetKind() == helmapi.HelmReleaseGVK.Kind {
|
||||
helm.Release = util.Object2RawExtension(helmResource)
|
||||
helm.Release = *util.Object2RawExtension(helmResource)
|
||||
}
|
||||
if helmResource.GetKind() == helmapi.HelmRepositoryGVK.Kind {
|
||||
helm.Repository = util.Object2RawExtension(helmResource)
|
||||
helm.Repository = *util.Object2RawExtension(helmResource)
|
||||
}
|
||||
}
|
||||
component.Spec.Helm = helm
|
||||
@@ -757,6 +782,9 @@ func gatherUsingAppRevision(ctx context.Context, h *AppHandler) (map[string]bool
|
||||
return nil, err
|
||||
}
|
||||
for _, rt := range rtList.Items {
|
||||
if dispatch.IsLifeLongResourceTracker(rt) {
|
||||
continue
|
||||
}
|
||||
appRev := dispatch.ExtractAppRevisionName(rt.Name, ns)
|
||||
usingRevision[appRev] = true
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
for i := 0; i < appRevisionLimit+1; i++ {
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, i)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
}
|
||||
@@ -104,7 +104,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("create new appRevision will remove appRevison1")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err := reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -131,7 +131,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("update app again will gc appRevision2")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 7)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -164,7 +164,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
for i := 0; i < appRevisionLimit+1; i++ {
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, i)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
}
|
||||
@@ -189,7 +189,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("create new appRevision will remove revision v1")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err := reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -216,7 +216,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("update app again will gc revision v2")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 7)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -242,7 +242,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("update app with comp as latest revision will not gc revision v3")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -273,7 +273,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
for i := 0; i < appRevisionLimit+1; i++ {
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, i)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
}
|
||||
@@ -298,7 +298,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("create new appRevision will remove revision v1")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err := reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -325,7 +325,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("update app again will gc revision v2")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 7)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -351,7 +351,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("update app with comp as latest revision will not gc revision v3")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -382,7 +382,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
for i := 0; i < appRevisionLimit+1; i++ {
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, i)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
}
|
||||
@@ -407,7 +407,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("create new appRevision will remove appRevison1")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err := reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -437,7 +437,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("update app again will gc appRevision2")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 7)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -475,7 +475,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
for i := 0; i < appRevisionLimit+1; i++ {
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, i)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
}
|
||||
@@ -500,7 +500,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("create new appRevision will remove appRevison1")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err := reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -530,7 +530,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("update app again will gc appRevision2")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 7)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -568,7 +568,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
for i := 0; i < appRevisionLimit+1; i++ {
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, i)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
}
|
||||
@@ -593,7 +593,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
By("create new appRevision will remove appRevison1")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err := reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -644,7 +644,7 @@ var _ = Describe("Test application controller clean up ", func() {
|
||||
for i := 7; i < 9; i++ {
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, i)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
checkApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
_, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: appKey})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
@@ -118,13 +118,13 @@ var _ = Describe("test generate revision ", func() {
|
||||
Type: cd.Name,
|
||||
Name: "express-server",
|
||||
Scopes: map[string]string{"healthscopes.core.oam.dev": "myapp-default-health"},
|
||||
Properties: runtime.RawExtension{
|
||||
Properties: &runtime.RawExtension{
|
||||
Raw: []byte(`{"image": "oamdev/testapp:v1", "cmd": ["node", "server.js"]}`),
|
||||
},
|
||||
Traits: []common.ApplicationTrait{
|
||||
{
|
||||
Type: td.Name,
|
||||
Properties: runtime.RawExtension{
|
||||
Properties: &runtime.RawExtension{
|
||||
Raw: []byte(`{"replicas": 5}`),
|
||||
},
|
||||
},
|
||||
@@ -232,7 +232,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
It("Test appliction contain a SkipAppRevision tait will have same hash", func() {
|
||||
rolloutTrait := common.ApplicationTrait{
|
||||
Type: "rollout",
|
||||
Properties: runtime.RawExtension{
|
||||
Properties: &runtime.RawExtension{
|
||||
Raw: []byte(`{"targetRevision":"myrev-v1"}`),
|
||||
},
|
||||
}
|
||||
@@ -336,7 +336,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
Expect(err).Should(BeNil())
|
||||
expectWorkload = comps[0].StandardWorkload.DeepCopy()
|
||||
util.RemoveLabels(expectWorkload, []string{oam.LabelAppRevision, oam.LabelAppRevisionHash, oam.LabelAppComponentRevision})
|
||||
Expect(cmp.Diff(gotComp.Spec.Workload, util.Object2RawExtension(expectWorkload))).Should(BeEmpty())
|
||||
Expect(cmp.Diff(gotComp.Spec.Workload, *util.Object2RawExtension(expectWorkload))).Should(BeEmpty())
|
||||
|
||||
By("Verify component revision is not changed")
|
||||
expectCompRevName = "express-server-v1"
|
||||
@@ -348,7 +348,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
By("Change the application and apply again")
|
||||
// bump the image tag
|
||||
app.ResourceVersion = curApp.ResourceVersion
|
||||
app.Spec.Components[0].Properties = runtime.RawExtension{
|
||||
app.Spec.Components[0].Properties = &runtime.RawExtension{
|
||||
Raw: []byte(`{"image": "oamdev/testapp:v2", "cmd": ["node", "server.js"]}`),
|
||||
}
|
||||
// persist the app
|
||||
@@ -400,12 +400,12 @@ var _ = Describe("test generate revision ", func() {
|
||||
Expect(err).Should(BeNil())
|
||||
expectWorkload = comps[0].StandardWorkload.DeepCopy()
|
||||
util.RemoveLabels(expectWorkload, []string{oam.LabelAppRevision, oam.LabelAppRevisionHash, oam.LabelAppComponentRevision})
|
||||
Expect(cmp.Diff(gotComp.Spec.Workload, util.Object2RawExtension(expectWorkload))).Should(BeEmpty())
|
||||
Expect(cmp.Diff(gotComp.Spec.Workload, *util.Object2RawExtension(expectWorkload))).Should(BeEmpty())
|
||||
|
||||
By("Change the application same as v1 and apply again")
|
||||
// bump the image tag
|
||||
app.ResourceVersion = curApp.ResourceVersion
|
||||
app.Spec.Components[0].Properties = runtime.RawExtension{
|
||||
app.Spec.Components[0].Properties = &runtime.RawExtension{
|
||||
Raw: []byte(`{"image": "oamdev/testapp:v1", "cmd": ["node", "server.js"]}`),
|
||||
}
|
||||
// persist the app
|
||||
@@ -465,7 +465,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
expectWorkload = comps[0].StandardWorkload.DeepCopy()
|
||||
util.RemoveLabels(expectWorkload, []string{oam.LabelAppRevision, oam.LabelAppRevisionHash, oam.LabelAppComponentRevision})
|
||||
expectWorkload.SetAnnotations(map[string]string{"testKey1": "true"})
|
||||
Expect(cmp.Diff(gotComp.Spec.Workload, util.Object2RawExtension(expectWorkload))).Should(BeEmpty())
|
||||
Expect(cmp.Diff(gotComp.Spec.Workload, *util.Object2RawExtension(expectWorkload))).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test App with rollout template", func() {
|
||||
@@ -546,7 +546,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
// bump the image tag
|
||||
app.SetAnnotations(map[string]string{oam.AnnotationAppRollout: strconv.FormatBool(true)})
|
||||
app.ResourceVersion = curApp.ResourceVersion
|
||||
app.Spec.Components[0].Properties = runtime.RawExtension{
|
||||
app.Spec.Components[0].Properties = &runtime.RawExtension{
|
||||
Raw: []byte(`{"image": "oamdev/testapp:v2", "cmd": ["node", "server.js"]}`),
|
||||
}
|
||||
// persist the app
|
||||
|
||||
@@ -55,13 +55,13 @@ var _ = Describe("Test Workflow", func() {
|
||||
Components: []common.ApplicationComponent{{
|
||||
Name: "test-component",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
}},
|
||||
Workflow: &oamcore.Workflow{
|
||||
Steps: []oamcore.WorkflowStep{{
|
||||
Name: "test-wf1",
|
||||
Type: "foowf",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"namespace":"test-ns"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"namespace":"test-ns"}`)},
|
||||
}},
|
||||
},
|
||||
},
|
||||
@@ -71,7 +71,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
appWithWorkflowAndPolicy.Spec.Policies = []oamcore.AppPolicy{{
|
||||
Name: "test-policy",
|
||||
Type: "foopolicy",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"key":"test"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"key":"test"}`)},
|
||||
}}
|
||||
|
||||
appWithPolicy := &oamcore.Application{
|
||||
@@ -83,12 +83,12 @@ var _ = Describe("Test Workflow", func() {
|
||||
Components: []common.ApplicationComponent{{
|
||||
Name: "test-component",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
}},
|
||||
Policies: []oamcore.AppPolicy{{
|
||||
Name: "test-policy",
|
||||
Type: "foopolicy",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"key":"test"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"key":"test"}`)},
|
||||
}},
|
||||
},
|
||||
}
|
||||
@@ -160,7 +160,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
appWithPolicyAndWorkflow.Spec.Policies = []oamcore.AppPolicy{{
|
||||
Name: "test-foo-policy",
|
||||
Type: "foopolicy",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"key":"test"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"key":"test"}`)},
|
||||
}}
|
||||
|
||||
Expect(k8sClient.Create(ctx, appWithPolicyAndWorkflow)).Should(BeNil())
|
||||
@@ -237,7 +237,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
suspendApp.Spec.Workflow.Steps = []oamcore.WorkflowStep{{
|
||||
Name: "suspend",
|
||||
Type: "suspend",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
}}
|
||||
Expect(k8sClient.Create(ctx, suspendApp)).Should(BeNil())
|
||||
|
||||
@@ -284,12 +284,12 @@ var _ = Describe("Test Workflow", func() {
|
||||
{
|
||||
Name: "suspend",
|
||||
Type: "suspend",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
},
|
||||
{
|
||||
Name: "suspend-1",
|
||||
Type: "suspend",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{}`)},
|
||||
}}
|
||||
Expect(k8sClient.Create(ctx, suspendApp)).Should(BeNil())
|
||||
|
||||
@@ -352,7 +352,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Inputs: common.StepInputs{
|
||||
{
|
||||
From: "message",
|
||||
@@ -367,7 +367,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Outputs: common.StepOutputs{
|
||||
{Name: "message", ValueFrom: "output.status.conditions[0].message+\",\"+outputs.gameconfig.data.lives"},
|
||||
},
|
||||
@@ -377,11 +377,11 @@ var _ = Describe("Test Workflow", func() {
|
||||
Steps: []oamcore.WorkflowStep{{
|
||||
Name: "test-web2",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
}, {
|
||||
Name: "test-web1",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
}},
|
||||
},
|
||||
},
|
||||
@@ -461,24 +461,24 @@ var _ = Describe("Test Workflow", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
DependsOn: []string{"myweb2"},
|
||||
},
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
},
|
||||
},
|
||||
Workflow: &oamcore.Workflow{
|
||||
Steps: []oamcore.WorkflowStep{{
|
||||
Name: "test-web2",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
}, {
|
||||
Name: "test-web1",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
}},
|
||||
},
|
||||
},
|
||||
@@ -549,7 +549,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)},
|
||||
DependsOn: []string{"myweb2"},
|
||||
Inputs: common.StepInputs{
|
||||
{
|
||||
@@ -565,7 +565,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "worker-with-health",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox","lives": "i am lives","enemies": "empty"}`)},
|
||||
Outputs: common.StepOutputs{
|
||||
{Name: "message", ValueFrom: "output.status.conditions[0].message+\",\"+outputs.gameconfig.data.lives"},
|
||||
},
|
||||
@@ -575,11 +575,11 @@ var _ = Describe("Test Workflow", func() {
|
||||
Steps: []oamcore.WorkflowStep{{
|
||||
Name: "test-web2",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
}, {
|
||||
Name: "test-web1",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
}},
|
||||
},
|
||||
},
|
||||
@@ -649,12 +649,12 @@ var _ = Describe("Test Workflow", func() {
|
||||
{
|
||||
Name: "myweb1",
|
||||
Type: "webserver",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"image":"busybox"}`)},
|
||||
},
|
||||
{
|
||||
Name: "myweb2",
|
||||
Type: "webserver",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"image":"busybox"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"image":"busybox"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -666,19 +666,19 @@ var _ = Describe("Test Workflow", func() {
|
||||
updateApp := &oamcore.Application{}
|
||||
Expect(k8sClient.Get(ctx, appKey, updateApp)).Should(BeNil())
|
||||
Expect(updateApp.Status.Phase).Should(BeEquivalentTo(common.ApplicationRunning))
|
||||
updateApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(`{}`)}
|
||||
updateApp.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte(`{}`)}
|
||||
updateApp.Spec.Workflow = &oamcore.Workflow{
|
||||
Steps: []oamcore.WorkflowStep{{
|
||||
Name: "test-web2",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb2"}`)},
|
||||
Outputs: common.StepOutputs{
|
||||
{Name: "image", ValueFrom: "output.spec.template.spec.containers[0].image"},
|
||||
},
|
||||
}, {
|
||||
Name: "test-web1",
|
||||
Type: "apply-component",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
Properties: &runtime.RawExtension{Raw: []byte(`{"component":"myweb1"}`)},
|
||||
Inputs: common.StepInputs{
|
||||
{
|
||||
From: "image",
|
||||
|
||||
@@ -328,7 +328,7 @@ spec:
|
||||
cd.Spec.Workload.Definition = common.WorkloadGVK{APIVersion: "apps/v1", Kind: "Deployment"}
|
||||
cd.Spec.Schematic = &common.Schematic{
|
||||
HELM: &common.Helm{
|
||||
Release: util.Object2RawExtension(map[string]interface{}{
|
||||
Release: *util.Object2RawExtension(map[string]interface{}{
|
||||
"chart": map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"chart": "podinfo",
|
||||
@@ -336,7 +336,7 @@ spec:
|
||||
},
|
||||
},
|
||||
}),
|
||||
Repository: util.Object2RawExtension(map[string]interface{}{
|
||||
Repository: *util.Object2RawExtension(map[string]interface{}{
|
||||
"url": "http://oam.dev/catalog/",
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -241,6 +241,46 @@ containers: [{
|
||||
}
|
||||
}, ...]
|
||||
}, ...]
|
||||
`},
|
||||
|
||||
{
|
||||
base: `
|
||||
containers: [{
|
||||
volumeMounts: [{name: "k1", path: "p1"},{name: "k1", path: "p2"},...]
|
||||
},...]
|
||||
volumes: [{name: "x1",value: "v1"},{name: "x2",value: "v2"},...]
|
||||
`,
|
||||
|
||||
patch: `
|
||||
// +patchKey=name
|
||||
volumes: [{name: "x1",value: "v1"},{name: "x3",value: "x2"}]
|
||||
|
||||
containers: [{
|
||||
volumeMounts: [{name: "k1", path: "p1"},{name: "k1", path: "p2"},{ name:"k2", path: "p3"}]
|
||||
},...]`,
|
||||
result: `containers: [{
|
||||
volumeMounts: [{
|
||||
path: "p1"
|
||||
name: "k1"
|
||||
}, {
|
||||
path: "p2"
|
||||
name: "k1"
|
||||
}, {
|
||||
path: "p3"
|
||||
name: "k2"
|
||||
}]
|
||||
}, ...]
|
||||
// +patchKey=name
|
||||
volumes: [{
|
||||
name: "x1"
|
||||
value: "v1"
|
||||
}, {
|
||||
name: "x2"
|
||||
value: "v2"
|
||||
}, {
|
||||
name: "x3"
|
||||
value: "x2"
|
||||
}, ...]
|
||||
`},
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@ func (nwk *nodewalker) walk(node ast.Node) {
|
||||
if n.Value != nil {
|
||||
origin := nwk.pos
|
||||
oriTags := nwk.tags
|
||||
nwk.tags = map[string]string{}
|
||||
for k, v := range oriTags {
|
||||
nwk.tags[k] = v
|
||||
}
|
||||
nwk.pos = append(nwk.pos, labelStr(n.Label))
|
||||
tags := findCommentTag(n.Comments())
|
||||
for tk, tv := range tags {
|
||||
|
||||
@@ -93,9 +93,9 @@ func NewValue(s string, pd *packages.PackageDiscover, tagTempl string, opts ...f
|
||||
}
|
||||
addImports := func(inst *build.Instance) error {
|
||||
if pd != nil {
|
||||
pd.ImportBuiltinPackagesFor(builder)
|
||||
pd.ImportBuiltinPackagesFor(inst)
|
||||
}
|
||||
if err := stdlib.AddImportsFor(builder, tagTempl); err != nil {
|
||||
if err := stdlib.AddImportsFor(inst, tagTempl); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"github.com/oam-dev/cluster-gateway/pkg/apis/cluster/v1alpha1"
|
||||
errors2 "github.com/pkg/errors"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -34,6 +35,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
errors3 "github.com/oam-dev/kubevela/pkg/utils/errors"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
@@ -52,11 +54,6 @@ var (
|
||||
ClusterGatewaySecretNamespace string
|
||||
)
|
||||
|
||||
// Context create context with multi-cluster
|
||||
func Context(ctx context.Context, obj *unstructured.Unstructured) context.Context {
|
||||
return ContextWithClusterName(ctx, obj.GetLabels()[ClusterLabelKey])
|
||||
}
|
||||
|
||||
// ContextWithClusterName create context with multi-cluster by cluster name
|
||||
func ContextWithClusterName(ctx context.Context, clusterName string) context.Context {
|
||||
return context.WithValue(ctx, ClusterContextKey, clusterName)
|
||||
@@ -129,5 +126,34 @@ func Initialize(restConfig *rest.Config) error {
|
||||
ClusterGatewaySecretNamespace = svc.Namespace
|
||||
klog.Infof("find cluster gateway service %s/%s:%d", svc.Namespace, svc.Name, *svc.Port)
|
||||
restConfig.Wrap(NewSecretModeMultiClusterRoundTripper)
|
||||
if err = UpgradeExistingClusterSecret(context.Background(), c); err != nil {
|
||||
// this error do not affect the running of current version
|
||||
klog.ErrorS(err, "error encountered while grading existing cluster secret to the latest version")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpgradeExistingClusterSecret upgrade outdated cluster secrets in v1.1.1 to latest
|
||||
func UpgradeExistingClusterSecret(ctx context.Context, c client.Client) error {
|
||||
const outdatedClusterCredentialLabelKey = "cluster.core.oam.dev/cluster-credential"
|
||||
secrets := &v1.SecretList{}
|
||||
if err := c.List(ctx, secrets, client.InNamespace(ClusterGatewaySecretNamespace), client.HasLabels{outdatedClusterCredentialLabelKey}); err != nil {
|
||||
if err != nil {
|
||||
return errors2.Wrapf(err, "failed to find outdated cluster secrets to do upgrade")
|
||||
}
|
||||
}
|
||||
errs := errors3.ErrorList{}
|
||||
for _, item := range secrets.Items {
|
||||
credType := item.Labels[v1alpha1.LabelKeyClusterCredentialType]
|
||||
if credType == "" && item.Type == v1.SecretTypeTLS {
|
||||
item.Labels[v1alpha1.LabelKeyClusterCredentialType] = string(v1alpha1.CredentialTypeX509Certificate)
|
||||
if err := c.Update(ctx, item.DeepCopy()); err != nil {
|
||||
errs.Append(errors2.Wrapf(err, "failed to update outdated secret %s", item.Name))
|
||||
}
|
||||
}
|
||||
}
|
||||
if errs.HasError() {
|
||||
return errs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
63
pkg/multicluster/utils_test.go
Normal file
63
pkg/multicluster/utils_test.go
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
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 multicluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/oam-dev/cluster-gateway/pkg/apis/cluster/v1alpha1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
)
|
||||
|
||||
func TestUpgradeExistingClusterSecret(t *testing.T) {
|
||||
oldClusterGatewaySecretNamespace := ClusterGatewaySecretNamespace
|
||||
ClusterGatewaySecretNamespace = "default"
|
||||
defer func() {
|
||||
ClusterGatewaySecretNamespace = oldClusterGatewaySecretNamespace
|
||||
}()
|
||||
ctx := context.Background()
|
||||
c := fake.NewClientBuilder().WithScheme(common.Scheme).Build()
|
||||
secret := &v1.Secret{
|
||||
ObjectMeta: v12.ObjectMeta{
|
||||
Name: "example-outdated-cluster-secret",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"cluster.core.oam.dev/cluster-credential": "tls",
|
||||
},
|
||||
},
|
||||
Type: v1.SecretTypeTLS,
|
||||
}
|
||||
if err := c.Create(ctx, secret); err != nil {
|
||||
t.Fatalf("failed to create fake outdated cluster secret, err: %v", err)
|
||||
}
|
||||
if err := UpgradeExistingClusterSecret(ctx, c); err != nil {
|
||||
t.Fatalf("expect no error while upgrading outdated cluster secret but encounter error: %v", err)
|
||||
}
|
||||
newSecret := &v1.Secret{}
|
||||
if err := c.Get(ctx, client.ObjectKeyFromObject(secret), newSecret); err != nil {
|
||||
t.Fatalf("found error while getting updated cluster secret: %v", err)
|
||||
}
|
||||
if newSecret.Labels[v1alpha1.LabelKeyClusterCredentialType] != string(v1alpha1.CredentialTypeX509Certificate) {
|
||||
t.Fatalf("updated secret label should has credential type x509")
|
||||
}
|
||||
}
|
||||
@@ -117,6 +117,9 @@ const (
|
||||
// AnnotationDefinitionRevisionName is used to specify the name of DefinitionRevision in component/trait definition
|
||||
AnnotationDefinitionRevisionName = "definitionrevision.oam.dev/name"
|
||||
|
||||
// AnnotationResourceTrackerLifeLong is used to identify life-long resourcetracker which should only be recycled when application is deleted
|
||||
AnnotationResourceTrackerLifeLong = "resourcetracker.oam.dev/life-long"
|
||||
|
||||
// AnnotationAddonsName records the name of initializer stored in configMap
|
||||
AnnotationAddonsName = "addons.oam.dev/name"
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user