Skip to content

Commit

Permalink
Separate RabbitmqClusterStatus from rabbitmqcluster_types.go
Browse files Browse the repository at this point in the history
  • Loading branch information
ChunyiLyu committed Jan 26, 2021
1 parent c420661 commit a5bc602
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 89 deletions.
94 changes: 94 additions & 0 deletions api/v1beta1/rabbitmqcluster_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package v1beta1

import (
"github.com/rabbitmq/cluster-operator/internal/status"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// Status presents the observed state of RabbitmqCluster
type RabbitmqClusterStatus struct {
// Unused.
ClusterStatus string `json:"clusterStatus,omitempty"`
// Set of Conditions describing the current state of the RabbitmqCluster
Conditions []status.RabbitmqClusterCondition `json:"conditions"`

// Identifying information on internal resources
DefaultUser *RabbitmqClusterDefaultUser `json:"defaultUser,omitempty"`
}

// Contains references to resources created with the RabbitmqCluster resource.
type RabbitmqClusterDefaultUser struct {
// Reference to the Kubernetes Secret containing the credentials of the default
// user.
SecretReference *RabbitmqClusterSecretReference `json:"secretReference,omitempty"`
// Reference to the Kubernetes Service serving the cluster.
ServiceReference *RabbitmqClusterServiceReference `json:"serviceReference,omitempty"`
}

// Reference to the Kubernetes Secret containing the credentials of the default user.
type RabbitmqClusterSecretReference struct {
// Name of the Secret containing the default user credentials
Name string `json:"name"`
// Namespace of the Secret containing the default user credentials
Namespace string `json:"namespace"`
// Key-value pairs in the Secret corresponding to `username` and `password`
Keys map[string]string `json:"keys"`
}

// Reference to the Kubernetes Service serving the cluster.
type RabbitmqClusterServiceReference struct {
// Name of the Service serving the cluster
Name string `json:"name"`
// Namespace of the Service serving the cluster
Namespace string `json:"namespace"`
}

func (clusterStatus *RabbitmqClusterStatus) SetConditions(resources []runtime.Object) {
var oldAllPodsReadyCondition *status.RabbitmqClusterCondition
var oldClusterAvailableCondition *status.RabbitmqClusterCondition
var oldNoWarningsCondition *status.RabbitmqClusterCondition
var oldReconcileCondition *status.RabbitmqClusterCondition

for _, condition := range clusterStatus.Conditions {
switch condition.Type {
case status.AllReplicasReady:
oldAllPodsReadyCondition = condition.DeepCopy()
case status.ClusterAvailable:
oldClusterAvailableCondition = condition.DeepCopy()
case status.NoWarnings:
oldNoWarningsCondition = condition.DeepCopy()
case status.ReconcileSuccess:
oldReconcileCondition = condition.DeepCopy()
}
}

allReplicasReadyCond := status.AllReplicasReadyCondition(resources, oldAllPodsReadyCondition)
clusterAvailableCond := status.ClusterAvailableCondition(resources, oldClusterAvailableCondition)
noWarningsCond := status.NoWarningsCondition(resources, oldNoWarningsCondition)

var reconciledCondition status.RabbitmqClusterCondition
if oldReconcileCondition != nil {
reconciledCondition = *oldReconcileCondition
} else {
reconciledCondition = status.ReconcileSuccessCondition(corev1.ConditionUnknown, "Initialising", "")
}

clusterStatus.Conditions = []status.RabbitmqClusterCondition{
allReplicasReadyCond,
clusterAvailableCond,
noWarningsCond,
reconciledCondition,
}
}

func (clusterStatus *RabbitmqClusterStatus) SetCondition(condType status.RabbitmqClusterConditionType,
condStatus corev1.ConditionStatus, reason string, messages ...string) {
for i := range clusterStatus.Conditions {
if clusterStatus.Conditions[i].Type == condType {
clusterStatus.Conditions[i].UpdateState(condStatus)
clusterStatus.Conditions[i].UpdateReason(reason, messages...)
break
}
}
}
86 changes: 86 additions & 0 deletions api/v1beta1/rabbitmqcluster_status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package v1beta1

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/rabbitmq/cluster-operator/internal/status"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

var _ = Describe("RabbitmqClusterStatus", func() {
It("sets conditions based on inputs", func() {
rabbitmqClusterStatus := RabbitmqClusterStatus{}
sts := &appsv1.StatefulSet{}
sts.Spec.Template.Spec.Containers = []corev1.Container{
{
Resources: corev1.ResourceRequirements{
Limits: map[corev1.ResourceName]resource.Quantity{
"memory": resource.MustParse("100Mi"),
},
Requests: map[corev1.ResourceName]resource.Quantity{
"memory": resource.MustParse("100Mi"),
},
},
},
}

sts.Status = appsv1.StatefulSetStatus{
ObservedGeneration: 0,
Replicas: 0,
ReadyReplicas: 3,
CurrentReplicas: 0,
UpdatedReplicas: 0,
CurrentRevision: "",
UpdateRevision: "",
CollisionCount: nil,
Conditions: nil,
}

endPoints := &corev1.Endpoints{
Subsets: []corev1.EndpointSubset{
{
Addresses: []corev1.EndpointAddress{
{
IP: "127.0.0.1",
},
},
},
},
}

rabbitmqClusterStatus.SetConditions([]runtime.Object{sts, endPoints})

Expect(rabbitmqClusterStatus.Conditions).To(HaveLen(4))
Expect(rabbitmqClusterStatus.Conditions[0].Type).To(Equal(status.AllReplicasReady))
Expect(rabbitmqClusterStatus.Conditions[1].Type).To(Equal(status.ClusterAvailable))
Expect(rabbitmqClusterStatus.Conditions[2].Type).To(Equal(status.NoWarnings))
Expect(rabbitmqClusterStatus.Conditions[3].Type).To(Equal(status.ReconcileSuccess))
})

It("updates an arbitrary condition", func() {
someCondition := status.RabbitmqClusterCondition{}
someCondition.Type = "a-type"
someCondition.Reason = "whynot"
someCondition.Status = "perhaps"
someCondition.LastTransitionTime = metav1.Unix(10, 0)
rmqStatus := RabbitmqClusterStatus{
Conditions: []status.RabbitmqClusterCondition{someCondition},
}

rmqStatus.SetCondition("a-type",
corev1.ConditionTrue, "some-reason", "my-message")

updatedCondition := rmqStatus.Conditions[0]
Expect(updatedCondition.Status).To(Equal(corev1.ConditionTrue))
Expect(updatedCondition.Reason).To(Equal("some-reason"))
Expect(updatedCondition.Message).To(Equal("my-message"))

notExpectedTime := metav1.Unix(10, 0)
Expect(updatedCondition.LastTransitionTime).NotTo(Equal(notExpectedTime))
Expect(updatedCondition.LastTransitionTime.Before(&notExpectedTime)).To(BeFalse())
})
})
89 changes: 0 additions & 89 deletions api/v1beta1/rabbitmqcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ import (

appsv1 "k8s.io/api/apps/v1"

"github.com/rabbitmq/cluster-operator/internal/status"
corev1 "k8s.io/api/core/v1"
k8sresource "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// +kubebuilder:object:root=true
Expand Down Expand Up @@ -321,44 +319,6 @@ type RabbitmqClusterServiceSpec struct {
Annotations map[string]string `json:"annotations,omitempty"`
}

// Status presents the observed state of RabbitmqCluster
type RabbitmqClusterStatus struct {
// Unused.
ClusterStatus string `json:"clusterStatus,omitempty"`
// Set of Conditions describing the current state of the RabbitmqCluster
Conditions []status.RabbitmqClusterCondition `json:"conditions"`

// Identifying information on internal resources
DefaultUser *RabbitmqClusterDefaultUser `json:"defaultUser,omitempty"`
}

// Contains references to resources created with the RabbitmqCluster resource.
type RabbitmqClusterDefaultUser struct {
// Reference to the Kubernetes Secret containing the credentials of the default
// user.
SecretReference *RabbitmqClusterSecretReference `json:"secretReference,omitempty"`
// Reference to the Kubernetes Service serving the cluster.
ServiceReference *RabbitmqClusterServiceReference `json:"serviceReference,omitempty"`
}

// Reference to the Kubernetes Secret containing the credentials of the default user.
type RabbitmqClusterSecretReference struct {
// Name of the Secret containing the default user credentials
Name string `json:"name"`
// Namespace of the Secret containing the default user credentials
Namespace string `json:"namespace"`
// Key-value pairs in the Secret corresponding to `username` and `password`
Keys map[string]string `json:"keys"`
}

// Reference to the Kubernetes Service serving the cluster.
type RabbitmqClusterServiceReference struct {
// Name of the Service serving the cluster
Name string `json:"name"`
// Namespace of the Service serving the cluster
Namespace string `json:"namespace"`
}

func (cluster *RabbitmqCluster) TLSEnabled() bool {
return cluster.Spec.TLS.SecretName != ""
}
Expand Down Expand Up @@ -388,55 +348,6 @@ func (cluster *RabbitmqCluster) AdditionalPluginEnabled(plugin Plugin) bool {
return false
}

func (clusterStatus *RabbitmqClusterStatus) SetConditions(resources []runtime.Object) {
var oldAllPodsReadyCondition *status.RabbitmqClusterCondition
var oldClusterAvailableCondition *status.RabbitmqClusterCondition
var oldNoWarningsCondition *status.RabbitmqClusterCondition
var oldReconcileCondition *status.RabbitmqClusterCondition

for _, condition := range clusterStatus.Conditions {
switch condition.Type {
case status.AllReplicasReady:
oldAllPodsReadyCondition = condition.DeepCopy()
case status.ClusterAvailable:
oldClusterAvailableCondition = condition.DeepCopy()
case status.NoWarnings:
oldNoWarningsCondition = condition.DeepCopy()
case status.ReconcileSuccess:
oldReconcileCondition = condition.DeepCopy()
}
}

allReplicasReadyCond := status.AllReplicasReadyCondition(resources, oldAllPodsReadyCondition)
clusterAvailableCond := status.ClusterAvailableCondition(resources, oldClusterAvailableCondition)
noWarningsCond := status.NoWarningsCondition(resources, oldNoWarningsCondition)

var reconciledCondition status.RabbitmqClusterCondition
if oldReconcileCondition != nil {
reconciledCondition = *oldReconcileCondition
} else {
reconciledCondition = status.ReconcileSuccessCondition(corev1.ConditionUnknown, "Initialising", "")
}

clusterStatus.Conditions = []status.RabbitmqClusterCondition{
allReplicasReadyCond,
clusterAvailableCond,
noWarningsCond,
reconciledCondition,
}
}

func (clusterStatus *RabbitmqClusterStatus) SetCondition(condType status.RabbitmqClusterConditionType,
condStatus corev1.ConditionStatus, reason string, messages ...string) {
for i := range clusterStatus.Conditions {
if clusterStatus.Conditions[i].Type == condType {
clusterStatus.Conditions[i].UpdateState(condStatus)
clusterStatus.Conditions[i].UpdateReason(reason, messages...)
break
}
}
}

// +kubebuilder:object:root=true

// RabbitmqClusterList contains a list of RabbitmqClusters.
Expand Down

0 comments on commit a5bc602

Please sign in to comment.