/
member_types.go
170 lines (144 loc) · 7.07 KB
/
member_types.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package v1
import (
"fmt"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// A ServiceMeshMember object marks the namespace in which it lives as a member
// of the Service Mesh Control Plane referenced in the object.
// The ServiceMeshMember object should be created in each application namespace
// that must be part of the service mesh and must be named "default".
//
// When the ServiceMeshMember object is created, it causes the namespace to be
// added to the ServiceMeshMemberRoll within the namespace of the
// ServiceMeshControlPlane object the ServiceMeshMember references.
//
// To reference a ServiceMeshControlPlane, the user creating the ServiceMeshMember
// object must have the "use" permission on the referenced ServiceMeshControlPlane
// object. This permission is given via the mesh-users RoleBinding (and mesh-user
// Role) in the namespace of the referenced ServiceMeshControlPlane object.
// +genclient
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:storageversion
// +kubebuilder:resource:shortName=smm,categories=maistra-io
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Control Plane",type="string",JSONPath=".status.annotations.controlPlaneRef",description="The ServiceMeshControlPlane this namespace belongs to"
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="Whether or not namespace is configured as a member of the mesh."
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the object"
type ServiceMeshMember struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// The desired state of this ServiceMeshMember.
// +kubebuilder:validation:Required
Spec ServiceMeshMemberSpec `json:"spec"`
// The current status of this ServiceMeshMember. This data may be out of
// date by some window of time.
// +optional
Status ServiceMeshMemberStatus `json:"status,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ServiceMeshMemberList contains a list of ServiceMeshMember objects
type ServiceMeshMemberList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ServiceMeshMember `json:"items"`
}
// ServiceMeshMemberSpec defines the member of the mesh
type ServiceMeshMemberSpec struct {
// A reference to the ServiceMeshControlPlane object.
ControlPlaneRef ServiceMeshControlPlaneRef `json:"controlPlaneRef"`
}
// ServiceMeshControlPlaneRef is a reference to a ServiceMeshControlPlane object
type ServiceMeshControlPlaneRef struct {
// The name of the referenced ServiceMeshControlPlane object.
Name string `json:"name"`
// The namespace of the referenced ServiceMeshControlPlane object.
Namespace string `json:"namespace"`
}
func (s ServiceMeshControlPlaneRef) String() string {
return fmt.Sprintf("%s%c%s", s.Namespace, '/', s.Name)
}
// ServiceMeshMemberStatus represents the current state of a ServiceMeshMember.
type ServiceMeshMemberStatus struct {
StatusBase `json:",inline"`
// The generation observed by the controller during the most recent
// reconciliation. The information in the status pertains to this particular
// generation of the object.
ObservedGeneration int64 `json:"observedGeneration"`
// The generation of the ServiceMeshControlPlane object observed by the
// controller during the most recent reconciliation of this
// ServiceMeshMember.
ServiceMeshGeneration int64 `json:"meshGeneration,omitempty"` // TODO: do we need this field at all?
// The reconciled version of the ServiceMeshControlPlane object observed by
// the controller during the most recent reconciliation of this
// ServiceMeshMember.
ServiceMeshReconciledVersion string `json:"meshReconciledVersion,omitempty"` // TODO: do we need this field at all?
// Represents the latest available observations of a ServiceMeshMember's
// current state.
Conditions []ServiceMeshMemberCondition `json:"conditions"`
}
// ServiceMeshMemberConditionType represents the type of the condition. Condition types are:
// Reconciled, NamespaceConfigured
type ServiceMeshMemberConditionType string
const (
// ConditionTypeReconciled signifies whether or not the controller has
// updated the ServiceMeshMemberRoll object based on this ServiceMeshMember.
ConditionTypeMemberReconciled ServiceMeshMemberConditionType = "Reconciled"
// ConditionTypeReady signifies whether the namespace has been configured
// to use the mesh
ConditionTypeMemberReady ServiceMeshMemberConditionType = "Ready" // TODO: remove the Ready condition in v2
)
type ServiceMeshMemberConditionReason string
const (
// ConditionReasonDeletionError ...
ConditionReasonMemberCannotCreateMemberRoll ServiceMeshMemberConditionReason = "CreateMemberRollFailed"
ConditionReasonMemberCannotUpdateMemberRoll ServiceMeshMemberConditionReason = "UpdateMemberRollFailed"
ConditionReasonMemberCannotDeleteMemberRoll ServiceMeshMemberConditionReason = "DeleteMemberRollFailed"
ConditionReasonMemberNamespaceNotExists ServiceMeshMemberConditionReason = "NamespaceNotExists"
ConditionReasonMemberReferencesDifferentControlPlane ServiceMeshMemberConditionReason = "ReferencesDifferentControlPlane"
ConditionReasonMemberTerminating ServiceMeshMemberConditionReason = "Terminating"
)
// Condition represents a specific condition on a resource
type ServiceMeshMemberCondition struct {
Type ServiceMeshMemberConditionType `json:"type,omitempty"`
Status core.ConditionStatus `json:"status,omitempty"`
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
Reason ServiceMeshMemberConditionReason `json:"reason,omitempty"`
Message string `json:"message,omitempty"`
}
// GetCondition removes a condition for the list of conditions
func (s *ServiceMeshMemberStatus) GetCondition(conditionType ServiceMeshMemberConditionType) ServiceMeshMemberCondition {
if s == nil {
return ServiceMeshMemberCondition{Type: conditionType, Status: core.ConditionUnknown}
}
for i := range s.Conditions {
if s.Conditions[i].Type == conditionType {
return s.Conditions[i]
}
}
return ServiceMeshMemberCondition{Type: conditionType, Status: core.ConditionUnknown}
}
// SetCondition sets a specific condition in the list of conditions
func (s *ServiceMeshMemberStatus) SetCondition(condition ServiceMeshMemberCondition) *ServiceMeshMemberStatus {
if s == nil {
return nil
}
now := metav1.Now()
for i := range s.Conditions {
if s.Conditions[i].Type == condition.Type {
if s.Conditions[i].Status != condition.Status {
condition.LastTransitionTime = now
} else {
condition.LastTransitionTime = s.Conditions[i].LastTransitionTime
}
s.Conditions[i] = condition
return s
}
}
// If the condition does not exist,
// initialize the lastTransitionTime
condition.LastTransitionTime = now
s.Conditions = append(s.Conditions, condition)
return s
}