kubevela/pkg/appfile/parser.go

699 lines
24 KiB
Go
Raw Normal View History

/*
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 appfile
import (
"context"
"encoding/json"
"fmt"
"sort"
"github.com/pkg/errors"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
ktypes "k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"sigs.k8s.io/controller-runtime/pkg/client"
monitorContext "github.com/kubevela/pkg/monitor/context"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/auth"
"github.com/oam-dev/kubevela/pkg/component"
"github.com/oam-dev/kubevela/pkg/cue/definition"
"github.com/oam-dev/kubevela/pkg/features"
Feat: add more performance optimization and prometheus metrics for controller (#3086) * Feat: add more prometheus metrics Signed-off-by: yangsoon <yangsoonlx@gmail.com> * Feat: add detail gc rt duration metrics Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add monitor to client Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add all cache object Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Fix: watch job Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add deleg client Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add optimize for rt list and disable controllerrevision Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add apprev disable optimize Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Fix: optimize log Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add time recorder for app ctrl Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add in-memory workflow context Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add reconcile-reduction & random-pick-gc & optimize rt record Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add optimize for healthcheck & resourcetracker trigger Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: record the resource-tracker number by informer event-handler Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Feat: add promethus collect annotation in template Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Fix: command line comment bug Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: rename args and remove legacy controller metrics Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: make code reviewable Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Chore: optimize flag descriptions Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: break optimize package Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: gc policy test Signed-off-by: Somefive <yd219913@alibaba-inc.com> Co-authored-by: Yin Da <yd219913@alibaba-inc.com> Co-authored-by: yangsoon <songyang.song@alibaba-inc.com>
2022-01-14 15:18:02 +08:00
"github.com/oam-dev/kubevela/pkg/monitor/metrics"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
policypkg "github.com/oam-dev/kubevela/pkg/policy"
"github.com/oam-dev/kubevela/pkg/utils"
utilscommon "github.com/oam-dev/kubevela/pkg/utils/common"
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
"github.com/oam-dev/kubevela/pkg/workflow/step"
)
// TemplateLoaderFn load template of a capability definition
type TemplateLoaderFn func(context.Context, client.Client, string, types.CapType) (*Template, error)
// LoadTemplate load template of a capability definition
func (fn TemplateLoaderFn) LoadTemplate(ctx context.Context, c client.Client, capName string, capType types.CapType) (*Template, error) {
return fn(ctx, c, capName, capType)
}
// Parser is an application parser
type Parser struct {
client client.Client
pd *packages.PackageDiscover
tmplLoader TemplateLoaderFn
}
// NewApplicationParser create appfile parser
func NewApplicationParser(cli client.Client, pd *packages.PackageDiscover) *Parser {
return &Parser{
client: cli,
pd: pd,
tmplLoader: LoadTemplate,
}
}
// NewDryRunApplicationParser create an appfile parser for DryRun
func NewDryRunApplicationParser(cli client.Client, pd *packages.PackageDiscover, defs []oam.Object) *Parser {
return &Parser{
client: cli,
pd: pd,
tmplLoader: DryRunTemplateLoader(defs),
}
}
// GenerateAppFile generate appfile for the application to run, if the application is controlled by PublishVersion,
// the application revision will be used to create the appfile
func (p *Parser) GenerateAppFile(ctx context.Context, app *v1beta1.Application) (*Appfile, error) {
Feat: add more performance optimization and prometheus metrics for controller (#3086) * Feat: add more prometheus metrics Signed-off-by: yangsoon <yangsoonlx@gmail.com> * Feat: add detail gc rt duration metrics Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add monitor to client Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add all cache object Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Fix: watch job Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add deleg client Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add optimize for rt list and disable controllerrevision Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add apprev disable optimize Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Fix: optimize log Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add time recorder for app ctrl Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add in-memory workflow context Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add reconcile-reduction & random-pick-gc & optimize rt record Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add optimize for healthcheck & resourcetracker trigger Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: record the resource-tracker number by informer event-handler Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Feat: add promethus collect annotation in template Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Fix: command line comment bug Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: rename args and remove legacy controller metrics Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: make code reviewable Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Chore: optimize flag descriptions Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: break optimize package Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: gc policy test Signed-off-by: Somefive <yd219913@alibaba-inc.com> Co-authored-by: Yin Da <yd219913@alibaba-inc.com> Co-authored-by: yangsoon <songyang.song@alibaba-inc.com>
2022-01-14 15:18:02 +08:00
if ctx, ok := ctx.(monitorContext.Context); ok {
subCtx := ctx.Fork("generate-app-file", monitorContext.DurationMetric(func(v float64) {
metrics.AppReconcileStageDurationHistogram.WithLabelValues("generate-appfile").Observe(v)
Feat: add more performance optimization and prometheus metrics for controller (#3086) * Feat: add more prometheus metrics Signed-off-by: yangsoon <yangsoonlx@gmail.com> * Feat: add detail gc rt duration metrics Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add monitor to client Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add all cache object Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Fix: watch job Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add deleg client Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add optimize for rt list and disable controllerrevision Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add apprev disable optimize Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Fix: optimize log Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add time recorder for app ctrl Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add in-memory workflow context Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add reconcile-reduction & random-pick-gc & optimize rt record Signed-off-by: Yin Da <yd219913@alibaba-inc.com> * Feat: add optimize for healthcheck & resourcetracker trigger Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: record the resource-tracker number by informer event-handler Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Feat: add promethus collect annotation in template Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Fix: command line comment bug Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: rename args and remove legacy controller metrics Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: make code reviewable Signed-off-by: yangsoon <songyang.song@alibaba-inc.com> * Chore: optimize flag descriptions Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: break optimize package Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: gc policy test Signed-off-by: Somefive <yd219913@alibaba-inc.com> Co-authored-by: Yin Da <yd219913@alibaba-inc.com> Co-authored-by: yangsoon <songyang.song@alibaba-inc.com>
2022-01-14 15:18:02 +08:00
}))
defer subCtx.Commit("finish generate appFile")
}
if isLatest, appRev, err := p.isLatestPublishVersion(ctx, app); err != nil {
return nil, err
} else if isLatest {
app.Spec = appRev.Spec.Application.Spec
return p.GenerateAppFileFromRevision(appRev)
}
return p.GenerateAppFileFromApp(ctx, app)
}
// GenerateAppFileFromApp converts an application to an Appfile
func (p *Parser) GenerateAppFileFromApp(ctx context.Context, app *v1beta1.Application) (*Appfile, error) {
ns := app.Namespace
appName := app.Name
2023-05-04 16:48:43 +08:00
for idx := range app.Spec.Policies {
if app.Spec.Policies[idx].Name == "" {
app.Spec.Policies[idx].Name = fmt.Sprintf("%s:auto-gen:%d", app.Spec.Policies[idx].Type, idx)
}
}
appfile := p.newAppFile(appName, ns, app)
if app.Status.LatestRevision != nil {
appfile.AppRevisionName = app.Status.LatestRevision.Name
}
var wds []*Workload
for _, comp := range app.Spec.Components {
wd, err := p.parseWorkload(ctx, comp)
if err != nil {
return nil, err
}
wds = append(wds, wd)
}
appfile.Workloads = wds
2021-08-04 18:58:57 +08:00
appfile.Components = app.Spec.Components
var err error
if err = p.parseWorkflowSteps(ctx, appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseWorkflowSteps")
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
}
if err = p.parsePolicies(ctx, appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parsePolicies")
}
if err = p.parseReferredObjects(ctx, appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseReferredObjects")
}
for _, w := range wds {
if w == nil {
continue
}
if w.FullTemplate.ComponentDefinition != nil {
cd := w.FullTemplate.ComponentDefinition.DeepCopy()
cd.Status = v1beta1.ComponentDefinitionStatus{}
appfile.RelatedComponentDefinitions[w.FullTemplate.ComponentDefinition.Name] = cd
}
for _, t := range w.Traits {
if t == nil {
continue
}
if t.FullTemplate.TraitDefinition != nil {
td := t.FullTemplate.TraitDefinition.DeepCopy()
td.Status = v1beta1.TraitDefinitionStatus{}
appfile.RelatedTraitDefinitions[t.FullTemplate.TraitDefinition.Name] = td
}
}
}
return appfile, nil
}
func (p *Parser) newAppFile(appName, ns string, app *v1beta1.Application) *Appfile {
file := &Appfile{
Name: appName,
Namespace: ns,
AppLabels: make(map[string]string),
AppAnnotations: make(map[string]string),
RelatedTraitDefinitions: make(map[string]*v1beta1.TraitDefinition),
RelatedComponentDefinitions: make(map[string]*v1beta1.ComponentDefinition),
RelatedWorkflowStepDefinitions: make(map[string]*v1beta1.WorkflowStepDefinition),
ExternalPolicies: make(map[string]*v1alpha1.Policy),
parser: p,
app: app,
}
for k, v := range app.Annotations {
file.AppAnnotations[k] = v
}
for k, v := range app.Labels {
file.AppLabels[k] = v
}
return file
}
// isLatestPublishVersion checks if the latest application revision has the same publishVersion with the application,
// return true and the latest ApplicationRevision if they share the same publishVersion
func (p *Parser) isLatestPublishVersion(ctx context.Context, app *v1beta1.Application) (bool, *v1beta1.ApplicationRevision, error) {
if !metav1.HasAnnotation(app.ObjectMeta, oam.AnnotationPublishVersion) {
return false, nil, nil
}
if app.Status.LatestRevision == nil {
return false, nil, nil
}
appRev := &v1beta1.ApplicationRevision{}
if err := p.client.Get(ctx, ktypes.NamespacedName{Name: app.Status.LatestRevision.Name, Namespace: app.GetNamespace()}, appRev); err != nil {
if kerrors.IsNotFound(err) {
return false, nil, nil
}
return false, nil, errors.Wrapf(err, "failed to load latest application revision")
}
if !metav1.HasAnnotation(appRev.ObjectMeta, oam.AnnotationPublishVersion) {
return false, nil, nil
}
if app.GetAnnotations()[oam.AnnotationPublishVersion] != appRev.GetAnnotations()[oam.AnnotationPublishVersion] {
return false, nil, nil
}
return true, appRev, nil
}
// inheritLabelAndAnnotationFromAppRev is a compatible function, that we can't record metadata for application object in AppRev
func inheritLabelAndAnnotationFromAppRev(appRev *v1beta1.ApplicationRevision) {
if len(appRev.Spec.Application.Annotations) > 0 || len(appRev.Spec.Application.Labels) > 0 {
return
}
appRev.Spec.Application.SetNamespace(appRev.Namespace)
if appRev.Spec.Application.GetName() == "" {
appRev.Spec.Application.SetName(appRev.Labels[oam.LabelAppName])
}
labels := make(map[string]string)
for k, v := range appRev.GetLabels() {
if k == oam.LabelAppRevisionHash || k == oam.LabelAppName {
continue
}
labels[k] = v
}
appRev.Spec.Application.SetLabels(labels)
annotations := make(map[string]string)
for k, v := range appRev.GetAnnotations() {
annotations[k] = v
}
appRev.Spec.Application.SetAnnotations(annotations)
}
// GenerateAppFileFromRevision converts an application revision to an Appfile
func (p *Parser) GenerateAppFileFromRevision(appRev *v1beta1.ApplicationRevision) (*Appfile, error) {
inheritLabelAndAnnotationFromAppRev(appRev)
app := appRev.Spec.Application.DeepCopy()
ns := app.Namespace
appName := app.Name
appfile := p.newAppFile(appName, ns, app)
appfile.AppRevision = appRev
appfile.AppRevisionName = appRev.Name
appfile.AppRevisionHash = appRev.Labels[oam.LabelAppRevisionHash]
appfile.ExternalPolicies = make(map[string]*v1alpha1.Policy)
for key, po := range appRev.Spec.Policies {
appfile.ExternalPolicies[key] = po.DeepCopy()
}
appfile.ExternalWorkflow = appRev.Spec.Workflow
var wds []*Workload
for _, comp := range app.Spec.Components {
wd, err := p.ParseWorkloadFromRevision(comp, appRev)
if err != nil {
return nil, err
}
wds = append(wds, wd)
}
appfile.Workloads = wds
appfile.Components = app.Spec.Components
if err := p.parseWorkflowStepsFromRevision(context.Background(), appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseWorkflowStepsFromRevision")
}
if err := p.parsePoliciesFromRevision(context.Background(), appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parsePolicies")
}
if err := p.parseReferredObjectsFromRevision(appfile); err != nil {
return nil, errors.Wrapf(err, "failed to parseReferredObjects")
}
for k, v := range appRev.Spec.ComponentDefinitions {
appfile.RelatedComponentDefinitions[k] = v.DeepCopy()
}
for k, v := range appRev.Spec.TraitDefinitions {
appfile.RelatedTraitDefinitions[k] = v.DeepCopy()
}
for k, v := range appRev.Spec.WorkflowStepDefinitions {
appfile.RelatedWorkflowStepDefinitions[k] = v.DeepCopy()
}
// add compatible code for upgrading to v1.3 as the workflow steps were not recorded before v1.2
if len(appfile.RelatedWorkflowStepDefinitions) == 0 && len(appfile.WorkflowSteps) > 0 {
ctx := context.Background()
for _, workflowStep := range appfile.WorkflowSteps {
if step.IsBuiltinWorkflowStepType(workflowStep.Type) {
continue
}
if _, found := appfile.RelatedWorkflowStepDefinitions[workflowStep.Type]; found {
continue
}
def := &v1beta1.WorkflowStepDefinition{}
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type); err != nil {
return nil, errors.Wrapf(err, "failed to get workflow step definition %s", workflowStep.Type)
}
appfile.RelatedWorkflowStepDefinitions[workflowStep.Type] = def
}
appRev.Spec.WorkflowStepDefinitions = make(map[string]*v1beta1.WorkflowStepDefinition)
for name, def := range appfile.RelatedWorkflowStepDefinitions {
appRev.Spec.WorkflowStepDefinitions[name] = def
}
}
return appfile, nil
}
func (p *Parser) parseReferredObjectsFromRevision(af *Appfile) error {
af.ReferredObjects = []*unstructured.Unstructured{}
for _, obj := range af.AppRevision.Spec.ReferredObjects {
un := &unstructured.Unstructured{}
if err := json.Unmarshal(obj.Raw, un); err != nil {
return errors.Errorf("failed to unmarshal referred objects %s", obj.Raw)
}
af.ReferredObjects = append(af.ReferredObjects, un)
}
return nil
}
func (p *Parser) parseReferredObjects(ctx context.Context, af *Appfile) error {
ctx = auth.ContextWithUserInfo(ctx, af.app)
for _, comp := range af.Components {
if comp.Type != v1alpha1.RefObjectsComponentType {
continue
}
spec := &v1alpha1.RefObjectsComponentSpec{}
if err := utils.StrictUnmarshal(comp.Properties.Raw, spec); err != nil {
return errors.Wrapf(err, "invalid properties for ref-objects in component %s", comp.Name)
}
for _, selector := range spec.Objects {
objs, err := component.SelectRefObjectsForDispatch(ctx, p.client, af.app.GetNamespace(), comp.Name, selector)
if err != nil {
return err
}
af.ReferredObjects = component.AppendUnstructuredObjects(af.ReferredObjects, objs...)
}
if utilfeature.DefaultMutableFeatureGate.Enabled(features.DisableReferObjectsFromURL) && len(spec.URLs) > 0 {
return fmt.Errorf("referring objects from url is disabled")
}
for _, url := range spec.URLs {
objs, err := utilscommon.HTTPGetKubernetesObjects(ctx, url)
if err != nil {
return fmt.Errorf("failed to load Kubernetes objects from url %s: %w", url, err)
}
for _, obj := range objs {
util.AddAnnotations(obj, map[string]string{oam.AnnotationResourceURL: url})
}
af.ReferredObjects = component.AppendUnstructuredObjects(af.ReferredObjects, objs...)
}
}
sort.Slice(af.ReferredObjects, func(i, j int) bool {
a, b := af.ReferredObjects[i], af.ReferredObjects[j]
keyA := a.GroupVersionKind().String() + "|" + client.ObjectKeyFromObject(a).String()
keyB := b.GroupVersionKind().String() + "|" + client.ObjectKeyFromObject(b).String()
return keyA < keyB
})
return nil
}
func (p *Parser) parsePoliciesFromRevision(ctx context.Context, af *Appfile) (err error) {
af.Policies, err = step.LoadExternalPoliciesForWorkflow(ctx, af.PolicyClient(p.client), af.app.GetNamespace(), af.WorkflowSteps, af.app.Spec.Policies)
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
if err != nil {
return err
}
for _, policy := range af.Policies {
if policy.Properties == nil && policy.Type != v1alpha1.DebugPolicyType {
return fmt.Errorf("policy %s named %s must not have empty properties", policy.Type, policy.Name)
}
switch policy.Type {
case v1alpha1.GarbageCollectPolicyType:
case v1alpha1.ApplyOncePolicyType:
case v1alpha1.SharedResourcePolicyType:
case v1alpha1.TakeOverPolicyType:
case v1alpha1.ReadOnlyPolicyType:
case v1alpha1.ResourceUpdatePolicyType:
case v1alpha1.EnvBindingPolicyType:
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
case v1alpha1.TopologyPolicyType:
case v1alpha1.OverridePolicyType:
case v1alpha1.DebugPolicyType:
af.Debug = true
default:
w, err := p.makeWorkloadFromRevision(policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.AppRevision)
if err != nil {
return err
}
af.PolicyWorkloads = append(af.PolicyWorkloads, w)
}
}
return nil
}
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
func (p *Parser) parsePolicies(ctx context.Context, af *Appfile) (err error) {
af.Policies, err = step.LoadExternalPoliciesForWorkflow(ctx, af.PolicyClient(p.client), af.app.GetNamespace(), af.WorkflowSteps, af.app.Spec.Policies)
if err != nil {
return err
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
}
for _, policy := range af.Policies {
if policy.Properties == nil && policy.Type != v1alpha1.DebugPolicyType {
return fmt.Errorf("policy %s named %s must not have empty properties", policy.Type, policy.Name)
}
switch policy.Type {
case v1alpha1.GarbageCollectPolicyType:
case v1alpha1.ApplyOncePolicyType:
case v1alpha1.SharedResourcePolicyType:
case v1alpha1.TakeOverPolicyType:
case v1alpha1.ReadOnlyPolicyType:
case v1alpha1.ResourceUpdatePolicyType:
case v1alpha1.EnvBindingPolicyType:
case v1alpha1.TopologyPolicyType:
2022-08-17 14:04:57 +08:00
case v1alpha1.ReplicationPolicyType:
case v1alpha1.DebugPolicyType:
af.Debug = true
case v1alpha1.OverridePolicyType:
compDefs, traitDefs, err := policypkg.ParseOverridePolicyRelatedDefinitions(ctx, p.client, af.app, policy)
if err != nil {
return err
}
for _, def := range compDefs {
af.RelatedComponentDefinitions[def.Name] = def
}
for _, def := range traitDefs {
af.RelatedTraitDefinitions[def.Name] = def
}
default:
w, err := p.makeWorkload(ctx, policy.Name, policy.Type, types.TypePolicy, policy.Properties)
if err != nil {
return err
}
af.PolicyWorkloads = append(af.PolicyWorkloads, w)
}
Feat: support standalone style multi-cluster (#3223) * Feat: ref component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support topology and override Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add support for external policy and workflow Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add admission control Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: disable cross namespace ref object Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support labelSelector in ref-objects Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add pre approve for deploy step Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support comp/trait type in override policy even not used by prototype Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: support regex match for patch component name Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: labelSelector not work for cluster Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: ref workflow contains external policy Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revision test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: parallel apply components Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for oam provider Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: service ref-comp & indirect trait ns Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: align namespace setting for chart Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add strict unmarshal and reformat Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: merge with cluster rework Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: patch trait-def Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: apply components + load dynamic component Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for loadPoliciesInOrder Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add test for open merge Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: reformat & add test for step generator Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for parse override policy related defs Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for multicluster provider (expandTopology and overrideConfiguration) Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add admission test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: revert trait status pass in component status Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add test for dependency in workflowstep & standalone multicluster test Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Fix: add check for ref and steps in WorkflowStep & enhance ref-objects scheme check Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-03-07 10:21:00 +08:00
}
return nil
}
func (p *Parser) loadWorkflowToAppfile(ctx context.Context, af *Appfile) error {
var err error
// parse workflow steps
af.WorkflowMode = &workflowv1alpha1.WorkflowExecuteMode{
Steps: workflowv1alpha1.WorkflowModeDAG,
SubSteps: workflowv1alpha1.WorkflowModeDAG,
}
if wfSpec := af.app.Spec.Workflow; wfSpec != nil {
app := af.app
mode := wfSpec.Mode
if wfSpec.Ref != "" && mode == nil {
wf := &workflowv1alpha1.Workflow{}
if err := af.WorkflowClient(p.client).Get(ctx, ktypes.NamespacedName{Namespace: af.app.Namespace, Name: app.Spec.Workflow.Ref}, wf); err != nil {
return err
}
mode = wf.Mode
}
af.WorkflowSteps = wfSpec.Steps
af.WorkflowMode.Steps = workflowv1alpha1.WorkflowModeStep
if mode != nil {
if mode.Steps != "" {
af.WorkflowMode.Steps = mode.Steps
}
if mode.SubSteps != "" {
af.WorkflowMode.SubSteps = mode.SubSteps
}
}
}
af.WorkflowSteps, err = step.NewChainWorkflowStepGenerator(
&step.RefWorkflowStepGenerator{Client: af.WorkflowClient(p.client), Context: ctx},
&step.DeployWorkflowStepGenerator{},
&step.Deploy2EnvWorkflowStepGenerator{},
&step.ApplyComponentWorkflowStepGenerator{},
).Generate(af.app, af.WorkflowSteps)
return err
}
func (p *Parser) parseWorkflowStepsFromRevision(ctx context.Context, af *Appfile) error {
return p.loadWorkflowToAppfile(ctx, af)
}
func (p *Parser) parseWorkflowSteps(ctx context.Context, af *Appfile) error {
if err := p.loadWorkflowToAppfile(ctx, af); err != nil {
return err
}
for _, workflowStep := range af.WorkflowSteps {
Feat: support step group with substep in the workflow (#3772) Signed-off-by: zhengq2006 <zhengq200618@cmbchina.com> workflow substep develop Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com>
2022-05-23 10:26:21 +08:00
err := p.parseWorkflowStep(ctx, af, workflowStep.Type)
if err != nil {
return err
}
Feat: support step group with substep in the workflow (#3772) Signed-off-by: zhengq2006 <zhengq200618@cmbchina.com> workflow substep develop Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com>
2022-05-23 10:26:21 +08:00
if workflowStep.SubSteps != nil {
for _, workflowSubStep := range workflowStep.SubSteps {
err := p.parseWorkflowStep(ctx, af, workflowSubStep.Type)
if err != nil {
return err
}
}
}
}
return nil
}
Feat: support step group with substep in the workflow (#3772) Signed-off-by: zhengq2006 <zhengq200618@cmbchina.com> workflow substep develop Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com>
2022-05-23 10:26:21 +08:00
func (p *Parser) parseWorkflowStep(ctx context.Context, af *Appfile, workflowStepType string) error {
if step.IsBuiltinWorkflowStepType(workflowStepType) {
Feat: support step group with substep in the workflow (#3772) Signed-off-by: zhengq2006 <zhengq200618@cmbchina.com> workflow substep develop Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com> Feat: support step group with substep in the workflow Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com>
2022-05-23 10:26:21 +08:00
return nil
}
if _, found := af.RelatedWorkflowStepDefinitions[workflowStepType]; found {
return nil
}
def := &v1beta1.WorkflowStepDefinition{}
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStepType); err != nil {
return errors.Wrapf(err, "failed to get workflow step definition %s", workflowStepType)
}
af.RelatedWorkflowStepDefinitions[workflowStepType] = def
return nil
}
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.client, typ, capType)
if err != nil {
return nil, errors.WithMessagef(err, "fetch component/policy type of %s", name)
}
return p.convertTemplate2Workload(name, typ, props, templ)
}
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.client.RESTMapper())
if err != nil {
return nil, errors.WithMessagef(err, "fetch component/policy type of %s from revision", name)
}
return p.convertTemplate2Workload(name, typ, props, templ)
}
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)
}
wlType, err := util.ConvertDefinitionRevName(typ)
if err != nil {
wlType = typ
}
return &Workload{
Traits: []*Trait{},
Name: name,
Type: wlType,
CapabilityCategory: templ.CapabilityCategory,
FullTemplate: templ,
Params: settings,
engine: definition.NewWorkloadAbstractEngine(name, p.pd),
}, nil
}
// parseWorkload resolve an ApplicationComponent and generate a Workload
// containing ALL information required by an Appfile.
func (p *Parser) parseWorkload(ctx context.Context, comp common.ApplicationComponent) (*Workload, error) {
workload, err := p.makeWorkload(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
if err != nil {
return nil, err
}
if err = p.parseTraits(ctx, workload, comp); err != nil {
return nil, err
}
return workload, nil
}
func (p *Parser) parseTraits(ctx context.Context, workload *Workload, comp common.ApplicationComponent) error {
for _, traitValue := range comp.Traits {
properties, err := util.RawExtension2Map(traitValue.Properties)
if err != nil {
return errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
}
trait, err := p.parseTrait(ctx, traitValue.Type, properties)
if err != nil {
return errors.WithMessagef(err, "component(%s) parse trait(%s)", comp.Name, traitValue.Type)
}
workload.Traits = append(workload.Traits, trait)
}
return nil
}
// ParseWorkloadFromRevision resolve an ApplicationComponent and generate a Workload
// containing ALL information required by an Appfile from app revision.
func (p *Parser) ParseWorkloadFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
workload, err := p.makeWorkloadFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
if err != nil {
return nil, err
}
if err = p.parseTraitsFromRevision(comp, appRev, workload); err != nil {
return nil, err
}
return workload, nil
}
func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision, workload *Workload) error {
for _, traitValue := range comp.Traits {
properties, err := util.RawExtension2Map(traitValue.Properties)
if err != nil {
return errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
}
trait, err := p.parseTraitFromRevision(traitValue.Type, properties, appRev)
if err != nil {
return errors.WithMessagef(err, "component(%s) parse trait(%s)", comp.Name, traitValue.Type)
}
workload.Traits = append(workload.Traits, trait)
}
return nil
}
// ParseWorkloadFromRevisionAndClient resolve an ApplicationComponent and generate a Workload
// containing ALL information required by an Appfile from app revision, and will fall back to
// load external definitions if not found
func (p *Parser) ParseWorkloadFromRevisionAndClient(ctx context.Context, comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
workload, err := p.makeWorkloadFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
if IsNotFoundInAppRevision(err) {
workload, err = p.makeWorkload(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
}
if err != nil {
return nil, err
}
for _, traitValue := range comp.Traits {
properties, err := util.RawExtension2Map(traitValue.Properties)
if err != nil {
return nil, errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
}
trait, err := p.parseTraitFromRevision(traitValue.Type, properties, appRev)
if IsNotFoundInAppRevision(err) {
trait, err = p.parseTrait(ctx, traitValue.Type, properties)
}
if err != nil {
return nil, errors.WithMessagef(err, "component(%s) parse trait(%s)", comp.Name, traitValue.Type)
}
workload.Traits = append(workload.Traits, trait)
}
return workload, nil
}
func (p *Parser) parseTrait(ctx context.Context, name string, properties map[string]interface{}) (*Trait, error) {
templ, err := p.tmplLoader.LoadTemplate(ctx, p.client, name, types.TypeTrait)
if kerrors.IsNotFound(err) {
return nil, errors.Errorf("trait definition of %s not found", name)
}
if err != nil {
return nil, err
}
return p.convertTemplate2Trait(name, properties, templ)
}
func (p *Parser) parseTraitFromRevision(name string, properties map[string]interface{}, appRev *v1beta1.ApplicationRevision) (*Trait, error) {
templ, err := LoadTemplateFromRevision(name, types.TypeTrait, appRev, p.client.RESTMapper())
if err != nil {
return nil, err
}
return p.convertTemplate2Trait(name, properties, templ)
}
func (p *Parser) convertTemplate2Trait(name string, properties map[string]interface{}, templ *Template) (*Trait, error) {
traitName, err := util.ConvertDefinitionRevName(name)
if err != nil {
traitName = name
}
return &Trait{
Name: traitName,
CapabilityCategory: templ.CapabilityCategory,
Params: properties,
Template: templ.TemplateStr,
HealthCheckPolicy: templ.Health,
CustomStatusFormat: templ.CustomStatus,
FullTemplate: templ,
engine: definition.NewTraitAbstractEngine(traitName, p.pd),
}, nil
}
// ValidateComponentNames validate all component names whether repeat in cluster and template
func (p *Parser) ValidateComponentNames(app *v1beta1.Application) (int, error) {
compNames := map[string]struct{}{}
for idx, comp := range app.Spec.Components {
if _, found := compNames[comp.Name]; found {
return idx, fmt.Errorf("duplicated component name %s", comp.Name)
}
compNames[comp.Name] = struct{}{}
}
return 0, nil
}