package stack import ( "context" "github.com/pulumi/pulumi/pkg/v3/display" "github.com/pulumi/pulumi/pkg/v3/resource/deploy" "github.com/pulumi/pulumi/sdk/v3/go/common/apitype" "github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/resource/config" ) func SerializePlanDiff( diff deploy.PlanDiff, enc config.Encrypter, showSecrets bool, ) (apitype.PlanDiffV1, error) { ctx := context.TODO() adds, err := SerializeProperties(ctx, diff.Adds, enc, showSecrets) if err != nil { return apitype.PlanDiffV1{}, err } updates, err := SerializeProperties(ctx, diff.Updates, enc, showSecrets) if err != nil { return apitype.PlanDiffV1{}, err } deletes := make([]string, len(diff.Deletes)) for i := range deletes { deletes[i] = string(diff.Deletes[i]) } return apitype.PlanDiffV1{ Adds: adds, Updates: updates, Deletes: deletes, }, nil } func DeserializePlanDiff( diff apitype.PlanDiffV1, dec config.Decrypter, enc config.Encrypter, ) (deploy.PlanDiff, error) { adds, err := DeserializeProperties(diff.Adds, dec, enc) if err != nil { return deploy.PlanDiff{}, err } updates, err := DeserializeProperties(diff.Updates, dec, enc) if err != nil { return deploy.PlanDiff{}, err } deletes := make([]resource.PropertyKey, len(diff.Deletes)) for i := range deletes { deletes[i] = resource.PropertyKey(diff.Deletes[i]) } return deploy.PlanDiff{Adds: adds, Updates: updates, Deletes: deletes}, nil } func SerializeResourcePlan( plan *deploy.ResourcePlan, enc config.Encrypter, showSecrets bool, ) (apitype.ResourcePlanV1, error) { var outputs map[string]interface{} if plan.Outputs != nil { ctx := context.TODO() outs, err := SerializeProperties(ctx, plan.Outputs, enc, showSecrets) if err != nil { return apitype.ResourcePlanV1{}, err } outputs = outs } steps := make([]apitype.OpType, len(plan.Ops)) for i, op := range plan.Ops { steps[i] = apitype.OpType(op) } var goal *apitype.GoalV1 if plan.Goal != nil { inputDiff, err := SerializePlanDiff(plan.Goal.InputDiff, enc, showSecrets) if err != nil { return apitype.ResourcePlanV1{}, err } outputDiff, err := SerializePlanDiff(plan.Goal.OutputDiff, enc, showSecrets) if err != nil { return apitype.ResourcePlanV1{}, err } goal = &apitype.GoalV1{ Type: plan.Goal.Type, Name: plan.Goal.Name, Custom: plan.Goal.Custom, InputDiff: inputDiff, OutputDiff: outputDiff, Parent: plan.Goal.Parent, Protect: plan.Goal.Protect, Dependencies: plan.Goal.Dependencies, Provider: plan.Goal.Provider, PropertyDependencies: plan.Goal.PropertyDependencies, DeleteBeforeReplace: plan.Goal.DeleteBeforeReplace, IgnoreChanges: plan.Goal.IgnoreChanges, AdditionalSecretOutputs: plan.Goal.AdditionalSecretOutputs, Aliases: plan.Goal.Aliases, ID: plan.Goal.ID, CustomTimeouts: plan.Goal.CustomTimeouts, } } return apitype.ResourcePlanV1{ Goal: goal, Seed: plan.Seed, Steps: steps, Outputs: outputs, }, nil } func SerializePlan(plan *deploy.Plan, enc config.Encrypter, showSecrets bool) (apitype.DeploymentPlanV1, error) { resourcePlans := map[resource.URN]apitype.ResourcePlanV1{} for urn, plan := range plan.ResourcePlans { serializedPlan, err := SerializeResourcePlan(plan, enc, showSecrets) if err != nil { return apitype.DeploymentPlanV1{}, err } resourcePlans[urn] = serializedPlan } return apitype.DeploymentPlanV1{ Manifest: plan.Manifest.Serialize(), ResourcePlans: resourcePlans, Config: plan.Config, }, nil } func DeserializeResourcePlan( plan apitype.ResourcePlanV1, dec config.Decrypter, enc config.Encrypter, ) (*deploy.ResourcePlan, error) { var goal *deploy.GoalPlan if plan.Goal != nil { inputDiff, err := DeserializePlanDiff(plan.Goal.InputDiff, dec, enc) if err != nil { return nil, err } outputDiff, err := DeserializePlanDiff(plan.Goal.OutputDiff, dec, enc) if err != nil { return nil, err } goal = &deploy.GoalPlan{ Type: plan.Goal.Type, Name: plan.Goal.Name, Custom: plan.Goal.Custom, InputDiff: inputDiff, OutputDiff: outputDiff, Parent: plan.Goal.Parent, Protect: plan.Goal.Protect, Dependencies: plan.Goal.Dependencies, Provider: plan.Goal.Provider, PropertyDependencies: plan.Goal.PropertyDependencies, DeleteBeforeReplace: plan.Goal.DeleteBeforeReplace, IgnoreChanges: plan.Goal.IgnoreChanges, AdditionalSecretOutputs: plan.Goal.AdditionalSecretOutputs, Aliases: plan.Goal.Aliases, ID: plan.Goal.ID, CustomTimeouts: plan.Goal.CustomTimeouts, } } var outputs resource.PropertyMap if plan.Outputs != nil { outs, err := DeserializeProperties(plan.Outputs, dec, enc) if err != nil { return nil, err } outputs = outs } ops := make([]display.StepOp, len(plan.Steps)) for i, op := range plan.Steps { ops[i] = display.StepOp(op) } return &deploy.ResourcePlan{ Goal: goal, Seed: plan.Seed, Ops: ops, Outputs: outputs, }, nil } func DeserializePlan(plan apitype.DeploymentPlanV1, dec config.Decrypter, enc config.Encrypter) (*deploy.Plan, error) { manifest, err := deploy.DeserializeManifest(plan.Manifest) if err != nil { return nil, err } deserializedPlan := &deploy.Plan{ Config: plan.Config, Manifest: *manifest, ResourcePlans: make(map[resource.URN]*deploy.ResourcePlan), } for urn, resourcePlan := range plan.ResourcePlans { deserializedResourcePlan, err := DeserializeResourcePlan(resourcePlan, dec, enc) if err != nil { return nil, err } deserializedPlan.ResourcePlans[urn] = deserializedResourcePlan } return deserializedPlan, nil }