fix metadata missing in AppRevision spec data (#1257)

* fix metadata missing in AppRevision spec data

* fix test
This commit is contained in:
Hongchao Deng
2021-03-22 11:29:25 +08:00
committed by GitHub
parent 0b72c7ce34
commit 75c123df2f
7 changed files with 90 additions and 1717 deletions
@@ -18,6 +18,7 @@ package v1alpha2
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
@@ -40,11 +41,13 @@ type ApplicationRevisionSpec struct {
ScopeDefinitions map[string]ScopeDefinition `json:"scopeDefinitions,omitempty"`
// Components records the rendered components from Application, it will contains the whole K8s CR of workload in it.
Components []*Component `json:"components"`
Components map[string]Component `json:"components,omitempty"`
// ApplicationConfiguration records the rendered applicationConfiguration from Application,
// it will contains the whole K8s CR of trait and the reference component in it.
ApplicationConfiguration ApplicationConfiguration `json:"applicationConfiguration"`
// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:pruning:PreserveUnknownFields
ApplicationConfiguration runtime.RawExtension `json:"applicationConfiguration"`
}
// ApplicationRevision is the Schema for the ApplicationRevision API
@@ -591,13 +591,9 @@ func (in *ApplicationRevisionSpec) DeepCopyInto(out *ApplicationRevisionSpec) {
}
if in.Components != nil {
in, out := &in.Components, &out.Components
*out = make([]*Component, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(Component)
(*in).DeepCopyInto(*out)
}
*out = make(map[string]Component, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
in.ApplicationConfiguration.DeepCopyInto(&out.ApplicationConfiguration)
@@ -445,845 +445,9 @@ spec:
type: object
applicationConfiguration:
description: ApplicationConfiguration records the rendered applicationConfiguration from Application, it will contains the whole K8s CR of trait and the reference component in it.
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: An ApplicationConfigurationSpec defines the desired state of a ApplicationConfiguration.
properties:
components:
description: Components of which this ApplicationConfiguration consists. Each component will be used to instantiate a workload.
items:
description: An ApplicationConfigurationComponent specifies a component of an ApplicationConfiguration. Each component is used to instantiate a workload.
properties:
componentName:
description: ComponentName specifies a component whose latest revision will be bind with ApplicationConfiguration. When the spec of the referenced component changes, ApplicationConfiguration will automatically migrate all trait affect from the prior revision to the new one. This is mutually exclusive with RevisionName.
type: string
dataInputs:
description: DataInputs specify the data input sinks into this component.
items:
description: DataInput specifies a data input sink to an object. If input is array, it will be appended to the target field paths.
properties:
conditions:
description: When the Conditions is satified, ToFieldPaths will be filled with passed value
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
inputStore:
description: InputStore specifies the object used to read intermediate data genereted by DataOutput
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
strategyMergeKeys:
description: StrategyMergeKeys specifies the merge key if the toFieldPaths target is an array. The StrategyMergeKeys is optional, by default, if the toFieldPaths target is an array, we will append. If StrategyMergeKeys specified, we will check the key in the target array. If any key exist, do update; if no key exist, append.
items:
type: string
type: array
toFieldPaths:
description: ToFieldPaths specifies the field paths of an object to fill passed value.
items:
type: string
type: array
valueFrom:
description: ValueFrom specifies the value source.
properties:
dataOutputName:
description: DataOutputName matches a name of a DataOutput in the same AppConfig.
type: string
required:
- dataOutputName
type: object
type: object
type: array
dataOutputs:
description: DataOutputs specify the data output sources from this component.
items:
description: DataOutput specifies a data output source from an object.
properties:
conditions:
description: Conditions specify the conditions that should be satisfied before emitting a data output. Different conditions are AND-ed together. If no conditions is specified, it is by default to check output value not empty.
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
fieldPath:
description: FieldPath refers to the value of an object's field.
type: string
name:
description: Name is the unique name of a DataOutput in an ApplicationConfiguration.
type: string
outputStore:
description: OutputStore specifies the object used to store intermediate data generated by Operations
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
parameterValues:
description: ParameterValues specify values for the the specified component's parameters. Any parameter required by the component must be specified.
items:
description: A ComponentParameterValue specifies a value for a named parameter. The associated component must publish a parameter with this name.
properties:
name:
description: Name of the component parameter to set.
type: string
value:
anyOf:
- type: integer
- type: string
description: Value to set.
x-kubernetes-int-or-string: true
required:
- name
- value
type: object
type: array
revisionName:
description: RevisionName of a specific component revision to which to bind ApplicationConfiguration. This is mutually exclusive with componentName.
type: string
scopes:
description: Scopes in which the specified component should exist.
items:
description: A ComponentScope specifies a scope in which a component should exist.
properties:
scopeRef:
description: A ScopeReference must refer to an OAM scope resource.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- scopeRef
type: object
type: array
traits:
description: Traits of the specified component.
items:
description: A ComponentTrait specifies a trait that should be applied to a component.
properties:
dataInputs:
description: DataInputs specify the data input sinks into this trait.
items:
description: DataInput specifies a data input sink to an object. If input is array, it will be appended to the target field paths.
properties:
conditions:
description: When the Conditions is satified, ToFieldPaths will be filled with passed value
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
inputStore:
description: InputStore specifies the object used to read intermediate data genereted by DataOutput
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
strategyMergeKeys:
description: StrategyMergeKeys specifies the merge key if the toFieldPaths target is an array. The StrategyMergeKeys is optional, by default, if the toFieldPaths target is an array, we will append. If StrategyMergeKeys specified, we will check the key in the target array. If any key exist, do update; if no key exist, append.
items:
type: string
type: array
toFieldPaths:
description: ToFieldPaths specifies the field paths of an object to fill passed value.
items:
type: string
type: array
valueFrom:
description: ValueFrom specifies the value source.
properties:
dataOutputName:
description: DataOutputName matches a name of a DataOutput in the same AppConfig.
type: string
required:
- dataOutputName
type: object
type: object
type: array
dataOutputs:
description: DataOutputs specify the data output sources from this trait.
items:
description: DataOutput specifies a data output source from an object.
properties:
conditions:
description: Conditions specify the conditions that should be satisfied before emitting a data output. Different conditions are AND-ed together. If no conditions is specified, it is by default to check output value not empty.
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
fieldPath:
description: FieldPath refers to the value of an object's field.
type: string
name:
description: Name is the unique name of a DataOutput in an ApplicationConfiguration.
type: string
outputStore:
description: OutputStore specifies the object used to store intermediate data generated by Operations
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
trait:
description: A Trait that will be created for the component
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
required:
- trait
type: object
type: array
type: object
type: array
required:
- components
type: object
status:
description: An ApplicationConfigurationStatus represents the observed state of a ApplicationConfiguration.
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
dependency:
description: DependencyStatus represents the observed state of the dependency of an ApplicationConfiguration.
properties:
unsatisfied:
items:
description: UnstaifiedDependency describes unsatisfied dependency flow between one pair of objects.
properties:
from:
description: DependencyFromObject represents the object that dependency data comes from.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
fieldPath:
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
reason:
type: string
to:
description: DependencyToObject represents the object that dependency data goes to.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
fieldPaths:
items:
type: string
type: array
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- from
- reason
- to
type: object
type: array
type: object
historyWorkloads:
description: HistoryWorkloads will record history but still working revision workloads.
items:
description: HistoryWorkload contain the old component revision that are still running
properties:
revision:
description: Revision of this workload
type: string
workloadRef:
description: Reference to running workload.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
observedGeneration:
description: The generation observed by the appConfig controller.
format: int64
type: integer
rollingStatus:
description: RollingStatus indicates what phase are we in the rollout phase
type: string
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the status of the entire application
type: string
workloads:
description: Workloads created by this ApplicationConfiguration.
items:
description: A WorkloadStatus represents the status of a workload.
properties:
appliedComponentRevision:
description: AppliedComponentRevision indicates the applied component revision name of this workload
type: string
componentName:
description: ComponentName that produced this workload.
type: string
componentRevisionName:
description: ComponentRevisionName of current component
type: string
dependencyUnsatisfied:
description: DependencyUnsatisfied notify does the workload has dependency unsatisfied
type: boolean
scopes:
description: Scopes associated with this workload.
items:
description: A WorkloadScope represents a scope associated with a workload and its status
properties:
scopeRef:
description: Reference to a scope created by an ApplicationConfiguration.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the status of the scope
type: string
required:
- scopeRef
type: object
type: array
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the entire status of the workload
type: string
traits:
description: Traits associated with this workload.
items:
description: A WorkloadTrait represents a trait associated with a workload and its status
properties:
appliedGeneration:
description: AppliedGeneration indicates the generation observed by the appConfig controller. The same field is also recorded in the annotations of traits. A trait is possible to be deleted from cluster after created. This field is useful to track the observed generation of traits after they are deleted.
format: int64
type: integer
dependencyUnsatisfied:
description: DependencyUnsatisfied notify does the trait has dependency unsatisfied
type: boolean
message:
description: Message will allow controller to leave some additional information for this trait
type: string
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the status of the trait
type: string
traitRef:
description: Reference to a trait created by an ApplicationConfiguration.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- traitRef
type: object
type: array
workloadRef:
description: Reference to a workload created by an ApplicationConfiguration.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
type: object
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
componentDefinitions:
additionalProperties:
description: ComponentDefinition is the Schema for the componentdefinitions API
@@ -1428,8 +592,7 @@ spec:
description: ComponentDefinitions records the snapshot of the componentDefinitions related with the created/modified Application
type: object
components:
description: Components records the rendered components from Application, it will contains the whole K8s CR of workload in it.
items:
additionalProperties:
description: A Component describes how an OAM workload kind may be instantiated.
properties:
apiVersion:
@@ -1543,7 +706,8 @@ spec:
type: integer
type: object
type: object
type: array
description: Components records the rendered components from Application, it will contains the whole K8s CR of workload in it.
type: object
scopeDefinitions:
additionalProperties:
description: A ScopeDefinition registers a kind of Kubernetes custom resource as a valid OAM scope kind by referencing its CustomResourceDefinition. The CRD is used to validate the schema of the scope when it is embedded in an OAM ApplicationConfiguration.
@@ -1849,7 +1013,6 @@ spec:
required:
- application
- applicationConfiguration
- components
type: object
type: object
served: true
@@ -443,845 +443,9 @@ spec:
type: object
applicationConfiguration:
description: ApplicationConfiguration records the rendered applicationConfiguration from Application, it will contains the whole K8s CR of trait and the reference component in it.
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: An ApplicationConfigurationSpec defines the desired state of a ApplicationConfiguration.
properties:
components:
description: Components of which this ApplicationConfiguration consists. Each component will be used to instantiate a workload.
items:
description: An ApplicationConfigurationComponent specifies a component of an ApplicationConfiguration. Each component is used to instantiate a workload.
properties:
componentName:
description: ComponentName specifies a component whose latest revision will be bind with ApplicationConfiguration. When the spec of the referenced component changes, ApplicationConfiguration will automatically migrate all trait affect from the prior revision to the new one. This is mutually exclusive with RevisionName.
type: string
dataInputs:
description: DataInputs specify the data input sinks into this component.
items:
description: DataInput specifies a data input sink to an object. If input is array, it will be appended to the target field paths.
properties:
conditions:
description: When the Conditions is satified, ToFieldPaths will be filled with passed value
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
inputStore:
description: InputStore specifies the object used to read intermediate data genereted by DataOutput
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
strategyMergeKeys:
description: StrategyMergeKeys specifies the merge key if the toFieldPaths target is an array. The StrategyMergeKeys is optional, by default, if the toFieldPaths target is an array, we will append. If StrategyMergeKeys specified, we will check the key in the target array. If any key exist, do update; if no key exist, append.
items:
type: string
type: array
toFieldPaths:
description: ToFieldPaths specifies the field paths of an object to fill passed value.
items:
type: string
type: array
valueFrom:
description: ValueFrom specifies the value source.
properties:
dataOutputName:
description: DataOutputName matches a name of a DataOutput in the same AppConfig.
type: string
required:
- dataOutputName
type: object
type: object
type: array
dataOutputs:
description: DataOutputs specify the data output sources from this component.
items:
description: DataOutput specifies a data output source from an object.
properties:
conditions:
description: Conditions specify the conditions that should be satisfied before emitting a data output. Different conditions are AND-ed together. If no conditions is specified, it is by default to check output value not empty.
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
fieldPath:
description: FieldPath refers to the value of an object's field.
type: string
name:
description: Name is the unique name of a DataOutput in an ApplicationConfiguration.
type: string
outputStore:
description: OutputStore specifies the object used to store intermediate data generated by Operations
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
parameterValues:
description: ParameterValues specify values for the the specified component's parameters. Any parameter required by the component must be specified.
items:
description: A ComponentParameterValue specifies a value for a named parameter. The associated component must publish a parameter with this name.
properties:
name:
description: Name of the component parameter to set.
type: string
value:
anyOf:
- type: integer
- type: string
description: Value to set.
x-kubernetes-int-or-string: true
required:
- name
- value
type: object
type: array
revisionName:
description: RevisionName of a specific component revision to which to bind ApplicationConfiguration. This is mutually exclusive with componentName.
type: string
scopes:
description: Scopes in which the specified component should exist.
items:
description: A ComponentScope specifies a scope in which a component should exist.
properties:
scopeRef:
description: A ScopeReference must refer to an OAM scope resource.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- scopeRef
type: object
type: array
traits:
description: Traits of the specified component.
items:
description: A ComponentTrait specifies a trait that should be applied to a component.
properties:
dataInputs:
description: DataInputs specify the data input sinks into this trait.
items:
description: DataInput specifies a data input sink to an object. If input is array, it will be appended to the target field paths.
properties:
conditions:
description: When the Conditions is satified, ToFieldPaths will be filled with passed value
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
inputStore:
description: InputStore specifies the object used to read intermediate data genereted by DataOutput
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
strategyMergeKeys:
description: StrategyMergeKeys specifies the merge key if the toFieldPaths target is an array. The StrategyMergeKeys is optional, by default, if the toFieldPaths target is an array, we will append. If StrategyMergeKeys specified, we will check the key in the target array. If any key exist, do update; if no key exist, append.
items:
type: string
type: array
toFieldPaths:
description: ToFieldPaths specifies the field paths of an object to fill passed value.
items:
type: string
type: array
valueFrom:
description: ValueFrom specifies the value source.
properties:
dataOutputName:
description: DataOutputName matches a name of a DataOutput in the same AppConfig.
type: string
required:
- dataOutputName
type: object
type: object
type: array
dataOutputs:
description: DataOutputs specify the data output sources from this trait.
items:
description: DataOutput specifies a data output source from an object.
properties:
conditions:
description: Conditions specify the conditions that should be satisfied before emitting a data output. Different conditions are AND-ed together. If no conditions is specified, it is by default to check output value not empty.
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
fieldPath:
description: FieldPath refers to the value of an object's field.
type: string
name:
description: Name is the unique name of a DataOutput in an ApplicationConfiguration.
type: string
outputStore:
description: OutputStore specifies the object used to store intermediate data generated by Operations
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
operations:
description: Operations specify the data processing operations
items:
description: DataOperation defines the specific operation for data
properties:
conditions:
items:
description: ConditionRequirement specifies the requirement to match a value.
properties:
fieldPath:
description: FieldPath specifies got value from workload/trait object
type: string
op:
description: ConditionOperator specifies the operator to match a value.
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from AppConfig This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
type: object
type: array
op:
description: Operator specifies the operation under this DataOperation type
type: string
toDataPath:
description: ToDataPath refers to the value of an object's specfied by ToDataPath. For example the ToDataPath "redis" specifies "redis info" in '{"redis":"redis info"}'
type: string
toFieldPath:
description: ToFieldPath refers to the value of an object's field
type: string
type:
description: Type specifies the type of DataOperation
type: string
value:
description: Value specifies an expected value This is mutually exclusive with ValueFrom
type: string
valueFrom:
description: ValueFrom specifies expected value from object such as workload and trait This is mutually exclusive with Value
properties:
fieldPath:
type: string
required:
- fieldPath
type: object
required:
- op
- toFieldPath
- type
type: object
type: array
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
trait:
description: A Trait that will be created for the component
type: object
required:
- trait
type: object
type: array
type: object
type: array
required:
- components
type: object
status:
description: An ApplicationConfigurationStatus represents the observed state of a ApplicationConfiguration.
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
dependency:
description: DependencyStatus represents the observed state of the dependency of an ApplicationConfiguration.
properties:
unsatisfied:
items:
description: UnstaifiedDependency describes unsatisfied dependency flow between one pair of objects.
properties:
from:
description: DependencyFromObject represents the object that dependency data comes from.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
fieldPath:
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
reason:
type: string
to:
description: DependencyToObject represents the object that dependency data goes to.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
fieldPaths:
items:
type: string
type: array
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- from
- reason
- to
type: object
type: array
type: object
historyWorkloads:
description: HistoryWorkloads will record history but still working revision workloads.
items:
description: HistoryWorkload contain the old component revision that are still running
properties:
revision:
description: Revision of this workload
type: string
workloadRef:
description: Reference to running workload.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
observedGeneration:
description: The generation observed by the appConfig controller.
format: int64
type: integer
rollingStatus:
description: RollingStatus indicates what phase are we in the rollout phase
type: string
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the status of the entire application
type: string
workloads:
description: Workloads created by this ApplicationConfiguration.
items:
description: A WorkloadStatus represents the status of a workload.
properties:
appliedComponentRevision:
description: AppliedComponentRevision indicates the applied component revision name of this workload
type: string
componentName:
description: ComponentName that produced this workload.
type: string
componentRevisionName:
description: ComponentRevisionName of current component
type: string
dependencyUnsatisfied:
description: DependencyUnsatisfied notify does the workload has dependency unsatisfied
type: boolean
scopes:
description: Scopes associated with this workload.
items:
description: A WorkloadScope represents a scope associated with a workload and its status
properties:
scopeRef:
description: Reference to a scope created by an ApplicationConfiguration.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the status of the scope
type: string
required:
- scopeRef
type: object
type: array
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the entire status of the workload
type: string
traits:
description: Traits associated with this workload.
items:
description: A WorkloadTrait represents a trait associated with a workload and its status
properties:
appliedGeneration:
description: AppliedGeneration indicates the generation observed by the appConfig controller. The same field is also recorded in the annotations of traits. A trait is possible to be deleted from cluster after created. This field is useful to track the observed generation of traits after they are deleted.
format: int64
type: integer
dependencyUnsatisfied:
description: DependencyUnsatisfied notify does the trait has dependency unsatisfied
type: boolean
message:
description: Message will allow controller to leave some additional information for this trait
type: string
status:
description: Status is a place holder for a customized controller to fill if it needs a single place to summarize the status of the trait
type: string
traitRef:
description: Reference to a trait created by an ApplicationConfiguration.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- traitRef
type: object
type: array
workloadRef:
description: Reference to a workload created by an ApplicationConfiguration.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: object
type: array
type: object
type: object
componentDefinitions:
additionalProperties:
description: ComponentDefinition is the Schema for the componentdefinitions API
@@ -1426,8 +590,7 @@ spec:
description: ComponentDefinitions records the snapshot of the componentDefinitions related with the created/modified Application
type: object
components:
description: Components records the rendered components from Application, it will contains the whole K8s CR of workload in it.
items:
additionalProperties:
description: A Component describes how an OAM workload kind may be instantiated.
properties:
apiVersion:
@@ -1541,7 +704,8 @@ spec:
type: integer
type: object
type: object
type: array
description: Components records the rendered components from Application, it will contains the whole K8s CR of workload in it.
type: object
scopeDefinitions:
additionalProperties:
description: A ScopeDefinition registers a kind of Kubernetes custom resource as a valid OAM scope kind by referencing its CustomResourceDefinition. The CRD is used to validate the schema of the scope when it is embedded in an OAM ApplicationConfiguration.
@@ -1847,7 +1011,6 @@ spec:
required:
- application
- applicationConfiguration
- components
type: object
type: object
version: v1alpha2
@@ -43,6 +43,7 @@ import (
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/applicationcontext"
"github.com/oam-dev/kubevela/pkg/controller/utils"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
@@ -360,7 +361,10 @@ var _ = Describe("Test Application Controller", func() {
}, appRevision)).Should(BeNil())
gotTrait := unstructured.Unstructured{}
Expect(json.Unmarshal(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits[0].Trait.Raw,
ac, err := applicationcontext.ConvertRawExtention2AppConfig(appRevision.Spec.ApplicationConfiguration)
Expect(err).Should(BeNil())
Expect(json.Unmarshal(ac.Spec.Components[0].Traits[0].Trait.Raw,
&gotTrait)).Should(BeNil())
Expect(gotTrait).Should(BeEquivalentTo(expectScalerTrait("myweb3", app.Name)))
@@ -429,12 +433,16 @@ var _ = Describe("Test Application Controller", func() {
Namespace: app.Namespace,
Name: curApp.Status.LatestRevision.Name,
}, appRevision)).Should(BeNil())
Expect(appContext.Spec.ApplicationRevisionName).Should(Equal(appRevision.Name))
Expect(len(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits)).Should(BeEquivalentTo(2))
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].ComponentName).Should(BeEmpty())
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].RevisionName).ShouldNot(BeEmpty())
ac, err := applicationcontext.ConvertRawExtention2AppConfig(appRevision.Spec.ApplicationConfiguration)
Expect(err).Should(BeNil())
Expect(len(ac.Spec.Components[0].Traits)).Should(BeEquivalentTo(2))
Expect(ac.Spec.Components[0].ComponentName).Should(BeEmpty())
Expect(ac.Spec.Components[0].RevisionName).ShouldNot(BeEmpty())
// component create handler may create a v2 when it can't find v1
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].RevisionName).Should(
Expect(ac.Spec.Components[0].RevisionName).Should(
SatisfyAny(BeEquivalentTo(utils.ConstructRevisionName(compName, 1)),
BeEquivalentTo(utils.ConstructRevisionName(compName, 2))))
@@ -460,13 +468,15 @@ var _ = Describe("Test Application Controller", func() {
},
},
}}
Expect(json.Unmarshal(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
ac, err = applicationcontext.ConvertRawExtention2AppConfig(appRevision.Spec.ApplicationConfiguration)
Expect(err).Should(BeNil())
Expect(json.Unmarshal(ac.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
fmt.Println(cmp.Diff(expectServiceTrait, gotTrait))
Expect(assert.ObjectsAreEqual(expectServiceTrait, gotTrait)).Should(BeTrue())
By("Check the second trait should be scaler")
gotTrait = unstructured.Unstructured{}
Expect(json.Unmarshal(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits[1].Trait.Raw, &gotTrait)).Should(BeNil())
Expect(json.Unmarshal(ac.Spec.Components[0].Traits[1].Trait.Raw, &gotTrait)).Should(BeNil())
Expect(gotTrait).Should(BeEquivalentTo(expectScalerTrait("myweb-composed-3", app.Name)))
By("Check component created as expected")
@@ -527,10 +537,12 @@ var _ = Describe("Test Application Controller", func() {
Expect(appContext.Spec.ApplicationRevisionName).Should(Equal(appRevision.Name))
gotTrait := unstructured.Unstructured{}
Expect(json.Unmarshal(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
ac, err := applicationcontext.ConvertRawExtention2AppConfig(appRevision.Spec.ApplicationConfiguration)
Expect(err).Should(BeNil())
Expect(json.Unmarshal(ac.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
Expect(gotTrait).Should(BeEquivalentTo(expectScalerTrait("myweb4", app.Name)))
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
Expect(ac.Spec.Components[0].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
APIVersion: "core.oam.dev/v1alpha2",
Kind: "HealthScope",
Name: "appWithTraitAndScope-default-health",
@@ -595,15 +607,17 @@ var _ = Describe("Test Application Controller", func() {
Expect(appContext.Spec.ApplicationRevisionName).Should(Equal(appRevision.Name))
gotTrait := unstructured.Unstructured{}
Expect(json.Unmarshal(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
ac, err := applicationcontext.ConvertRawExtention2AppConfig(appRevision.Spec.ApplicationConfiguration)
Expect(err).Should(BeNil())
Expect(json.Unmarshal(ac.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
Expect(gotTrait).Should(BeEquivalentTo(expectScalerTrait("myweb5", app.Name)))
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
Expect(ac.Spec.Components[0].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
APIVersion: "core.oam.dev/v1alpha2",
Kind: "HealthScope",
Name: "app-with-two-comp-default-health",
}))
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[1].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
Expect(ac.Spec.Components[1].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
APIVersion: "core.oam.dev/v1alpha2",
Kind: "HealthScope",
Name: "app-with-two-comp-default-health",
@@ -667,15 +681,15 @@ var _ = Describe("Test Application Controller", func() {
}, appRevision)).Should(BeNil())
Expect(appContext.Spec.ApplicationRevisionName).Should(Equal(appRevision.Name))
Expect(json.Unmarshal(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
Expect(json.Unmarshal(ac.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
Expect(gotTrait).Should(BeEquivalentTo(expectScalerTrait("myweb5", app.Name)))
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
Expect(ac.Spec.Components[0].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
APIVersion: "core.oam.dev/v1alpha2",
Kind: "HealthScope",
Name: "app-with-two-comp-default-health",
}))
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[1].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
Expect(ac.Spec.Components[1].Scopes[0].ScopeReference).Should(BeEquivalentTo(v1alpha1.TypedReference{
APIVersion: "core.oam.dev/v1alpha2",
Kind: "HealthScope",
Name: "app-with-two-comp-default-health",
@@ -752,7 +766,10 @@ var _ = Describe("Test Application Controller", func() {
}, appRevision)).Should(BeNil())
Expect(appContext.Spec.ApplicationRevisionName).Should(Equal(appRevision.Name))
gotTrait := unstructured.Unstructured{}
Expect(json.Unmarshal(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
ac, err := applicationcontext.ConvertRawExtention2AppConfig(appRevision.Spec.ApplicationConfiguration)
Expect(err).Should(BeNil())
Expect(json.Unmarshal(ac.Spec.Components[0].Traits[0].Trait.Raw, &gotTrait)).Should(BeNil())
Expect(gotTrait).Should(BeEquivalentTo(expTrait))
Expect(k8sClient.Delete(ctx, app)).Should(BeNil())
@@ -916,11 +933,13 @@ var _ = Describe("Test Application Controller", func() {
Expect(component.Status.LatestRevision).ShouldNot(BeNil())
Expect(component.Status.LatestRevision.Revision).Should(BeEquivalentTo(1))
// check that the new appconfig has the correct annotation and labels
Expect(appRevision.Spec.ApplicationConfiguration.GetAnnotations()[oam.AnnotationAppRollout]).Should(Equal(strconv.FormatBool(true)))
Expect(appRevision.Spec.ApplicationConfiguration.GetAnnotations()["keep"]).Should(Equal("true"))
Expect(appRevision.Spec.ApplicationConfiguration.GetLabels()[oam.LabelAppRevisionHash]).ShouldNot(BeEmpty())
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].ComponentName).Should(BeEmpty())
Expect(appRevision.Spec.ApplicationConfiguration.Spec.Components[0].RevisionName).Should(Equal(component.Status.LatestRevision.Name))
ac, err := applicationcontext.ConvertRawExtention2AppConfig(appRevision.Spec.ApplicationConfiguration)
Expect(err).Should(BeNil())
Expect(ac.GetAnnotations()[oam.AnnotationAppRollout]).Should(Equal(strconv.FormatBool(true)))
Expect(ac.GetAnnotations()["keep"]).Should(Equal("true"))
Expect(ac.GetLabels()[oam.LabelAppRevisionHash]).ShouldNot(BeEmpty())
Expect(ac.Spec.Components[0].ComponentName).Should(BeEmpty())
Expect(ac.Spec.Components[0].RevisionName).Should(Equal(component.Status.LatestRevision.Name))
By("Reconcile again to make sure we are not creating more appConfigs")
reconcileRetry(reconciler, reconcile.Request{NamespacedName: appKey})
@@ -26,6 +26,7 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
"github.com/oam-dev/kubevela/pkg/controller/utils"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
)
// AppRevisionHash is used to compute the hash value of the AppRevision
@@ -45,8 +46,8 @@ func (h *appHandler) GenerateRevision(ctx context.Context, ac *v1alpha2.Applicat
appRev := &v1alpha2.ApplicationRevision{
Spec: v1alpha2.ApplicationRevisionSpec{
Application: *copiedApp,
Components: comps,
ApplicationConfiguration: *ac,
Components: convertComponentList2Map(comps),
ApplicationConfiguration: util.Object2RawExtension(ac),
ComponentDefinitions: make(map[string]v1alpha2.ComponentDefinition),
WorkloadDefinitions: make(map[string]v1alpha2.WorkloadDefinition),
TraitDefinitions: make(map[string]v1alpha2.TraitDefinition),
@@ -118,6 +119,15 @@ func (h *appHandler) GenerateRevision(ctx context.Context, ac *v1alpha2.Applicat
return true, appRev, nil
}
func convertComponentList2Map(comps []*v1alpha2.Component) map[string]v1alpha2.Component {
objs := map[string]v1alpha2.Component{}
for _, comp := range comps {
obj := comp.DeepCopy()
objs[comp.Name] = *obj
}
return objs
}
// DeepEqualRevision will check the Application and Definition to see if the Application is the same revision
// AC and component are generated by the application and definitions
func DeepEqualRevision(old, new *v1alpha2.ApplicationRevision) bool {
@@ -2,6 +2,7 @@ package applicationcontext
import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
@@ -11,6 +12,7 @@ import (
"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -74,7 +76,11 @@ func (r *Reconciler) Reconcile(request reconcile.Request) (reconcile.Result, err
}
// copy the status
appConfig := appRevision.Spec.ApplicationConfiguration.DeepCopy()
acRaw := appRevision.Spec.ApplicationConfiguration
appConfig, err := ConvertRawExtention2AppConfig(acRaw)
if err != nil {
return reconcile.Result{}, err
}
appConfig.Status = appContext.Status
// the name of the appConfig has to be the same as the appContext
appConfig.ObjectMeta = metav1.ObjectMeta{Namespace: appContext.Namespace, Name: appContext.Name, UID: appContext.UID}
@@ -91,6 +97,19 @@ func (r *Reconciler) Reconcile(request reconcile.Request) (reconcile.Result, err
return reconResult, err
}
// ConvertRawExtention2AppConfig converts runtime.RawExtention to ApplicationConfiguration
func ConvertRawExtention2AppConfig(raw runtime.RawExtension) (*v1alpha2.ApplicationConfiguration, error) {
ac := &v1alpha2.ApplicationConfiguration{}
b, err := raw.MarshalJSON()
if err != nil {
return nil, err
}
if err := json.Unmarshal(b, ac); err != nil {
return nil, err
}
return ac, nil
}
// SetupWithManager setup the controller with manager
func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
r.record = event.NewAPIRecorder(mgr.GetEventRecorderFor("AppRollout")).