WIP: outputs in plans
This commit is contained in:
parent
24a0eb0274
commit
954bdc025b
|
@ -145,6 +145,30 @@ func (m *resourceMap) mapRange(callback func(urn resource.URN, state *resource.S
|
|||
})
|
||||
}
|
||||
|
||||
type resourcePlans struct {
|
||||
m sync.RWMutex
|
||||
plans map[resource.URN]*ResourcePlan
|
||||
}
|
||||
|
||||
func (m *resourcePlans) set(urn resource.URN, plan *ResourcePlan) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
m.plans[urn] = plan
|
||||
}
|
||||
|
||||
func (m *resourcePlans) get(urn resource.URN) (*ResourcePlan, bool) {
|
||||
m.m.RLock()
|
||||
defer m.m.RUnlock()
|
||||
|
||||
p, ok := m.plans[urn]
|
||||
return p, ok
|
||||
}
|
||||
|
||||
func (m *resourcePlans) plan() Plan {
|
||||
return m.plans
|
||||
}
|
||||
|
||||
// A Deployment manages the iterative computation and execution of a deployment based on a stream of goal states.
|
||||
// A running deployment emits events that indicate its progress. These events must be used to record the new state
|
||||
// of the deployment target.
|
||||
|
@ -164,7 +188,7 @@ type Deployment struct {
|
|||
providers *providers.Registry // the provider registry for this deployment.
|
||||
goals *goalMap // the set of resource goals generated by the deployment.
|
||||
news *resourceMap // the set of new resources generated by the deployment
|
||||
newPlan map[resource.URN]*ResourcePlan // the set of new resource plans.
|
||||
newPlans *resourcePlans // the set of new resource plans.
|
||||
}
|
||||
|
||||
// addDefaultProviders adds any necessary default provider definitions and references to the given snapshot. Version
|
||||
|
@ -354,7 +378,7 @@ func NewDeployment(ctx *plugin.Context, target *Target, prev *Snapshot, plan Pla
|
|||
providers: reg,
|
||||
goals: newGoals,
|
||||
news: newResources,
|
||||
newPlan: Plan{},
|
||||
newPlans: &resourcePlans{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ func (ex *deploymentExecutor) Execute(callerCtx context.Context, opts Options, p
|
|||
return nil, result.Bail()
|
||||
}
|
||||
|
||||
return ex.deployment.newPlan, res
|
||||
return ex.deployment.newPlans.plan(), res
|
||||
}
|
||||
|
||||
func (ex *deploymentExecutor) performDeletes(
|
||||
|
@ -466,7 +466,7 @@ func (ex *deploymentExecutor) importResources(callerCtx context.Context, opts Op
|
|||
ex.reportExecResult("canceled", preview)
|
||||
return nil, result.Bail()
|
||||
}
|
||||
return ex.deployment.newPlan, nil
|
||||
return ex.deployment.newPlans.plan(), nil
|
||||
}
|
||||
|
||||
// refresh refreshes the state of the base checkpoint file for the current deployment in memory.
|
||||
|
|
|
@ -21,8 +21,9 @@ type Plan map[resource.URN]*ResourcePlan
|
|||
// A ResourcePlan represents the planned goal state and resource operations for a single resource. The operations are
|
||||
// ordered.
|
||||
type ResourcePlan struct {
|
||||
Goal *resource.Goal
|
||||
Ops []StepOp
|
||||
Goal *resource.Goal
|
||||
Ops []StepOp
|
||||
Outputs resource.PropertyMap
|
||||
}
|
||||
|
||||
func (rp *ResourcePlan) diffURNs(a, b []resource.URN) (message string, changed bool) {
|
||||
|
|
|
@ -296,6 +296,11 @@ func (se *stepExecutor) executeStep(workerID int, step Step) error {
|
|||
if _, hasGoal := se.deployment.goals.get(newState.URN); hasGoal {
|
||||
se.deployment.news.set(newState.URN, newState)
|
||||
}
|
||||
|
||||
// Update the resource's outputs in the generated plan.
|
||||
if resourcePlan, ok := se.deployment.newPlans.get(newState.URN); ok {
|
||||
resourcePlan.Outputs = newState.Outputs
|
||||
}
|
||||
}
|
||||
|
||||
if events != nil {
|
||||
|
|
|
@ -170,12 +170,12 @@ func (sg *stepGenerator) GenerateSteps(event RegisterResourceEvent) ([]Step, res
|
|||
resourcePlan.Ops = resourcePlan.Ops[1:]
|
||||
}
|
||||
|
||||
resourcePlan, ok := sg.deployment.newPlan[s.URN()]
|
||||
resourcePlan, ok := sg.deployment.newPlans.get(s.URN())
|
||||
if !ok {
|
||||
// TODO(pdg-plan): using the program inputs means that non-determinism could sneak in as part of default
|
||||
// application. However, it is necessary in the face of computed inputs.
|
||||
resourcePlan = &ResourcePlan{Goal: event.Goal()}
|
||||
sg.deployment.newPlan[s.URN()] = resourcePlan
|
||||
sg.deployment.newPlans.set(s.URN(), resourcePlan)
|
||||
}
|
||||
resourcePlan.Ops = append(resourcePlan.Ops, s.Op())
|
||||
}
|
||||
|
|
|
@ -13,6 +13,15 @@ func SerializeResourcePlan(plan *deploy.ResourcePlan, enc config.Encrypter, show
|
|||
return apitype.ResourcePlanV1{}, err
|
||||
}
|
||||
|
||||
var outputs map[string]interface{}
|
||||
if plan.Outputs != nil {
|
||||
outs, err := SerializeProperties(plan.Outputs, enc, showSecrets)
|
||||
if err != nil {
|
||||
return apitype.ResourcePlanV1{}, err
|
||||
}
|
||||
outputs = outs
|
||||
}
|
||||
|
||||
goal := apitype.GoalV1{
|
||||
Type: plan.Goal.Type,
|
||||
Name: plan.Goal.Name,
|
||||
|
@ -37,8 +46,9 @@ func SerializeResourcePlan(plan *deploy.ResourcePlan, enc config.Encrypter, show
|
|||
}
|
||||
|
||||
return apitype.ResourcePlanV1{
|
||||
Goal: goal,
|
||||
Steps: steps,
|
||||
Goal: goal,
|
||||
Steps: steps,
|
||||
Outputs: outputs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -60,6 +70,15 @@ func DeserializeResourcePlan(plan apitype.ResourcePlanV1, dec config.Decrypter,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var outputs resource.PropertyMap
|
||||
if plan.Outputs != nil {
|
||||
outs, err := DeserializeProperties(plan.Outputs, dec, enc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outputs = outs
|
||||
}
|
||||
|
||||
goal := &resource.Goal{
|
||||
Type: plan.Goal.Type,
|
||||
Name: plan.Goal.Name,
|
||||
|
@ -84,8 +103,9 @@ func DeserializeResourcePlan(plan apitype.ResourcePlanV1, dec config.Decrypter,
|
|||
}
|
||||
|
||||
return &deploy.ResourcePlan{
|
||||
Goal: goal,
|
||||
Ops: ops,
|
||||
Goal: goal,
|
||||
Ops: ops,
|
||||
Outputs: outputs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ type ResourcePlanV1 struct {
|
|||
Goal GoalV1 `json:"goal"`
|
||||
// The steps to be performed on the resource.
|
||||
Steps []OpType `json:"steps,omitempty"`
|
||||
// The proposed outputs for the resource, if any. Purely advisory.
|
||||
Outputs map[string]interface{} `json:"state"`
|
||||
}
|
||||
|
||||
// VersionedDeploymentPlan is a version number plus a JSON document. The version number describes what
|
||||
|
|
Loading…
Reference in a new issue