Skip to content

Commit

Permalink
Auto import resources exist in spec and live cluster but no recorded …
Browse files Browse the repository at this point in the history
…in Kusion (#236)

* add import interface in Runtime

* cleanup coeds for go vet
  • Loading branch information
SparkYuan committed Feb 9, 2023
1 parent 249cd6d commit edbc8f8
Show file tree
Hide file tree
Showing 18 changed files with 273 additions and 61 deletions.
7 changes: 6 additions & 1 deletion pkg/cmd/apply/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"kusionstack.io/kusion/pkg/engine/operation"
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/runtime"
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
"kusionstack.io/kusion/pkg/engine/states/local"
"kusionstack.io/kusion/pkg/generator"
"kusionstack.io/kusion/pkg/projectstack"
Expand Down Expand Up @@ -85,7 +86,7 @@ func mockGenerateSpec() {
}

func mockNewKubernetesRuntime() {
monkey.Patch(runtime.NewKubernetesRuntime, func() (runtime.Runtime, error) {
monkey.Patch(kubernetes.NewKubernetesRuntime, func() (runtime.Runtime, error) {
return &fakerRuntime{}, nil
})
}
Expand All @@ -94,6 +95,10 @@ var _ runtime.Runtime = (*fakerRuntime)(nil)

type fakerRuntime struct{}

func (f *fakerRuntime) Import(ctx context.Context, request *runtime.ImportRequest) *runtime.ImportResponse {
return &runtime.ImportResponse{Resource: request.PlanResource}
}

func (f *fakerRuntime) Apply(ctx context.Context, request *runtime.ApplyRequest) *runtime.ApplyResponse {
return &runtime.ApplyResponse{
Resource: request.PlanResource,
Expand Down
7 changes: 6 additions & 1 deletion pkg/cmd/destroy/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"kusionstack.io/kusion/pkg/engine/operation"
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/runtime"
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
"kusionstack.io/kusion/pkg/engine/states/local"
"kusionstack.io/kusion/pkg/generator"
"kusionstack.io/kusion/pkg/projectstack"
Expand Down Expand Up @@ -107,7 +108,7 @@ func Test_preview(t *testing.T) {
}

func mockNewKubernetesRuntime() {
monkey.Patch(runtime.NewKubernetesRuntime, func() (runtime.Runtime, error) {
monkey.Patch(kubernetes.NewKubernetesRuntime, func() (runtime.Runtime, error) {
return &fakerRuntime{}, nil
})
}
Expand All @@ -116,6 +117,10 @@ var _ runtime.Runtime = (*fakerRuntime)(nil)

type fakerRuntime struct{}

func (f *fakerRuntime) Import(ctx context.Context, request *runtime.ImportRequest) *runtime.ImportResponse {
return &runtime.ImportResponse{Resource: request.PlanResource}
}

func (f *fakerRuntime) Apply(ctx context.Context, request *runtime.ApplyRequest) *runtime.ApplyResponse {
return &runtime.ApplyResponse{
Resource: request.PlanResource,
Expand Down
7 changes: 6 additions & 1 deletion pkg/cmd/preview/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"kusionstack.io/kusion/pkg/engine/operation"
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/runtime"
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
"kusionstack.io/kusion/pkg/engine/states/local"
"kusionstack.io/kusion/pkg/generator"
"kusionstack.io/kusion/pkg/projectstack"
Expand Down Expand Up @@ -106,6 +107,10 @@ func TestPreviewOptions_Run(t *testing.T) {

type fooRuntime struct{}

func (f *fooRuntime) Import(ctx context.Context, request *runtime.ImportRequest) *runtime.ImportResponse {
return &runtime.ImportResponse{Resource: request.PlanResource}
}

func (f *fooRuntime) Apply(ctx context.Context, request *runtime.ApplyRequest) *runtime.ApplyResponse {
return &runtime.ApplyResponse{
Resource: request.PlanResource,
Expand Down Expand Up @@ -193,7 +198,7 @@ func mockGenerateSpec() {
}

func mockNewKubernetesRuntime() {
monkey.Patch(runtime.NewKubernetesRuntime, func() (runtime.Runtime, error) {
monkey.Patch(kubernetes.NewKubernetesRuntime, func() (runtime.Runtime, error) {
return &fooRuntime{}, nil
})
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/engine/operation/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/runtime"
runtimeinit "kusionstack.io/kusion/pkg/engine/runtime/init"
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
"kusionstack.io/kusion/pkg/engine/states"
"kusionstack.io/kusion/pkg/engine/states/local"
"kusionstack.io/kusion/pkg/projectstack"
Expand Down Expand Up @@ -137,7 +138,7 @@ func TestOperation_Apply(t *testing.T) {
fields: fields{
OperationType: opsmodels.Apply,
StateStorage: &local.FileSystemState{Path: filepath.Join("test_data", local.KusionState)},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &runtime.KubernetesRuntime{}},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &kubernetes.KubernetesRuntime{}},
MsgCh: make(chan opsmodels.Message, 5),
},
args: args{applyRequest: &ApplyRequest{opsmodels.Request{
Expand Down Expand Up @@ -176,7 +177,7 @@ func TestOperation_Apply(t *testing.T) {
return nil
})
monkey.Patch(runtimeinit.Runtimes, func(resources models.Resources) (map[models.Type]runtime.Runtime, status.Status) {
return map[models.Type]runtime.Runtime{runtime.Kubernetes: &runtime.KubernetesRuntime{}}, nil
return map[models.Type]runtime.Runtime{runtime.Kubernetes: &kubernetes.KubernetesRuntime{}}, nil
})

gotRsp, gotSt := ao.Apply(tt.args.applyRequest)
Expand Down
3 changes: 2 additions & 1 deletion pkg/engine/operation/destory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"kusionstack.io/kusion/pkg/engine/operation/graph"
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/runtime"
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
"kusionstack.io/kusion/pkg/engine/states/local"
"kusionstack.io/kusion/pkg/projectstack"
"kusionstack.io/kusion/pkg/status"
Expand Down Expand Up @@ -54,7 +55,7 @@ func TestOperation_Destroy(t *testing.T) {
opsmodels.Operation{
OperationType: opsmodels.Destroy,
StateStorage: &local.FileSystemState{Path: filepath.Join("test_data", local.KusionState)},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &runtime.KubernetesRuntime{}},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &kubernetes.KubernetesRuntime{}},
},
}
r := &DestroyRequest{
Expand Down
19 changes: 9 additions & 10 deletions pkg/engine/operation/graph/resource_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,28 +148,27 @@ func (rn *ResourceNode) applyResource(operation *opsmodels.Operation, priorState
var s status.Status
resourceType := rn.state.Type

rt := operation.RuntimeMap[resourceType]
switch rn.Action {
case opsmodels.Create, opsmodels.Update:
response := operation.RuntimeMap[resourceType].Apply(context.Background(), &runtime.ApplyRequest{
PriorResource: priorState, PlanResource: planedState, Stack: operation.Stack,
})
response := rt.Apply(context.Background(), &runtime.ApplyRequest{PriorResource: priorState, PlanResource: planedState, Stack: operation.Stack})
res = response.Resource
s = response.Status
log.Debugf("apply resource:%s, result: %v", planedState.ID, jsonutil.Marshal2String(res))
if s != nil {
log.Debugf("apply status: %v", s.String())
}
log.Debugf("apply resource:%s, response: %v", planedState.ID, jsonutil.Marshal2String(response))
case opsmodels.Delete:
response := operation.RuntimeMap[resourceType].Delete(context.Background(), &runtime.DeleteRequest{Resource: priorState, Stack: operation.Stack})
response := rt.Delete(context.Background(), &runtime.DeleteRequest{Resource: priorState, Stack: operation.Stack})
s = response.Status
if s != nil {
log.Debugf("delete state: %v", s.String())
log.Debugf("delete resource:%s, state: %v", planedState.ID, s.String())
}
case opsmodels.UnChange:
log.Infof("planed resource and live state are equal")
// auto import resources exist in spec and live cluster but no recorded in kusion_state.json
if priorState == nil {
res = live
response := rt.Import(context.Background(), &runtime.ImportRequest{PlanResource: planedState})
s = response.Status
log.Debugf("import resource:%s, state:%v", planedState.ID, s.String())
res = response.Resource
} else {
res = priorState
}
Expand Down
13 changes: 7 additions & 6 deletions pkg/engine/operation/graph/resource_node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"kusionstack.io/kusion/pkg/engine/models"
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/runtime"
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
"kusionstack.io/kusion/pkg/engine/states"
"kusionstack.io/kusion/pkg/engine/states/local"
"kusionstack.io/kusion/pkg/status"
Expand Down Expand Up @@ -109,7 +110,7 @@ func TestResourceNode_Execute(t *testing.T) {
MsgCh: make(chan opsmodels.Message),
ResultState: states.NewState(),
Lock: &sync.Mutex{},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &runtime.KubernetesRuntime{}},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &kubernetes.KubernetesRuntime{}},
}},
want: nil,
},
Expand All @@ -129,7 +130,7 @@ func TestResourceNode_Execute(t *testing.T) {
MsgCh: make(chan opsmodels.Message),
ResultState: states.NewState(),
Lock: &sync.Mutex{},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &runtime.KubernetesRuntime{}},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &kubernetes.KubernetesRuntime{}},
}},
want: nil,
},
Expand All @@ -149,7 +150,7 @@ func TestResourceNode_Execute(t *testing.T) {
MsgCh: make(chan opsmodels.Message),
ResultState: states.NewState(),
Lock: &sync.Mutex{},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &runtime.KubernetesRuntime{}},
RuntimeMap: map[models.Type]runtime.Runtime{runtime.Kubernetes: &kubernetes.KubernetesRuntime{}},
}},
want: status.NewErrorStatusWithMsg(status.IllegalManifest, "can't find specified value in resource:jack by ref:jack.notExist"),
},
Expand All @@ -162,19 +163,19 @@ func TestResourceNode_Execute(t *testing.T) {
state: tt.fields.state,
}
monkey.PatchInstanceMethod(reflect.TypeOf(tt.args.operation.RuntimeMap[runtime.Kubernetes]), "Apply",
func(k *runtime.KubernetesRuntime, ctx context.Context, request *runtime.ApplyRequest) *runtime.ApplyResponse {
func(k *kubernetes.KubernetesRuntime, ctx context.Context, request *runtime.ApplyRequest) *runtime.ApplyResponse {
mockState := *newResourceState
mockState.Attributes["a"] = "c"
return &runtime.ApplyResponse{
Resource: &mockState,
}
})
monkey.PatchInstanceMethod(reflect.TypeOf(tt.args.operation.RuntimeMap[runtime.Kubernetes]), "Delete",
func(k *runtime.KubernetesRuntime, ctx context.Context, request *runtime.DeleteRequest) *runtime.DeleteResponse {
func(k *kubernetes.KubernetesRuntime, ctx context.Context, request *runtime.DeleteRequest) *runtime.DeleteResponse {
return &runtime.DeleteResponse{Status: nil}
})
monkey.PatchInstanceMethod(reflect.TypeOf(tt.args.operation.RuntimeMap[runtime.Kubernetes]), "Read",
func(k *runtime.KubernetesRuntime, ctx context.Context, request *runtime.ReadRequest) *runtime.ReadResponse {
func(k *kubernetes.KubernetesRuntime, ctx context.Context, request *runtime.ReadRequest) *runtime.ReadResponse {
return &runtime.ReadResponse{Resource: request.PriorResource}
})
monkey.PatchInstanceMethod(reflect.TypeOf(tt.args.operation.StateStorage), "Apply",
Expand Down
4 changes: 4 additions & 0 deletions pkg/engine/operation/preview_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ var _ runtime.Runtime = (*fakePreviewRuntime)(nil)

type fakePreviewRuntime struct{}

func (f *fakePreviewRuntime) Import(ctx context.Context, request *runtime.ImportRequest) *runtime.ImportResponse {
return &runtime.ImportResponse{Resource: request.PlanResource}
}

func (f *fakePreviewRuntime) Apply(ctx context.Context, request *runtime.ApplyRequest) *runtime.ApplyResponse {
return &runtime.ApplyResponse{
Resource: request.PlanResource,
Expand Down
10 changes: 9 additions & 1 deletion pkg/engine/operation/watch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8sWatch "k8s.io/apimachinery/pkg/watch"

"kusionstack.io/kusion/pkg/engine/models"
opsmodels "kusionstack.io/kusion/pkg/engine/operation/models"
"kusionstack.io/kusion/pkg/engine/runtime"
Expand Down Expand Up @@ -59,10 +60,17 @@ var barDeployment = map[string]interface{}{
},
}

var fooRuntime = &fooWatchRuntime{}
var (
fooRuntime = &fooWatchRuntime{}
_ runtime.Runtime = (*fooWatchRuntime)(nil)
)

type fooWatchRuntime struct{}

func (f *fooWatchRuntime) Import(ctx context.Context, request *runtime.ImportRequest) *runtime.ImportResponse {
return &runtime.ImportResponse{Resource: request.PlanResource}
}

func (f *fooWatchRuntime) Apply(ctx context.Context, request *runtime.ApplyRequest) *runtime.ApplyResponse {
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/engine/runtime/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import (

"kusionstack.io/kusion/pkg/engine/models"
"kusionstack.io/kusion/pkg/engine/runtime"
"kusionstack.io/kusion/pkg/engine/runtime/kubernetes"
"kusionstack.io/kusion/pkg/engine/runtime/terraform"
"kusionstack.io/kusion/pkg/status"
)

var SupportRuntimes = map[models.Type]InitFn{
runtime.Kubernetes: runtime.NewKubernetesRuntime,
runtime.Kubernetes: kubernetes.NewKubernetesRuntime,
runtime.Terraform: terraform.NewTerraformRuntime,
}

Expand Down
Loading

0 comments on commit edbc8f8

Please sign in to comment.