Skip to content

Commit 6b33318

Browse files
authored
chore: align instance api configs (#10146)
1 parent 404b435 commit 6b33318

13 files changed

Lines changed: 1403 additions & 165 deletions

File tree

apis/workloads/v1/instance_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ type InstanceSpec struct {
128128
// +optional
129129
LifecycleActions *LifecycleActions `json:"lifecycleActions,omitempty"`
130130

131+
// Describe the configs to be reconfigured.
132+
//
133+
// +optional
134+
Configs []ConfigTemplate `json:"configs,omitempty"`
135+
131136
// Assistant objects that are necessary to run the instance.
132137
//
133138
// +optional
@@ -183,6 +188,11 @@ type InstanceStatus2 struct {
183188
// +optional
184189
Role string `json:"role,omitempty"`
185190

191+
// The status of configs.
192+
//
193+
// +optional
194+
Configs []InstanceConfigStatus `json:"configs,omitempty"`
195+
186196
// Represents whether the instance is in volume expansion.
187197
//
188198
// +optional

apis/workloads/v1/zz_generated.deepcopy.go

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/workloads.kubeblocks.io_instances.yaml

Lines changed: 478 additions & 0 deletions
Large diffs are not rendered by default.

controllers/workloads/instance_controller_test.go

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,150 @@ var _ = Describe("Instance Controller", func() {
501501
})
502502

503503
// It("reconfigure", func() {
504-
// // TODO
505-
// })
504+
It("reconfigure", func() {
505+
var (
506+
reconfigure string
507+
parameters map[string]string
508+
)
509+
510+
testapps.MockKBAgentClient(func(recorder *kbacli.MockClientMockRecorder) {
511+
recorder.Action(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, req kbagentproto.ActionRequest) (kbagentproto.ActionResponse, error) {
512+
if req.Action == "reconfigure" {
513+
reconfigure = req.Action
514+
parameters = req.Parameters
515+
}
516+
return kbagentproto.ActionResponse{}, nil
517+
}).AnyTimes()
518+
})
519+
defer kbacli.UnsetMockClient()
520+
521+
createInstObj(instName, func(f *testapps.MockInstanceFactory) {
522+
f.AddConfigs(
523+
workloads.ConfigTemplate{
524+
Name: "server",
525+
Generation: int64(1),
526+
},
527+
workloads.ConfigTemplate{
528+
Name: "logging",
529+
Generation: int64(2),
530+
},
531+
)
532+
})
533+
534+
mockPodReady(instObj.Namespace, instObj.Name)
535+
536+
By("check the init config status")
537+
Eventually(testapps.CheckObj(&testCtx, instKey, func(g Gomega, inst *workloads.Instance) {
538+
g.Expect(inst.Status.Configs).Should(Equal([]workloads.InstanceConfigStatus{
539+
{Name: "server", Generation: int64(1)},
540+
{Name: "logging", Generation: int64(2)},
541+
}))
542+
})).Should(Succeed())
543+
544+
By("check the reconfigure action not called")
545+
Consistently(func(g Gomega) {
546+
g.Expect(reconfigure).Should(BeEmpty())
547+
g.Expect(parameters).Should(BeNil())
548+
}).Should(Succeed())
549+
550+
By("update configs")
551+
Expect(testapps.GetAndChangeObj(&testCtx, instKey, func(inst *workloads.Instance) {
552+
inst.Spec.Configs[1].Generation = 128
553+
inst.Spec.Configs[1].Reconfigure = testapps.NewLifecycleAction("reconfigure")
554+
inst.Spec.Configs[1].Parameters = map[string]string{"foo": "bar"}
555+
})()).ShouldNot(HaveOccurred())
556+
557+
By("check the config status updated")
558+
Eventually(testapps.CheckObj(&testCtx, instKey, func(g Gomega, inst *workloads.Instance) {
559+
g.Expect(inst.Status.Configs).Should(Equal([]workloads.InstanceConfigStatus{
560+
{Name: "server", Generation: int64(1)},
561+
{Name: "logging", Generation: int64(128)},
562+
}))
563+
})).Should(Succeed())
564+
565+
By("check the reconfigure action call")
566+
Eventually(func(g Gomega) {
567+
g.Expect(reconfigure).Should(Equal("reconfigure"))
568+
g.Expect(parameters).Should(HaveKeyWithValue("foo", "bar"))
569+
}).Should(Succeed())
570+
})
571+
572+
It("reconfigure after config removed and added back", func() {
573+
var (
574+
reconfigure string
575+
parameters map[string]string
576+
)
577+
578+
testapps.MockKBAgentClient(func(recorder *kbacli.MockClientMockRecorder) {
579+
recorder.Action(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, req kbagentproto.ActionRequest) (kbagentproto.ActionResponse, error) {
580+
if req.Action == "reconfigure" {
581+
reconfigure = req.Action
582+
parameters = req.Parameters
583+
}
584+
return kbagentproto.ActionResponse{}, nil
585+
}).AnyTimes()
586+
})
587+
defer kbacli.UnsetMockClient()
588+
589+
createInstObj(instName, func(f *testapps.MockInstanceFactory) {
590+
f.AddConfigs(
591+
workloads.ConfigTemplate{
592+
Name: "server",
593+
Generation: int64(1),
594+
},
595+
workloads.ConfigTemplate{
596+
Name: "logging",
597+
Generation: int64(2),
598+
},
599+
)
600+
})
601+
602+
mockPodReady(instObj.Namespace, instObj.Name)
603+
604+
By("check the init config status")
605+
Eventually(testapps.CheckObj(&testCtx, instKey, func(g Gomega, inst *workloads.Instance) {
606+
g.Expect(inst.Status.Configs).Should(Equal([]workloads.InstanceConfigStatus{
607+
{Name: "server", Generation: int64(1)},
608+
{Name: "logging", Generation: int64(2)},
609+
}))
610+
})).Should(Succeed())
611+
612+
By("remove one config from spec")
613+
Expect(testapps.GetAndChangeObj(&testCtx, instKey, func(inst *workloads.Instance) {
614+
inst.Spec.Configs = inst.Spec.Configs[:1]
615+
})()).ShouldNot(HaveOccurred())
616+
617+
By("check the removed config status pruned")
618+
Eventually(testapps.CheckObj(&testCtx, instKey, func(g Gomega, inst *workloads.Instance) {
619+
g.Expect(inst.Status.Configs).Should(Equal([]workloads.InstanceConfigStatus{
620+
{Name: "server", Generation: int64(1)},
621+
}))
622+
})).Should(Succeed())
623+
624+
By("add the config back with same generation")
625+
Expect(testapps.GetAndChangeObj(&testCtx, instKey, func(inst *workloads.Instance) {
626+
inst.Spec.Configs = append(inst.Spec.Configs, workloads.ConfigTemplate{
627+
Name: "logging",
628+
Generation: int64(2),
629+
Reconfigure: testapps.NewLifecycleAction("reconfigure"),
630+
Parameters: map[string]string{"foo": "bar"},
631+
})
632+
})()).ShouldNot(HaveOccurred())
633+
634+
By("check the config status restored")
635+
Eventually(testapps.CheckObj(&testCtx, instKey, func(g Gomega, inst *workloads.Instance) {
636+
g.Expect(inst.Status.Configs).Should(Equal([]workloads.InstanceConfigStatus{
637+
{Name: "server", Generation: int64(1)},
638+
{Name: "logging", Generation: int64(2)},
639+
}))
640+
})).Should(Succeed())
641+
642+
By("check the reconfigure action call")
643+
Eventually(func(g Gomega) {
644+
g.Expect(reconfigure).Should(Equal("reconfigure"))
645+
g.Expect(parameters).Should(HaveKeyWithValue("foo", "bar"))
646+
}).Should(Succeed())
647+
})
506648
//
507649
// It("member join", func() {
508650
// // TODO

controllers/workloads/instanceset_controller_2_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2020
package workloads
2121

2222
import (
23+
"context"
2324
"fmt"
25+
"strings"
2426
"time"
2527

28+
"github.com/golang/mock/gomock"
2629
. "github.com/onsi/ginkgo/v2"
2730
. "github.com/onsi/gomega"
2831

@@ -40,6 +43,8 @@ import (
4043
"github.com/apecloud/kubeblocks/pkg/constant"
4144
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
4245
"github.com/apecloud/kubeblocks/pkg/generics"
46+
kbacli "github.com/apecloud/kubeblocks/pkg/kbagent/client"
47+
kbagentproto "github.com/apecloud/kubeblocks/pkg/kbagent/proto"
4348
testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps"
4449
)
4550

@@ -286,6 +291,96 @@ var _ = Describe("InstanceSet Controller 2", func() {
286291
})).Should(Succeed())
287292
})
288293

