Skip to content

Commit

Permalink
chore: update describe for status field
Browse files Browse the repository at this point in the history
  • Loading branch information
Rory-Z committed Aug 31, 2022
1 parent 09516de commit 81f8bb1
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 92 deletions.
51 changes: 31 additions & 20 deletions apis/apps/v2alpha1/emqx_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,35 +110,44 @@ const (
)

type Condition struct {
Type ConditionType `json:"type"`
Status corev1.ConditionStatus `json:"status"`
LastUpdateTime string `json:"lastUpdateTime,omitempty"`
LastUpdateAt metav1.Time `json:"-"`
LastTransitionTime string `json:"lastTransitionTime,omitempty"`
// Status of cluster condition.
Type ConditionType `json:"type"`
// Status of the condition, one of True, False, Unknown.
Status corev1.ConditionStatus `json:"status"`
// The reason for the condition's last transition.
Reason string `json:"reason,omitempty"`
// A human readable message indicating details about the transition.
Message string `json:"message,omitempty"`
// Last time the condition transitioned from one status to another.
LastTransitionTime string `json:"lastTransitionTime,omitempty"`
// The last time this condition was updated.
LastUpdateTime string `json:"lastUpdateTime,omitempty"`
LastUpdateAt metav1.Time `json:"-"`
}

