Feat: optimize the dry run feature (#4364)

* Feat: optimize the dry run feature

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

* Fix: e2e test case

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

* Fix: change the bcode

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

* Fix: change some names

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
barnettZQG
2022-07-18 14:01:11 +08:00
committed by GitHub
parent ace23f1c6f
commit a519a6c89d
16 changed files with 338 additions and 126 deletions

View File

@@ -690,8 +690,8 @@
"tags": [
"application"
],
"summary": "compare application with env latest revision",
"operationId": "compareAppWithLatestRevision",
"summary": "compare application",
"operationId": "compareApp",
"parameters": [
{
"name": "body",
@@ -2796,6 +2796,40 @@
}
}
},
"/api/v1/cloudshell": {
"post": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"cloudshell"
],
"summary": "prepare the user's cloud shell environment",
"operationId": "prepareCloudShell",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.SimpleResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/bcode.Bcode"
}
},
"500": {
"description": "Bummer, something went wrong"
}
}
}
},
"/api/v1/clusters": {
"get": {
"consumes": [
@@ -5957,6 +5991,74 @@
}
}
}
},
"/view/cloudshell": {
"get": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"cloudshell"
],
"summary": "prepare the user's cloud shell environment",
"operationId": "proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.SimpleResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/bcode.Bcode"
}
},
"500": {
"description": "Bummer, something went wrong"
}
}
}
},
"/view/cloudshell/{subpath}": {
"get": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"cloudshell"
],
"summary": "prepare the user's cloud shell environment",
"operationId": "proxy",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.SimpleResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/bcode.Bcode"
}
},
"500": {
"description": "Bummer, something went wrong"
}
}
}
}
},
"definitions": {
@@ -7794,12 +7896,15 @@
"type": "object"
},
"v1.AppCompareReq": {
"required": [
"env"
],
"properties": {
"env": {
"type": "string"
"compareLatestWithRunning": {
"$ref": "#/definitions/v1.CompareLatestWithRunningOption"
},
"compareRevisionWithLatest": {
"$ref": "#/definitions/v1.CompareRevisionWithLatestOption"
},
"compareRevisionWithRunning": {
"$ref": "#/definitions/v1.CompareRevisionWithRunningOption"
}
}
},
@@ -7807,35 +7912,32 @@
"required": [
"isDiff",
"diffReport",
"newAppYAML",
"oldAppYAML"
"baseAppYAML",
"targetAppYAML"
],
"properties": {
"baseAppYAML": {
"type": "string"
},
"diffReport": {
"type": "string"
},
"isDiff": {
"type": "boolean"
},
"newAppYAML": {
"type": "string"
},
"oldAppYAML": {
"targetAppYAML": {
"type": "string"
}
}
},
"v1.AppDryRunReq": {
"required": [
"appName",
"dryRunType",
"env",
"workflow",
"version"
],
"properties": {
"appName": {
"type": "string"
},
"dryRunType": {
"type": "string"
},
@@ -7844,14 +7946,24 @@
},
"version": {
"type": "string"
},
"workflow": {
"type": "string"
}
}
},
"v1.AppDryRunResponse": {
"required": [
"yaml"
"yaml",
"success"
],
"properties": {
"message": {
"type": "string"
},
"success": {
"type": "boolean"
},
"yaml": {
"type": "string"
}
@@ -7943,11 +8055,11 @@
"v1.ApplicationDeployResponse": {
"required": [
"version",
"note",
"triggerType",
"createTime",
"status",
"envName"
"envName",
"createTime",
"note",
"triggerType"
],
"properties": {
"codeInfo": {
@@ -8263,6 +8375,20 @@
}
}
},
"v1.CloudShellPrepareResponse": {
"required": [
"status",
"message"
],
"properties": {
"message": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"v1.ClusterBase": {
"required": [
"name",
@@ -8381,6 +8507,30 @@
}
}
},
"v1.CompareLatestWithRunningOption": {
"required": [
"env"
],
"properties": {
"env": {
"type": "string"
}
}
},
"v1.CompareRevisionWithLatestOption": {
"properties": {
"revision": {
"type": "string"
}
}
},
"v1.CompareRevisionWithRunningOption": {
"properties": {
"revision": {
"type": "string"
}
}
},
"v1.ComponentBase": {
"required": [
"name",
@@ -9044,6 +9194,9 @@
"alias": {
"type": "string"
},
"allowTargetConflict": {
"type": "boolean"
},
"description": {
"type": "string"
},
@@ -9249,7 +9402,8 @@
"description",
"icon",
"status",
"labels"
"labels",
"ownerAddon"
],
"properties": {
"alias": {
@@ -9273,6 +9427,9 @@
"name": {
"type": "string"
},
"ownerAddon": {
"type": "string"
},
"policy": {
"$ref": "#/definitions/v1beta1.PolicyDefinitionSpec"
},
@@ -9329,11 +9486,11 @@
},
"v1.DetailAddonResponse": {
"required": [
"description",
"invisible",
"version",
"icon",
"name",
"version",
"invisible",
"description",
"schema",
"uiSchema",
"definitions",
@@ -9413,13 +9570,13 @@
},
"v1.DetailApplicationResponse": {
"required": [
"icon",
"name",
"alias",
"project",
"description",
"icon",
"project",
"createTime",
"updateTime",
"name",
"policies",
"envBindings",
"resourceInfo"
@@ -9476,20 +9633,20 @@
},
"v1.DetailClusterResponse": {
"required": [
"createTime",
"updateTime",
"reason",
"dashboardURL",
"labels",
"apiServerURL",
"kubeConfig",
"kubeConfigSecret",
"name",
"status",
"dashboardURL",
"createTime",
"kubeConfig",
"labels",
"provider",
"apiServerURL",
"description",
"alias",
"icon",
"status",
"description",
"provider",
"reason",
"kubeConfigSecret",
"updateTime",
"resourceInfo"
],
"properties": {
@@ -9547,14 +9704,14 @@
},
"v1.DetailComponentResponse": {
"required": [
"type",
"createTime",
"name",
"updateTime",
"alias",
"creator",
"main",
"appPrimaryKey",
"creator",
"alias",
"name",
"main",
"createTime",
"updateTime",
"type",
"definition"
],
"properties": {
@@ -9642,12 +9799,13 @@
},
"v1.DetailDefinitionResponse": {
"required": [
"ownerAddon",
"name",
"status",
"labels",
"alias",
"description",
"status",
"alias",
"icon",
"labels",
"schema",
"uiSchema"
],
@@ -9673,6 +9831,9 @@
"name": {
"type": "string"
},
"ownerAddon": {
"type": "string"
},
"policy": {
"$ref": "#/definitions/v1beta1.PolicyDefinitionSpec"
},
@@ -9701,14 +9862,14 @@
},
"v1.DetailPolicyResponse": {
"required": [
"updateTime",
"envName",
"name",
"type",
"description",
"creator",
"properties",
"createTime"
"createTime",
"updateTime",
"envName",
"name"
],
"properties": {
"createTime": {
@@ -9741,17 +9902,17 @@
},
"v1.DetailRevisionResponse": {
"required": [
"version",
"envName",
"createTime",
"appPrimaryKey",
"reason",
"deployUser",
"workflowName",
"updateTime",
"triggerType",
"envName",
"status",
"note"
"deployUser",
"triggerType",
"updateTime",
"appPrimaryKey",
"version",
"createTime",
"note",
"reason"
],
"properties": {
"appPrimaryKey": {
@@ -9805,10 +9966,10 @@
},
"v1.DetailTargetResponse": {
"required": [
"project",
"createTime",
"updateTime",
"name"
"name",
"createTime",
"project"
],
"properties": {
"alias": {
@@ -9848,11 +10009,11 @@
},
"v1.DetailUserResponse": {
"required": [
"disabled",
"createTime",
"lastLoginTime",
"name",
"email",
"disabled",
"projects",
"roles"
],
@@ -9893,12 +10054,12 @@
},
"v1.DetailWorkflowRecordResponse": {
"required": [
"namespace",
"workflowName",
"workflowAlias",
"applicationRevision",
"status",
"name",
"namespace",
"workflowName",
"workflowAlias",
"deployTime",
"deployUser",
"note",
@@ -9950,14 +10111,14 @@
},
"v1.DetailWorkflowResponse": {
"required": [
"createTime",
"updateTime",
"name",
"description",
"envName",
"alias",
"enable",
"default"
"envName",
"updateTime",
"name",
"default",
"createTime",
"description"
],
"properties": {
"alias": {
@@ -10662,11 +10823,11 @@
},
"v1.LoginUserInfoResponse": {
"required": [
"email",
"disabled",
"createTime",
"lastLoginTime",
"name",
"email",
"disabled",
"projects",
"platformPermissions",
"projectPermissions"

View File

@@ -679,6 +679,7 @@ spec:
- containerPort: 80
---
## From the trait test-ingress
apiVersion: v1
kind: Service
metadata:
@@ -701,6 +702,7 @@ spec:
app.oam.dev/component: express-server
---
## From the trait test-ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:

View File

@@ -808,11 +808,12 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
envName = workflow.EnvName
}
envbinding, err := c.EnvBindingService.GetEnvBinding(ctx, appModel, envName)
env, err := c.EnvService.GetEnv(ctx, envName)
if err != nil {
return nil, err
}
env, err := c.EnvService.GetEnv(ctx, envName)
envbinding, err := c.EnvBindingService.GetEnvBinding(ctx, appModel, envName)
if err != nil {
return nil, err
}
@@ -1519,27 +1520,35 @@ func (c *applicationServiceImpl) ResetAppToLatestRevision(ctx context.Context, a
func (c *applicationServiceImpl) DryRunAppOrRevision(ctx context.Context, appModel *model.Application, dryRunReq apisv1.AppDryRunReq) (*apisv1.AppDryRunResponse, error) {
var app *v1beta1.Application
var err error
if dryRunReq.DryRunType == "APP" {
switch dryRunReq.DryRunType {
case "APP":
app, err = c.renderOAMApplication(ctx, appModel, dryRunReq.Workflow, dryRunReq.Env, "")
if err != nil {
return nil, err
}
} else {
app, _, err = c.getAppModelFromRevision(ctx, dryRunReq.AppName, dryRunReq.Version)
case "REVISION":
app, _, err = c.getAppModelFromRevision(ctx, appModel.Name, dryRunReq.Version)
if err != nil {
return nil, err
}
default:
return nil, bcode.ErrApplicationDryRunFailed.SetMessage("The dry run type is not supported")
}
args := common2.Args{
Schema: common2.Scheme,
}
_ = args.SetConfig(c.KubeConfig)
args.SetClient(c.KubeClient)
res := &apisv1.AppDryRunResponse{}
dryRunResult, err := dryRunApplication(ctx, args, app)
if err != nil {
return nil, err
res.Success = false
res.Message = err.Error()
} else {
res.Success = true
}
return &apisv1.AppDryRunResponse{YAML: dryRunResult.String()}, nil
res.YAML = dryRunResult.String()
return res, nil
}
func genWebhookToken() string {
@@ -1631,6 +1640,15 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
func dryRunApplication(ctx context.Context, c common2.Args, app *v1beta1.Application) (bytes.Buffer, error) {
var buff = bytes.Buffer{}
if _, err := fmt.Fprintf(&buff, "---\n# Application(%s) \n---\n\n", app.Name); err != nil {
return buff, fmt.Errorf("fail to write to buff %w", err)
}
result, err := yaml.Marshal(app)
if err != nil {
return buff, fmt.Errorf("marshal app: %w", err)
}
buff.Write(result)
newClient, err := c.GetClient()
if err != nil {
return buff, err
@@ -1648,20 +1666,11 @@ func dryRunApplication(ctx context.Context, c common2.Args, app *v1beta1.Applica
if err != nil {
return buff, err
}
dryRunOpt := dryrun.NewDryRunOption(newClient, config, dm, pd, objects)
dryRunOpt := dryrun.NewDryRunOption(newClient, config, dm, pd, objects, true)
comps, policies, err := dryRunOpt.ExecuteDryRun(ctx, app)
if err != nil {
return buff, fmt.Errorf("generate OAM objects %w", err)
return buff, err
}
if _, err = fmt.Fprintf(&buff, "---\n# Application(%s) \n---\n\n", app.Name); err != nil {
return buff, fmt.Errorf("fail to write to buff %w", err)
}
result, err := yaml.Marshal(app)
if err != nil {
return buff, fmt.Errorf("marshal app: %w", err)
}
buff.Write(result)
buff.WriteString("\n---\n")
if err = dryRunOpt.PrintDryRun(&buff, app.Name, comps, policies); err != nil {
return buff, err
}

View File

@@ -652,7 +652,7 @@ var _ = Describe("Test application service function", func() {
It("Test DryRun with env revision function", func() {
appModel, err := appService.GetApplication(context.TODO(), testApp)
Expect(err).Should(BeNil())
resetResponse, err := appService.DryRunAppOrRevision(context.TODO(), appModel, v1.AppDryRunReq{DryRunType: "Revision", Env: "app-dev"})
resetResponse, err := appService.DryRunAppOrRevision(context.TODO(), appModel, v1.AppDryRunReq{DryRunType: "REVISION", Env: "app-dev"})
Expect(err).Should(BeNil())
Expect(strings.Contains(resetResponse.YAML, "# Application(test-app)")).Should(BeTrue())
Expect(strings.Contains(resetResponse.YAML, "# Application(test-app) -- Component(component-name)")).Should(BeTrue())
@@ -661,7 +661,7 @@ var _ = Describe("Test application service function", func() {
It("Test DryRun with last revision function", func() {
appModel, err := appService.GetApplication(context.TODO(), testApp)
Expect(err).Should(BeNil())
resetResponse, err := appService.DryRunAppOrRevision(context.TODO(), appModel, v1.AppDryRunReq{DryRunType: "Revision"})
resetResponse, err := appService.DryRunAppOrRevision(context.TODO(), appModel, v1.AppDryRunReq{DryRunType: "REVISION"})
Expect(err).Should(BeNil())
Expect(strings.Contains(resetResponse.YAML, "# Application(test-app)")).Should(BeTrue())
Expect(strings.Contains(resetResponse.YAML, "# Application(test-app) -- Component(component-name)")).Should(BeTrue())

View File

@@ -280,19 +280,25 @@ func (e *envBindingServiceImpl) ApplicationEnvRecycle(ctx context.Context, appMo
return err
}
var app v1beta1.Application
err = e.KubeClient.Get(ctx, types.NamespacedName{Namespace: env.Namespace, Name: appModel.Name}, &app)
if err != nil {
if apierrors.IsNotFound(err) {
return nil
}
return err
name := envBinding.AppDeployName
if name == "" {
name = appModel.Name
}
if err := e.KubeClient.Delete(ctx, &app); err != nil {
return err
err = e.KubeClient.Get(ctx, types.NamespacedName{Namespace: env.Namespace, Name: name}, &app)
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
}
if err == nil {
if err := e.KubeClient.Delete(ctx, &app); err != nil {
return err
}
}
if err := resetRevisionsAndRecords(ctx, e.Store, appModel.Name, "", "", ""); err != nil {
return err
}
log.Logger.Infof("Application %s(%s) recycle successfully from env %s", appModel.Name, name, env.Name)
return nil
}

View File

@@ -1234,10 +1234,6 @@ func (c *applicationAPIInterface) dryRunAppOrRevision(req *restful.Request, res
bcode.ReturnError(req, res, err)
return
}
if dryRunReq.AppName == "" {
dryRunReq.AppName = app.Name
}
base, err := c.ApplicationService.DryRunAppOrRevision(req.Request.Context(), app, dryRunReq)
if err != nil {
bcode.ReturnError(req, res, err)

View File

@@ -399,8 +399,7 @@ type CompareLatestWithRunningOption struct {
// AppDryRunReq application dry-run req
type AppDryRunReq struct {
AppName string `json:"appName"`
DryRunType string `json:"dryRunType"`
DryRunType string `json:"dryRunType" validate:"oneof=APP REVISION"`
Env string `json:"env"`
Workflow string `json:"workflow"`
Version string `json:"version"`
@@ -408,7 +407,9 @@ type AppDryRunReq struct {
// AppDryRunResponse application dry-run result
type AppDryRunResponse struct {
YAML string `json:"yaml"`
YAML string `json:"yaml"`
Success bool `json:"success"`
Message string `json:"message,omitempty"`
}
// ApplicationStatusResponse application status response body

View File

@@ -94,5 +94,8 @@ var ErrApplicationTriggerNotExist = NewBcode(404, 10024, "application trigger is
// ErrApplicationComponentNotAllowDelete means the component is main in one application, and it must be deleted before delete app.
var ErrApplicationComponentNotAllowDelete = NewBcode(400, 10025, "main component in application can not be deleted")
// ErrApplicationPolicyIsBeingUsed means this policy is been used, cannot deleted.
var ErrApplicationPolicyIsBeingUsed = NewBcode(400, 10026, "the policy is being used by workflow, cannot be deleted")
// ErrApplicationPolicyIsBeingUsed means this policy is been used, cannot deleted.
var ErrApplicationPolicyIsBeingUsed = NewBcode(400, 10026, "the policy is being used by workflow, cannot be deleted")
// ErrApplicationDryRunFailed means the application configuration does not dry run successfully
var ErrApplicationDryRunFailed = NewBcode(400, 10027, "The application dry run failed")

View File

@@ -41,7 +41,7 @@ import (
// NewLiveDiffOption creates a live-diff option
func NewLiveDiffOption(c client.Client, cfg *rest.Config, dm discoverymapper.DiscoveryMapper, pd *packages.PackageDiscover, as []oam.Object) *LiveDiffOption {
parser := appfile.NewApplicationParser(c, dm, pd)
return &LiveDiffOption{DryRun: NewDryRunOption(c, cfg, dm, pd, as), Parser: parser}
return &LiveDiffOption{DryRun: NewDryRunOption(c, cfg, dm, pd, as, false), Parser: parser}
}
// ManifestKind enums the kind of OAM objects

View File

@@ -160,7 +160,7 @@ var _ = Describe("Test Live-Diff", func() {
It("Test renderless diff", func() {
liveDiffOpt := LiveDiffOption{
DryRun: NewDryRunOption(k8sClient, cfg, dm, pd, nil),
DryRun: NewDryRunOption(k8sClient, cfg, dm, pd, nil, false),
Parser: appfile.NewApplicationParser(k8sClient, dm, pd),
}
applyFile := func(filename string, ns string) {

View File

@@ -38,10 +38,12 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/cue/definition"
"github.com/oam-dev/kubevela/pkg/cue/packages"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/utils/apply"
)
// DryRun executes dry-run on an application
@@ -50,8 +52,8 @@ type DryRun interface {
}
// NewDryRunOption creates a dry-run option
func NewDryRunOption(c client.Client, cfg *rest.Config, dm discoverymapper.DiscoveryMapper, pd *packages.PackageDiscover, as []oam.Object) *Option {
return &Option{c, dm, pd, cfg, as}
func NewDryRunOption(c client.Client, cfg *rest.Config, dm discoverymapper.DiscoveryMapper, pd *packages.PackageDiscover, as []oam.Object, serverSideDryRun bool) *Option {
return &Option{c, dm, pd, cfg, as, serverSideDryRun}
}
// Option contains options to execute dry-run
@@ -65,6 +67,9 @@ type Option struct {
// DryRun will use capabilities in Auxiliaries as higher priority than
// getting one from cluster.
Auxiliaries []oam.Object
// serverSideDryRun If set to true, means will dry run via the apiserver.
serverSideDryRun bool
}
// validateObjectFromFile will read file into Unstructured object
@@ -122,7 +127,8 @@ func (d *Option) ValidateApp(ctx context.Context, filename string) error {
// ExecuteDryRun simulates applying an application into cluster and returns rendered
// resources but not persist them into cluster.
func (d *Option) ExecuteDryRun(ctx context.Context, app *v1beta1.Application) ([]*types.ComponentManifest, []*unstructured.Unstructured, error) {
func (d *Option) ExecuteDryRun(ctx context.Context, application *v1beta1.Application) ([]*types.ComponentManifest, []*unstructured.Unstructured, error) {
app := application.DeepCopy()
parser := appfile.NewDryRunApplicationParser(d.Client, d.DiscoveryMapper, d.PackageDiscover, d.Auxiliaries)
if app.Namespace != "" {
ctx = oamutil.SetNamespaceInCtx(ctx, app.Namespace)
@@ -138,11 +144,17 @@ func (d *Option) ExecuteDryRun(ctx context.Context, app *v1beta1.Application) ([
if err != nil {
return nil, nil, errors.WithMessage(err, "cannot generate manifests from components and traits")
}
objs, err := appFile.GeneratePolicyManifests(ctx)
policyManifests, err := appFile.GeneratePolicyManifests(ctx)
if err != nil {
return nil, nil, errors.WithMessage(err, "cannot generate manifests from policies")
}
return comps, objs, nil
if d.serverSideDryRun {
applyUtil := apply.NewAPIApplicator(d.Client)
if err := applyUtil.Apply(ctx, app, apply.DryRunAll()); err != nil {
return nil, nil, err
}
}
return comps, policyManifests, nil
}
// PrintDryRun will print the result of dry-run
@@ -162,6 +174,13 @@ func (d *Option) PrintDryRun(buff *bytes.Buffer, appName string, comps []*types.
buff.Write(result)
buff.WriteString("\n---\n")
for _, t := range c.Traits {
traitType := t.GetLabels()[oam.TraitTypeLabel]
switch {
case traitType == definition.AuxiliaryWorkload:
buff.WriteString("## From the auxiliary workload \n")
case traitType != "":
buff.WriteString(fmt.Sprintf("## From the trait %s \n", traitType))
}
result, err := yaml.Marshal(t)
if err != nil {
return errors.New("marshal result for Component " + c.Name + " trait " + t.GetName() + " object in yaml format")

View File

@@ -107,7 +107,7 @@ var _ = BeforeSuite(func(done Done) {
tdMyScaler, err := oamutil.Object2Unstructured(myscalerDef)
Expect(err).Should(BeNil())
dryrunOpt = NewDryRunOption(k8sClient, cfg, dm, pd, []oam.Object{cdMyWorker, tdMyIngress, tdMyScaler})
dryrunOpt = NewDryRunOption(k8sClient, cfg, dm, pd, []oam.Object{cdMyWorker, tdMyIngress, tdMyScaler}, false)
diffOpt = &LiveDiffOption{DryRun: dryrunOpt, Parser: appfile.NewApplicationParser(k8sClient, dm, pd)}
close(done)

View File

@@ -55,6 +55,7 @@ type applyAction struct {
isShared bool
skipUpdate bool
updateAnnotation bool
dryRun bool
}
// ApplyOption is called before applying state to the object.
@@ -172,6 +173,9 @@ func (a *APIApplicator) Apply(ctx context.Context, desired client.Object, ao ...
if err != nil {
return errors.Wrap(err, "cannot calculate patch by computing a three way diff")
}
if applyAct.dryRun {
return errors.Wrapf(a.c.Patch(ctx, desired, patch, client.DryRunAll), "cannot patch object")
}
return errors.Wrapf(a.c.Patch(ctx, desired, patch), "cannot patch object")
}
@@ -211,6 +215,9 @@ func createOrGetExisting(ctx context.Context, act *applyAction, c client.Client,
}
}
loggingApply("creating object", desired)
if act.dryRun {
return nil, errors.Wrap(c.Create(ctx, desired, client.DryRunAll), "cannot create object")
}
return nil, errors.Wrap(c.Create(ctx, desired), "cannot create object")
}
@@ -374,3 +381,11 @@ func SharedByApp(app *v1beta1.Application) ApplyOption {
return nil
}
}
// DryRunAll executing all validation, etc without persisting the change to storage.
func DryRunAll() ApplyOption {
return func(a *applyAction, existing, _ client.Object) error {
a.dryRun = true
return nil
}
}

View File

@@ -132,7 +132,7 @@ func (d *debugOpts) debugApplication(ctx context.Context, c common.Args, app *v1
if err != nil {
return err
}
dryRunOpt := dryrun.NewDryRunOption(cli, config, dm, pd, []oam.Object{})
dryRunOpt := dryrun.NewDryRunOption(cli, config, dm, pd, []oam.Object{}, false)
comps, _, err := dryRunOpt.ExecuteDryRun(ctx, app)
if err != nil {
ioStreams.Info(color.RedString("%s%s", emojiFail, err.Error()))

View File

@@ -133,7 +133,7 @@ func DryRunApplication(cmdOption *DryRunCmdOptions, c common.Args, namespace str
return buff, err
}
dryRunOpt := dryrun.NewDryRunOption(newClient, config, dm, pd, objs)
dryRunOpt := dryrun.NewDryRunOption(newClient, config, dm, pd, objs, false)
ctx := oamutil.SetNamespaceInCtx(context.Background(), namespace)
// Perform validation only if not in offline mode

View File

@@ -56,7 +56,7 @@ var _ = Describe("Test dry run with policy", func() {
dm, err := discoverymapper.New(cfg)
Expect(err).Should(BeNil())
dryRunOpt := dryrun.NewDryRunOption(k8sClient, cfg, dm, pd, nil)
dryRunOpt := dryrun.NewDryRunOption(k8sClient, cfg, dm, pd, nil, false)
comps, plcs, err := dryRunOpt.ExecuteDryRun(context.TODO(), &app)
Expect(err).Should(BeNil())