294+
It("reconfigure", func() {
295+
var (
296+
reconfigure string
297+
parameters map[string]string
298+
)
299+
300+
testapps.MockKBAgentClient(func(recorder *kbacli.MockClientMockRecorder) {
301+
recorder.Action(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, req kbagentproto.ActionRequest) (kbagentproto.ActionResponse, error) {
302+
if strings.ToLower(req.Action) == "reconfigure" {
303+
reconfigure = req.Action
304+
parameters = req.Parameters
305+
}
306+
return kbagentproto.ActionResponse{}, nil
307+
}).AnyTimes()
308+
})
309+
defer kbacli.UnsetMockClient()
310+
311+
oldReplicas := replicas
312+
replicas = 1
313+
defer func() {
314+
replicas = oldReplicas
315+
}()
316+
317+
createITSObj(itsName, func(f *testapps.MockInstanceSetFactory) {
318+
f.SetInstanceUpdateStrategy(&workloads.InstanceUpdateStrategy{
319+
Type: kbappsv1.RollingUpdateStrategyType,
320+
}).AddConfigs(
321+
workloads.ConfigTemplate{
322+
Name: "server",
323+
Generation: int64(1),
324+
},
325+
workloads.ConfigTemplate{
326+
Name: "logging",
327+
Generation: int64(2),
328+
},
329+
)
330+
})
331+
332+
mockPodsReady()
333+
334+
By("check the init instance status")
335+
Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) {
336+
g.Expect(its.Status.InstanceStatus).Should(HaveLen(1))
337+
g.Expect(its.Status.InstanceStatus[0].Configs).Should(Equal([]workloads.InstanceConfigStatus{
338+
{Name: "server", Generation: int64(1)},
339+
{Name: "logging", Generation: int64(2)},
340+
}))
341+
})).Should(Succeed())
342+
343+
instKey := types.NamespacedName{Namespace: itsObj.Namespace, Name: podName(0)}
344+
By("check the instance spec synced")
345+
Eventually(testapps.CheckObj(&testCtx, instKey, func(g Gomega, inst *workloads.Instance) {
346+
g.Expect(inst.Spec.Configs).Should(HaveLen(2))
347+
g.Expect(inst.Spec.Configs[1].Generation).Should(BeEquivalentTo(2))
348+
})).Should(Succeed())
349+
350+
By("update configs")
351+
Expect(testapps.GetAndChangeObj(&testCtx, itsKey, func(its *workloads.InstanceSet) {
352+
its.Spec.Configs[1].Generation = 128
353+
its.Spec.Configs[1].Reconfigure = testapps.NewLifecycleAction("reconfigure")
354+
its.Spec.Configs[1].ReconfigureActionName = ""
355+
its.Spec.Configs[1].Parameters = map[string]string{"foo": "bar"}
356+
})()).ShouldNot(HaveOccurred())
357+
358+
By("check the instance spec updated")
359+
Eventually(testapps.CheckObj(&testCtx, instKey, func(g Gomega, inst *workloads.Instance) {
360+
g.Expect(inst.Spec.Configs).Should(HaveLen(2))
361+
g.Expect(inst.Spec.Configs[1].Generation).Should(BeEquivalentTo(128))
362+
g.Expect(inst.Status.Configs).Should(Equal([]workloads.InstanceConfigStatus{
363+
{Name: "server", Generation: int64(1)},
364+
{Name: "logging", Generation: int64(128)},
365+
}))
366+
})).Should(Succeed())
367+
368+
By("check the its status updated")
369+
Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) {
370+
g.Expect(its.Status.InstanceStatus).Should(HaveLen(1))
371+
g.Expect(its.Status.InstanceStatus[0].Configs).Should(Equal([]workloads.InstanceConfigStatus{
372+
{Name: "server", Generation: int64(1)},
373+
{Name: "logging", Generation: int64(128)},
374+
}))
375+
})).Should(Succeed())
376+
377+
By("check the reconfigure action call")
378+
Eventually(func(g Gomega) {
379+
g.Expect(strings.ToLower(reconfigure)).Should(Equal("reconfigure"))
380+
g.Expect(parameters).Should(HaveKeyWithValue("foo", "bar"))
381+
}).Should(Succeed())
382+
})
383+
289384
It("scale-in", func() {
290385
createITSObj(itsName)
291386

0 commit comments

Comments
 (0)