type EMQXNodeStatus struct {
Node string `json:"node,omitempty"`
type EmqxNode struct {
// EMQX node name, example: [email protected]
Node string `json:"node,omitempty"`
// EMQX node status, example: Running
NodeStatus string `json:"node_status,omitempty"`
// Erlang/OTP version used by EMQX, example: 24.2/12.2
OTPRelease string `json:"otp_release,omitempty"`
Version string `json:"version,omitempty"`
Role string `json:"role,omitempty"`
// EMQX version
Version string `json:"version,omitempty"`
// EMQX cluster node role
Role string `json:"role,omitempty"`
}

// EMQXStatus defines the observed state of EMQX
type EMQXStatus struct {
CurrentImage string `json:"currentImage,omitempty"`
OriginalImage string `json:"originalImage,omitempty"`
CoreReplicas int32 `json:"coreReplicas,omitempty"`
ReadyCoreReplicas int32 `json:"readyCoreReplicas,omitempty"`
ReplicantReplicas int32 `json:"replicantReplicas,omitempty"`
ReadyReplicantReplicas int32 `json:"readyReplicantReplicas,omitempty"`
NodeStatuses []EMQXNodeStatus `json:"nodes,omitempty"`
Conditions []Condition `json:"conditions,omitempty"`
CurrentImage string `json:"currentImage,omitempty"`
OriginalImage string `json:"originalImage,omitempty"`
CoreReplicas int32 `json:"coreReplicas,omitempty"`
ReadyCoreReplicas int32 `json:"readyCoreReplicas,omitempty"`
ReplicantReplicas int32 `json:"replicantReplicas,omitempty"`
ReadyReplicantReplicas int32 `json:"readyReplicantReplicas,omitempty"`
EmqxNodes []EmqxNode `json:"emqxNodes,omitempty"`
Conditions []Condition `json:"conditions,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down Expand Up @@ -192,9 +201,11 @@ func (s *EMQXStatus) IsCoreUpdating() bool {
}

func (s *EMQXStatus) IsRunning() bool {
cond := s.Conditions[0]
if cond.Type == ClusterRunning && cond.Status == corev1.ConditionTrue {
return true
if len(s.Conditions) > 0 {
cond := s.Conditions[0]
if cond.Type == ClusterRunning && cond.Status == corev1.ConditionTrue {
return true
}
}
return false
}
Expand Down
36 changes: 18 additions & 18 deletions apis/apps/v2alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion config/crd/bases/apps.emqx.io_emqxes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13199,8 +13199,11 @@ spec:
items:
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status
to another.
type: string
lastUpdateTime:
description: The last time this condition was updated.
type: string
message:
description: A human readable message indicating details about
Expand All @@ -13210,8 +13213,10 @@ spec:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Status of cluster condition.
type: string
required:
- status
Expand All @@ -13223,18 +13228,23 @@ spec:
type: integer
currentImage:
type: string
nodes:
emqxNodes:
items:
properties:
node:
description: 'EMQX node name, example: [email protected]'
type: string
node_status:
description: 'EMQX node status, example: Running'
type: string
otp_release:
description: 'Erlang/OTP version used by EMQX, example: 24.2/12.2'
type: string
role:
description: EMQX cluster node role
type: string
version:
description: EMQX version
type: string
type: object
type: array
Expand Down
64 changes: 31 additions & 33 deletions controllers/apps/v2alpha1/emqx_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,78 +176,76 @@ func (r *EMQXReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
}
}

readyCoreReplicas := int32(0)
readyReplicantReplicas := int32(0)
nodeStatuses, err := r.getNodeStatuesByAPI(sts)
instance.Status.CoreReplicas = *instance.Spec.CoreTemplate.Spec.Replicas
if isExistReplicant(instance) {
instance.Status.ReplicantReplicas = *instance.Spec.ReplicantTemplate.Spec.Replicas
} else {
instance.Status.ReplicantReplicas = int32(0)
}
instance.Status.ReadyCoreReplicas = int32(0)
instance.Status.ReadyReplicantReplicas = int32(0)

emqxNodes, err := r.getNodeStatuesByAPI(sts)
if err != nil {
r.EventRecorder.Event(instance, corev1.EventTypeWarning, "FailedToGetNodeStatues", err.Error())
}
if nodeStatuses != nil {
instance.Status.NodeStatuses = nodeStatuses
if emqxNodes != nil {
instance.Status.EmqxNodes = emqxNodes

for _, node := range nodeStatuses {
for _, node := range emqxNodes {
if node.NodeStatus == "Running" {
if node.Role == "core" {
readyCoreReplicas++
instance.Status.ReadyCoreReplicas++
}
if node.Role == "replicant" {
readyReplicantReplicas++
instance.Status.ReadyReplicantReplicas++
}
}
}
}

instance.Status.CoreReplicas = *instance.Spec.CoreTemplate.Spec.Replicas
instance.Status.ReadyCoreReplicas = readyCoreReplicas
if isExistReplicant(instance) {
instance.Status.ReplicantReplicas = *instance.Spec.ReplicantTemplate.Spec.Replicas
instance.Status.ReadyReplicantReplicas = readyReplicantReplicas
}

switch instance.Status.Conditions[0].Type {
case appsv2alpha1.ClusterCoreUpdating:
if instance.Status.ReadyCoreReplicas == instance.Status.CoreReplicas {
instance.Status.OriginalImage = instance.Status.CurrentImage

var condition *appsv2alpha1.Condition
if isExistReplicant(instance) {
condition := appsv2alpha1.NewCondition(
condition = appsv2alpha1.NewCondition(
appsv2alpha1.ClusterReplicantUpdating,
corev1.ConditionTrue,
"ClusterReplicantUpdating",
"Updating replicant node in cluster",
)
instance.Status.SetCondition(*condition)
} else {
condition := appsv2alpha1.NewCondition(
condition = appsv2alpha1.NewCondition(
appsv2alpha1.ClusterRunning,
corev1.ConditionTrue,
"ClusterReady",
"All node are ready",
)
instance.Status.SetCondition(*condition)
}
}
case appsv2alpha1.ClusterRunning:
if instance.Status.CoreReplicas != instance.Status.ReadyCoreReplicas ||
instance.Status.ReadyCoreReplicas != instance.Status.ReadyReplicantReplicas {
condition := appsv2alpha1.NewCondition(
appsv2alpha1.ClusterRunning,
corev1.ConditionFalse,
"ClusterNotReady",
"Some node not ready",
)
instance.Status.SetCondition(*condition)
}
default:
var condition *appsv2alpha1.Condition
if instance.Status.CoreReplicas == instance.Status.ReadyCoreReplicas &&
instance.Status.ReplicantReplicas == instance.Status.ReadyReplicantReplicas {
condition := appsv2alpha1.NewCondition(
condition = appsv2alpha1.NewCondition(
appsv2alpha1.ClusterRunning,
corev1.ConditionTrue,
"ClusterReady",
"All node are ready",
)
instance.Status.SetCondition(*condition)
} else {
condition = appsv2alpha1.NewCondition(
appsv2alpha1.ClusterRunning,
corev1.ConditionFalse,
"ClusterNotReady",
"Some node not ready",
)
}
instance.Status.SetCondition(*condition)
}

// Check cluster status
Expand All @@ -265,7 +263,7 @@ func (r *EMQXReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}

func (r *EMQXReconciler) getNodeStatuesByAPI(obj client.Object) ([]appsv2alpha1.EMQXNodeStatus, error) {
func (r *EMQXReconciler) getNodeStatuesByAPI(obj client.Object) ([]appsv2alpha1.EmqxNode, error) {
resp, body, err := r.Handler.RequestAPI(obj, "GET", username, password, dashboardPort, "api/v5/nodes")
if err != nil {
return nil, fmt.Errorf("failed to get listeners: %v", err)
Expand All @@ -274,7 +272,7 @@ func (r *EMQXReconciler) getNodeStatuesByAPI(obj client.Object) ([]appsv2alpha1.
return nil, fmt.Errorf("failed to get listener, status : %s, body: %s", resp.Status, body)
}

nodeStatuses := []appsv2alpha1.EMQXNodeStatus{}
nodeStatuses := []appsv2alpha1.EmqxNode{}
if err := json.Unmarshal(body, &nodeStatuses); err != nil {
return nil, fmt.Errorf("failed to unmarshal node statuses: %v", err)
}
Expand Down
28 changes: 8 additions & 20 deletions e2e/v2alpha1/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,12 @@ var _ = Describe("E2E Test", func() {
Expect(k8sClient.Create(context.TODO(), instance)).Should(Succeed())
})
It("Check EMQX Status", func() {
Eventually(func() corev1.ConditionStatus {
Eventually(func() bool {
_ = k8sClient.Get(context.TODO(), types.NamespacedName{Name: "e2e-test", Namespace: "default"}, instance)
running := corev1.ConditionFalse
for _, c := range instance.Status.Conditions {
if c.Type == appsv2alpha1.ClusterRunning {
running = c.Status
}
}
return running
}, timeout, interval).Should(Equal(corev1.ConditionTrue))
return instance.Status.IsRunning()
}, timeout, interval).Should(BeTrue())

Expect(instance.Status.NodeStatuses).Should(HaveLen(3))
Expect(instance.Status.EmqxNodes).Should(HaveLen(3))
Expect(instance.Status.CoreReplicas).Should(Equal(int32(3)))
Expect(instance.Status.ReadyCoreReplicas).Should(Equal(int32(3)))
Expect(instance.Status.ReplicantReplicas).Should(Equal(int32(0)))
Expand Down Expand Up @@ -121,18 +115,12 @@ var _ = Describe("E2E Test", func() {
Expect(k8sClient.Create(context.TODO(), instance)).Should(Succeed())
})
It("Check EMQX Status", func() {
Eventually(func() corev1.ConditionStatus {
Eventually(func() bool {
_ = k8sClient.Get(context.TODO(), types.NamespacedName{Name: "e2e-test", Namespace: "default"}, instance)
running := corev1.ConditionFalse
for _, c := range instance.Status.Conditions {
if c.Type == appsv2alpha1.ClusterRunning {
running = c.Status
}
}
return running
}, timeout, interval).Should(Equal(corev1.ConditionTrue))
return instance.Status.IsRunning()
}, timeout, interval).Should(BeTrue())

Expect(instance.Status.NodeStatuses).Should(HaveLen(6))
Expect(instance.Status.EmqxNodes).Should(HaveLen(6))
Expect(instance.Status.CoreReplicas).Should(Equal(int32(3)))
Expect(instance.Status.ReadyCoreReplicas).Should(Equal(int32(3)))
Expect(instance.Status.ReplicantReplicas).Should(Equal(int32(3)))
Expand Down

0 comments on commit 81f8bb1

Please sign in to comment.