Feat: supports multiple difference compare modes (#4334)

* Feat: supports multiple difference alignment modes

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: change field name

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
barnettZQG
2022-07-08 09:38:18 +08:00
committed by GitHub
parent 201f68c6cd
commit b7bf9df55f
6 changed files with 299 additions and 118 deletions
@@ -22,6 +22,7 @@ import (
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
)
@@ -95,3 +96,26 @@ func DeleteApplicationEnvPolicies(ctx context.Context, store datastore.DataStore
}
return nil
}
// GetApplicationRevision get the application revision
// If the version is empty, will query the latest revision of the application
func GetApplicationRevision(ctx context.Context, store datastore.DataStore, appName, version string) (*model.ApplicationRevision, error) {
ar := &model.ApplicationRevision{AppPrimaryKey: appName}
if version != "" {
ar.Version = version
}
revisions, err := store.List(ctx, ar, &datastore.ListOptions{
Page: 1,
PageSize: 1,
SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}},
})
if err != nil || len(revisions) == 0 {
return nil, bcode.ErrApplicationRevisionNotExist
}
latestRevisionRaw := revisions[0]
latestRevision, ok := latestRevisionRaw.(*model.ApplicationRevision)
if !ok {
return nil, errors.New("convert application revision error")
}
return latestRevision, nil
}
+143 -93
View File
@@ -93,7 +93,7 @@ type ApplicationService interface {
DetailRevision(ctx context.Context, appName, revisionName string) (*apisv1.DetailRevisionResponse, error)
Statistics(ctx context.Context, app *model.Application) (*apisv1.ApplicationStatisticsResponse, error)
ListRecords(ctx context.Context, appName string) (*apisv1.ListWorkflowRecordsResponse, error)
CompareAppWithLatestRevision(ctx context.Context, app *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error)
CompareApp(ctx context.Context, app *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error)
ResetAppToLatestRevision(ctx context.Context, appName string) (*apisv1.AppResetResponse, error)
DryRunAppOrRevision(ctx context.Context, app *model.Application, dryRunReq apisv1.AppDryRunReq) (*apisv1.AppDryRunResponse, error)
CreateApplicationTrigger(ctx context.Context, app *model.Application, req apisv1.CreateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error)
@@ -295,6 +295,23 @@ func (c *applicationServiceImpl) GetApplicationStatus(ctx context.Context, appmo
return &app.Status, nil
}
// GetApplicationStatus get application CR from controller cluster
func (c *applicationServiceImpl) GetApplicationCRInEnv(ctx context.Context, appmodel *model.Application, envName string) (*v1beta1.Application, error) {
var app v1beta1.Application
env, err := c.EnvService.GetEnv(ctx, envName)
if err != nil {
return nil, err
}
err = c.KubeClient.Get(ctx, types.NamespacedName{Namespace: env.Namespace, Name: appmodel.GetAppNameForSynced()}, &app)
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, err
}
return &app, nil
}
// GetApplicationCR get application CR in cluster
func (c *applicationServiceImpl) GetApplicationCR(ctx context.Context, appModel *model.Application) (*v1beta1.ApplicationList, error) {
var apps v1beta1.ApplicationList
@@ -629,7 +646,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
// TODO: rollback to handle all the error case
// step1: Render oam application
version := utils.GenerateVersion("")
oamApp, err := c.renderOAMApplication(ctx, app, req.WorkflowName, version)
oamApp, err := c.renderOAMApplication(ctx, app, req.WorkflowName, "", version)
if err != nil {
return nil, err
}
@@ -770,7 +787,7 @@ func (c *applicationServiceImpl) syncConfigs4Application(ctx context.Context, ap
return nil
}
func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appModel *model.Application, reqWorkflowName, version string) (*v1beta1.Application, error) {
func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appModel *model.Application, reqWorkflowName, envName, version string) (*v1beta1.Application, error) {
// Priority 1 uses the requested workflow as release .
// Priority 2 uses the default workflow as release .
var workflow *model.Workflow
@@ -786,14 +803,15 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
return nil, err
}
}
if workflow == nil || workflow.EnvName == "" {
return nil, bcode.ErrWorkflowNotExist
if workflow != nil {
envName = workflow.EnvName
}
envbinding, err := c.EnvBindingService.GetEnvBinding(ctx, appModel, workflow.EnvName)
envbinding, err := c.EnvBindingService.GetEnvBinding(ctx, appModel, envName)
if err != nil {
return nil, err
}
env, err := c.EnvService.GetEnv(ctx, workflow.EnvName)
env, err := c.EnvService.GetEnv(ctx, envName)
if err != nil {
return nil, err
}
@@ -896,25 +914,25 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
}
app.Spec.Policies = append(app.Spec.Policies, appPolicy)
}
app.Annotations[oam.AnnotationWorkflowName] = workflow.Name
var steps []v1beta1.WorkflowStep
for _, step := range workflow.Steps {
var workflowStep = v1beta1.WorkflowStep{
Name: step.Name,
Type: step.Type,
Inputs: step.Inputs,
Outputs: step.Outputs,
if workflow != nil {
app.Annotations[oam.AnnotationWorkflowName] = workflow.Name
var steps []v1beta1.WorkflowStep
for _, step := range workflow.Steps {
var workflowStep = v1beta1.WorkflowStep{
Name: step.Name,
Type: step.Type,
Inputs: step.Inputs,
Outputs: step.Outputs,
}
if step.Properties != nil {
workflowStep.Properties = step.Properties.RawExtension()
}
steps = append(steps, workflowStep)
}
if step.Properties != nil {
workflowStep.Properties = step.Properties.RawExtension()
app.Spec.Workflow = &v1beta1.Workflow{
Steps: steps,
}
steps = append(steps, workflowStep)
}
app.Spec.Workflow = &v1beta1.Workflow{
Steps: steps,
}
return app, nil
}
@@ -1378,50 +1396,101 @@ func (c *applicationServiceImpl) Statistics(ctx context.Context, app *model.Appl
}, nil
}
// CompareAppWithLatestRevision compare application with last revision
func (c *applicationServiceImpl) CompareAppWithLatestRevision(ctx context.Context, appModel *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error) {
var reqWorkflowName string
if compareReq.Env != "" {
reqWorkflowName = repository.ConvertWorkflowName(compareReq.Env)
}
newApp, err := c.renderOAMApplication(ctx, appModel, reqWorkflowName, "")
if err != nil {
return nil, err
}
ignoreSomeParams(newApp)
newAppBytes, err := yaml.Marshal(newApp)
if err != nil {
return nil, err
// CompareApp compare application
func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error) {
var base, compareTarget *v1beta1.Application
var err error
var envNameByRevision string
switch {
case compareReq.CompareLatestWithRunning != nil:
base, err = c.renderOAMApplication(ctx, appModel, "", compareReq.CompareLatestWithRunning.Env, "")
if err != nil {
log.Logger.Errorf("failed to build the latest application %s", err.Error())
break
}
case compareReq.CompareRevisionWithRunning != nil || compareReq.CompareRevisionWithLatest != nil:
var revision = ""
if compareReq.CompareRevisionWithRunning != nil {
revision = compareReq.CompareRevisionWithRunning.Revision
}
if compareReq.CompareRevisionWithLatest != nil {
revision = compareReq.CompareRevisionWithLatest.Revision
}
base, envNameByRevision, err = c.getAppModelFromRevision(ctx, appModel.Name, revision)
if err != nil {
log.Logger.Errorf("failed to get the app model from the revision %s", err.Error())
break
}
}
oldApp, err := c.getAppFromLatestRevision(ctx, appModel.Name, compareReq.Env, "")
if err != nil {
if errors.Is(err, bcode.ErrApplicationRevisionNotExist) {
return &apisv1.AppCompareResponse{IsDiff: false, NewAppYAML: string(newAppBytes)}, nil
switch {
case compareReq.CompareLatestWithRunning != nil || compareReq.CompareRevisionWithRunning != nil:
var envName string
if compareReq.CompareLatestWithRunning != nil {
envName = compareReq.CompareLatestWithRunning.Env
}
if compareReq.CompareRevisionWithRunning != nil {
envName = envNameByRevision
}
if envName == "" {
break
}
compareTarget, err = c.GetApplicationCRInEnv(ctx, appModel, envName)
if err != nil {
log.Logger.Errorf("failed to query the application CR %s", err.Error())
break
}
case compareReq.CompareRevisionWithLatest != nil:
compareTarget, err = c.renderOAMApplication(ctx, appModel, "", envNameByRevision, "")
if err != nil {
log.Logger.Errorf("failed to build the latest application %s", err.Error())
break
}
return nil, err
}
ignoreSomeParams(oldApp)
oldAppBytes, err := yaml.Marshal(oldApp)
if err != nil {
return nil, err
var baseAppBytes, targetAppBytes []byte
if base != nil {
ignoreSomeParams(base)
baseAppBytes, err = yaml.Marshal(base)
if err != nil {
return nil, err
}
}
if compareTarget != nil {
ignoreSomeParams(compareTarget)
targetAppBytes, err = yaml.Marshal(compareTarget)
if err != nil {
return nil, err
}
}
compareResponse := &apisv1.AppCompareResponse{IsDiff: true, BaseAppYAML: string(baseAppBytes), TargetAppYAML: string(targetAppBytes)}
if base == nil || compareTarget == nil {
return compareResponse, nil
}
args := common2.Args{
Schema: common2.Scheme,
}
_ = args.SetConfig(c.KubeConfig)
args.SetClient(c.KubeClient)
diffResult, buff, err := compare(ctx, args, newApp, oldApp)
diffResult, buff, err := compare(ctx, args, compareTarget, base)
if err != nil {
log.Logger.Errorf("fail to compare the app %s", err.Error())
return &apisv1.AppCompareResponse{IsDiff: false, NewAppYAML: string(newAppBytes), OldAppYAML: string(oldAppBytes)}, err
compareResponse.IsDiff = false
return compareResponse, nil
}
return &apisv1.AppCompareResponse{IsDiff: diffResult.DiffType != "", DiffReport: buff.String(), NewAppYAML: string(newAppBytes), OldAppYAML: string(oldAppBytes)}, nil
compareResponse.IsDiff = diffResult.DiffType != ""
compareResponse.DiffReport = buff.String()
return compareResponse, nil
}
// ResetAppToLatestRevision reset app's component to last revision
func (c *applicationServiceImpl) ResetAppToLatestRevision(ctx context.Context, appName string) (*apisv1.AppResetResponse, error) {
targetApp, err := c.getAppFromLatestRevision(ctx, appName, "", "")
targetApp, _, err := c.getAppModelFromRevision(ctx, appName, "")
if err != nil {
return nil, err
}
@@ -1433,16 +1502,12 @@ func (c *applicationServiceImpl) DryRunAppOrRevision(ctx context.Context, appMod
var app *v1beta1.Application
var err error
if dryRunReq.DryRunType == "APP" {
var reqWorkflowName string
if dryRunReq.Env != "" {
reqWorkflowName = repository.ConvertWorkflowName(dryRunReq.Env)
}
app, err = c.renderOAMApplication(ctx, appModel, reqWorkflowName, "")
app, err = c.renderOAMApplication(ctx, appModel, dryRunReq.Workflow, dryRunReq.Env, "")
if err != nil {
return nil, err
}
} else {
app, err = c.getAppFromLatestRevision(ctx, dryRunReq.AppName, dryRunReq.Env, dryRunReq.Version)
app, _, err = c.getAppModelFromRevision(ctx, dryRunReq.AppName, dryRunReq.Version)
if err != nil {
return nil, err
}
@@ -1470,33 +1535,16 @@ func genWebhookToken() string {
return string(b)
}
func (c *applicationServiceImpl) getAppFromLatestRevision(ctx context.Context, appName string, envName string, version string) (*v1beta1.Application, error) {
ar := &model.ApplicationRevision{AppPrimaryKey: appName}
if envName != "" {
ar.EnvName = envName
}
if version != "" {
ar.Version = version
}
revisions, err := c.Store.List(ctx, ar, &datastore.ListOptions{
Page: 1,
PageSize: 1,
SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}},
})
if err != nil || len(revisions) == 0 {
return nil, bcode.ErrApplicationRevisionNotExist
}
latestRevisionRaw := revisions[0]
latestRevision, ok := latestRevisionRaw.(*model.ApplicationRevision)
if !ok {
return nil, errors.New("convert application revision error")
func (c *applicationServiceImpl) getAppModelFromRevision(ctx context.Context, appName string, version string) (*v1beta1.Application, string, error) {
latestRevision, err := repository.GetApplicationRevision(ctx, c.Store, appName, version)
if err != nil {
return nil, "", err
}
oldApp := &v1beta1.Application{}
if err := yaml.Unmarshal([]byte(latestRevision.ApplyAppConfig), oldApp); err != nil {
return nil, err
return nil, "", err
}
return oldApp, nil
return oldApp, latestRevision.EnvName, nil
}
func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta1.Application) (*apisv1.AppResetResponse, error) {
@@ -1605,21 +1653,23 @@ func dryRunApplication(ctx context.Context, c common2.Args, app *v1beta1.Applica
// ignoreSomeParams ignore some parameters before comparing the app changes.
// ignore the workflow spec
func ignoreSomeParams(o *v1beta1.Application) {
// set default
o.ResourceVersion = ""
o.Spec.Workflow = nil
newAnnotations := map[string]string{}
annotations := o.GetAnnotations()
for k, v := range annotations {
if k == oam.AnnotationDeployVersion || k == oam.AnnotationPublishVersion || k == "kubectl.kubernetes.io/last-applied-configuration" {
continue
}
newAnnotations[k] = v
}
o.SetAnnotations(newAnnotations)
var defaultApplication = v1beta1.Application{}
// only compare the spec without the workflow
defaultApplication.Spec = o.Spec
defaultApplication.Spec.Workflow = nil
defaultApplication.Name = o.Name
defaultApplication.Namespace = o.Namespace
sort.Slice(defaultApplication.Spec.Policies, func(i, j int) bool {
return defaultApplication.Spec.Policies[i].Name < defaultApplication.Spec.Policies[j].Name
})
sort.Slice(defaultApplication.Spec.Components, func(i, j int) bool {
return defaultApplication.Spec.Components[i].Name < defaultApplication.Spec.Components[j].Name
})
*o = defaultApplication
}
func compare(ctx context.Context, c common2.Args, newApp *v1beta1.Application, oldApp *v1beta1.Application) (*dryrun.DiffEntry, bytes.Buffer, error) {
func compare(ctx context.Context, c common2.Args, targetApp *v1beta1.Application, baseApp *v1beta1.Application) (*dryrun.DiffEntry, bytes.Buffer, error) {
var buff = bytes.Buffer{}
_, err := c.GetClient()
if err != nil {
@@ -1643,7 +1693,7 @@ func compare(ctx context.Context, c common2.Args, newApp *v1beta1.Application, o
return nil, buff, err
}
liveDiffOption := dryrun.NewLiveDiffOption(client, config, dm, pd, objs)
diffResult, err := liveDiffOption.DiffApps(ctx, newApp, oldApp)
diffResult, err := liveDiffOption.DiffApps(ctx, baseApp, targetApp)
if err != nil {
return nil, buff, err
}
@@ -478,8 +478,12 @@ var _ = Describe("Test application service function", func() {
Expect(resp.Total).Should(Equal(int64(3)))
})
It("Test CompareAppWithLatestRevision function", func() {
It("Test CompareApp function", func() {
check := func(compareResponse *v1.AppCompareResponse, isDiff bool) {
Expect(cmp.Diff(compareResponse.BaseAppYAML, "")).ShouldNot(BeEmpty())
Expect(cmp.Diff(compareResponse.TargetAppYAML, "")).ShouldNot(BeEmpty())
Expect(cmp.Diff(compareResponse.IsDiff, isDiff)).Should(BeEmpty())
}
appModel, err := appService.GetApplication(context.TODO(), testApp)
Expect(err).Should(BeNil())
_, err = appService.Deploy(context.TODO(), appModel, v1.ApplicationDeployRequest{WorkflowName: repository.ConvertWorkflowName("app-dev")})
@@ -488,23 +492,40 @@ var _ = Describe("Test application service function", func() {
Expect(err).Should(BeNil())
By("compare when app not change, should return false")
compareResponse, err := appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
compareResponse, err := appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithRunning: &v1.CompareRevisionWithRunningOption{},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, false)).Should(BeEmpty())
check(compareResponse, false)
By("compare when app not change and env not empty, should return false")
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{Env: "app-dev"})
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithLatest: &v1.CompareRevisionWithLatestOption{},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, false)).Should(BeEmpty())
check(compareResponse, false)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
check(compareResponse, false)
By("compare when app add env, not change, should return false")
_, err = envService.CreateEnv(context.TODO(), v1.CreateEnvRequest{Name: "app-prod", Namespace: "envnsprod", Targets: []string{defaultTarget}, Project: "app-prod"})
Expect(err).Should(BeNil())
_, err = envBindingService.CreateEnvBinding(context.TODO(), appModel, v1.CreateApplicationEnvbindingRequest{EnvBinding: v1.EnvBinding{Name: "app-prod"}})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-prod",
},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, false)).Should(BeEmpty())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
Expect(cmp.Diff(compareResponse.TargetAppYAML, "")).Should(BeEmpty())
Expect(cmp.Diff(compareResponse.BaseAppYAML, "")).ShouldNot(BeEmpty())
By("compare when app's env add target, should return true")
_, err = targetService.CreateTarget(context.TODO(), v1.CreateTargetRequest{Name: "dev-target1", Project: appModel.Project, Cluster: &v1.ClusterTarget{ClusterName: "local", Namespace: "dev-target1"}})
@@ -515,9 +536,13 @@ var _ = Describe("Test application service function", func() {
Targets: []string{defaultTarget, "dev-target1"},
})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
check(compareResponse, true)
By("compare when update app's trait, should return true")
// reset app config
@@ -529,11 +554,21 @@ var _ = Describe("Test application service function", func() {
Description: "description",
})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithLatest: &v1.CompareRevisionWithLatestOption{},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
By("compare when update component's target after app deployed ,should return ture")
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
By("compare when update component's target after app deployed ,should return true")
// reset app config
_, err = appService.ResetAppToLatestRevision(context.TODO(), testApp)
Expect(err).Should(BeNil())
@@ -545,9 +580,49 @@ var _ = Describe("Test application service function", func() {
Properties: &newProperties,
})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithLatest: &v1.CompareRevisionWithLatestOption{},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
check(compareResponse, true)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
check(compareResponse, true)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithRunning: &v1.CompareRevisionWithRunningOption{},
})
Expect(err).Should(BeNil())
check(compareResponse, false)
By("compare when changed the application CR, should return true")
appCR, err := appService.GetApplicationCRInEnv(context.TODO(), appModel, "app-dev")
Expect(err).Should(BeNil())
appCR.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte("{\"exposeType\":\"NodePort\",\"image\":\"nginx:222\",\"imagePullPolicy\":\"Always\"}")}
err = k8sClient.Update(context.TODO(), appCR)
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithRunning: &v1.CompareRevisionWithRunningOption{},
})
Expect(err).Should(BeNil())
check(compareResponse, true)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
check(compareResponse, true)
err = envBindingService.ApplicationEnvRecycle(context.TODO(), &model.Application{Name: testApp}, &model.EnvBinding{Name: "app-dev"})
Expect(err).Should(BeNil())
})
+13 -1
View File
@@ -23,6 +23,9 @@ import (
"strings"
"time"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/event/sync/convert"
@@ -98,8 +101,17 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
targetNames = append(targetNames, name)
}
}
var namespace corev1.Namespace
envName := model.AutoGenEnvNamePrefix + targetApp.Namespace
// Get the env name from the label of namespace
// If the namespace created by `vela env init`
if c.cli.Get(ctx, types.NamespacedName{Name: targetApp.Namespace}, &namespace) == nil {
if env, ok := namespace.Labels[oam.LabelNamespaceOfEnvName]; ok {
envName = env
}
}
dsApp.Env = &model.Env{
Name: model.AutoGenEnvNamePrefix + targetApp.Namespace,
Name: envName,
Namespace: targetApp.Namespace,
Description: model.AutoGenDesc,
Project: newProject,
+4 -4
View File
@@ -549,8 +549,8 @@ func (c *applicationAPIInterface) GetWebServiceRoute() *restful.WebService {
Returns(400, "Bad Request", bcode.Bcode{}).
Writes(apis.ListWorkflowRecordsResponse{}))
ws.Route(ws.POST("/{appName}/compare").To(c.compareAppWithLatestRevision).
Doc("compare application with env latest revision").
ws.Route(ws.POST("/{appName}/compare").To(c.compareApp).
Doc("compare application").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(c.RbacService.CheckPerm("application", "compare")).
Filter(c.appCheckFilter).
@@ -1184,7 +1184,7 @@ func (c *applicationAPIInterface) listApplicationRecords(req *restful.Request, r
}
}
func (c *applicationAPIInterface) compareAppWithLatestRevision(req *restful.Request, res *restful.Response) {
func (c *applicationAPIInterface) compareApp(req *restful.Request, res *restful.Response) {
app := req.Request.Context().Value(&apis.CtxKeyApplication).(*model.Application)
// Verify the validity of parameters
var compareReq apis.AppCompareReq
@@ -1197,7 +1197,7 @@ func (c *applicationAPIInterface) compareAppWithLatestRevision(req *restful.Requ
return
}
base, err := c.ApplicationService.CompareAppWithLatestRevision(req.Request.Context(), app, compareReq)
base, err := c.ApplicationService.CompareApp(req.Request.Context(), app, compareReq)
if err != nil {
bcode.ReturnError(req, res, err)
return
+25 -5
View File
@@ -362,10 +362,10 @@ type ApplicationBase struct {
// AppCompareResponse application compare result
type AppCompareResponse struct {
IsDiff bool `json:"isDiff"`
DiffReport string `json:"diffReport"`
NewAppYAML string `json:"newAppYAML"`
OldAppYAML string `json:"oldAppYAML"`
IsDiff bool `json:"isDiff"`
DiffReport string `json:"diffReport"`
BaseAppYAML string `json:"baseAppYAML"`
TargetAppYAML string `json:"targetAppYAML"`
}
// AppResetResponse application reset result
@@ -375,7 +375,26 @@ type AppResetResponse struct {
// AppCompareReq application compare req
type AppCompareReq struct {
Env string `json:"env"`
CompareRevisionWithRunning *CompareRevisionWithRunningOption `json:"compareRevisionWithRunning,omitempty"`
CompareRevisionWithLatest *CompareRevisionWithLatestOption `json:"compareRevisionWithLatest,omitempty"`
CompareLatestWithRunning *CompareLatestWithRunningOption `json:"compareLatestWithRunning,omitempty"`
}
// CompareRevisionWithRunningOption means compare the specified version with the application in cluster.
type CompareRevisionWithRunningOption struct {
// Revision, If not specified, means use the latest revision.
Revision string `json:"revision" optional:"true"`
}
// CompareRevisionWithLatestOption means compare the the specified version with the latest application configuration
type CompareRevisionWithLatestOption struct {
// Revision, If not specified, means use the latest revision.
Revision string `json:"revision" optional:"true"`
}
// CompareLatestWithRunningOption means compare the latest configuration with the app in cluster.
type CompareLatestWithRunningOption struct {
Env string `json:"env" validate:"required"`
}
// AppDryRunReq application dry-run req
@@ -383,6 +402,7 @@ type AppDryRunReq struct {
AppName string `json:"appName"`
DryRunType string `json:"dryRunType"`
Env string `json:"env"`
Workflow string `json:"workflow"`
Version string `json:"version"`
}