-
Notifications
You must be signed in to change notification settings - Fork 78
/
destory.go
99 lines (85 loc) · 2.71 KB
/
destory.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package operation
import (
"sync"
"kusionstack.io/kusion/pkg/engine/operation/graph"
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/operation/parser"
runtimeinit "kusionstack.io/kusion/pkg/engine/runtime/init"
"kusionstack.io/kusion/pkg/models"
"kusionstack.io/kusion/pkg/status"
"kusionstack.io/kusion/third_party/terraform/dag"
"kusionstack.io/kusion/third_party/terraform/tfdiags"
)
type DestroyOperation struct {
opsmodels.Operation
}
type DestroyRequest struct {
opsmodels.Request `json:",inline" yaml:",inline"`
}
func NewDestroyGraph(resource models.Resources) (*dag.AcyclicGraph, status.Status) {
ag := &dag.AcyclicGraph{}
ag.Add(&graph.RootNode{})
deleteResourceParser := parser.NewDeleteResourceParser(resource)
s := deleteResourceParser.Parse(ag)
if status.IsErr(s) {
return nil, s
}
return ag, s
}
// Destroy will delete all resources in this request. The whole process is similar to the operation Apply,
// but every node's execution is deleting the resource.
func (do *DestroyOperation) Destroy(request *DestroyRequest) (st status.Status) {
o := do.Operation
defer close(o.MsgCh)
if st = validateRequest(&request.Request); status.IsErr(st) {
return st
}
// 1. init & build Indexes
priorState, resultState := o.InitStates(&request.Request)
priorStateResourceIndex := priorState.Resources.Index()
// copy priorStateResourceIndex into a new map
stateResourceIndex := map[string]*models.Resource{}
for k, v := range priorStateResourceIndex {
stateResourceIndex[k] = v
}
// only destroy resources we have recorded
resources := priorState.Resources
runtimesMap, s := runtimeinit.Runtimes(resources, o.Stack)
if status.IsErr(s) {
return s
}
o.RuntimeMap = runtimesMap
// 2. build & walk DAG
destroyGraph, s := NewDestroyGraph(resources)
if status.IsErr(s) {
return s
}
newDo := &DestroyOperation{
Operation: opsmodels.Operation{
OperationType: opsmodels.Destroy,
StateStorage: o.StateStorage,
CtxResourceIndex: map[string]*models.Resource{},
PriorStateResourceIndex: priorStateResourceIndex,
StateResourceIndex: stateResourceIndex,
RuntimeMap: o.RuntimeMap,
Stack: o.Stack,
MsgCh: o.MsgCh,
ResultState: resultState,
Lock: &sync.Mutex{},
},
}
w := &dag.Walker{Callback: newDo.destroyWalkFun}
w.Update(destroyGraph)
// Wait
if diags := w.Wait(); diags.HasErrors() {
st = status.NewErrorStatus(diags.Err())
return st
}
return nil
}
func (do *DestroyOperation) destroyWalkFun(v dag.Vertex) (diags tfdiags.Diagnostics) {
ao := &ApplyOperation{
Operation: do.Operation,
}
return ao.applyWalkFun(v)
}