Skip to content

Commit b1444af

Browse files
authored
Merge pull request #3606 from Nordix/mhc-external-remediation-jan
✨ MachineHealthCheck now supports external remediation templates
2 parents e51e27e + 83bf1a0 commit b1444af

9 files changed

+630
-3
lines changed

api/v1alpha2/conversion.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ func (src *Machine) ConvertTo(dstRaw conversion.Hub) error {
119119
restoreMachineSpec(&restored.Spec, &dst.Spec)
120120
dst.Status.ObservedGeneration = restored.Status.ObservedGeneration
121121
dst.Status.Conditions = restored.Status.Conditions
122-
123122
return nil
124123
}
125124

api/v1alpha3/condition_consts.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,18 @@ const (
126126

127127
// WaitingForRemediationReason is the reason used when a machine fails a health check and remediation is needed.
128128
WaitingForRemediationReason = "WaitingForRemediation"
129+
130+
// ExternalRemediationTemplateAvailable is set on machinehealthchecks when MachineHealthCheck controller uses external remediation.
131+
// ExternalRemediationTemplateAvailable is set to false if external remediation template is not found.
132+
ExternalRemediationTemplateAvailable ConditionType = "ExternalRemediationTemplateAvailable"
133+
134+
// ExternalRemediationTemplateNotFound is the reason used when a machine health check fails to find external remediation template.
135+
ExternalRemediationTemplateNotFound = "ExternalRemediationTemplateNotFound"
136+
137+
// ExternalRemediationRequestAvailable is set on machinehealthchecks when MachineHealthCheck controller uses external remediation.
138+
// ExternalRemediationRequestAvailable is set to false if creating external remediation request fails.
139+
ExternalRemediationRequestAvailable ConditionType = "ExternalRemediationRequestAvailable"
140+
141+
// ExternalRemediationRequestCreationFailed is the reason used when a machine health check fails to create external remediation request.
142+
ExternalRemediationRequestCreationFailed = "ExternalRemediationRequestCreationFailed"
129143
)

api/v1alpha3/machinehealthcheck_types.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ type MachineHealthCheckSpec struct {
4949
// failed and will be remediated.
5050
// +optional
5151
NodeStartupTimeout *metav1.Duration `json:"nodeStartupTimeout,omitempty"`
52+
53+
// RemediationTemplate is a reference to a remediation template
54+
// provided by an infrastructure provider.
55+
//
56+
// This field is completely optional, when filled, the MachineHealthCheck controller
57+
// creates a new object from the template referenced and hands off remediation of the machine to
58+
// a controller that lives outside of Cluster API.
59+
// +optional
60+
RemediationTemplate *corev1.ObjectReference `json:"remediationTemplate,omitempty"`
5261
}
5362

5463
// ANCHOR_END: MachineHealthCHeckSpec
@@ -91,6 +100,10 @@ type MachineHealthCheckStatus struct {
91100
// Targets shows the current list of machines the machine health check is watching
92101
// +optional
93102
Targets []string `json:"targets,omitempty"`
103+
104+
// Conditions defines current service state of the MachineHealthCheck.
105+
// +optional
106+
Conditions Conditions `json:"conditions,omitempty"`
94107
}
95108

96109
// ANCHOR_END: MachineHealthCheckStatus
@@ -115,6 +128,14 @@ type MachineHealthCheck struct {
115128
Status MachineHealthCheckStatus `json:"status,omitempty"`
116129
}
117130

131+
func (m *MachineHealthCheck) GetConditions() Conditions {
132+
return m.Status.Conditions
133+
}
134+
135+
func (m *MachineHealthCheck) SetConditions(conditions Conditions) {
136+
m.Status.Conditions = conditions
137+
}
138+
118139
// +kubebuilder:object:root=true
119140

120141
// MachineHealthCheckList contains a list of MachineHealthCheck

api/v1alpha3/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/cluster.x-k8s.io_machinehealthchecks.yaml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,47 @@ spec:
7171
description: Machines older than this duration without a node will
7272
be considered to have failed and will be remediated.
7373
type: string
74+
remediationTemplate:
75+
description: "RemediationTemplate is a reference to a remediation
76+
template provided by an infrastructure provider. \n This field is
77+
completely optional, when filled, the MachineHealthCheck controller
78+
creates a new object from the template referenced and hands off
79+
remediation of the machine to a controller that lives outside of
80+
Cluster API."
81+
properties:
82+
apiVersion:
83+
description: API version of the referent.
84+
type: string
85+
fieldPath:
86+
description: 'If referring to a piece of an object instead of
87+
an entire object, this string should contain a valid JSON/Go
88+
field access statement, such as desiredState.manifest.containers[2].
89+
For example, if the object reference is to a container within
90+
a pod, this would take on a value like: "spec.containers{name}"
91+
(where "name" refers to the name of the container that triggered
92+
the event) or if no container name is specified "spec.containers[2]"
93+
(container with index 2 in this pod). This syntax is chosen
94+
only to have some well-defined way of referencing a part of
95+
an object. TODO: this design is not final and this field is
96+
subject to change in the future.'
97+
type: string
98+
kind:
99+
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
100+
type: string
101+
name:
102+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
103+
type: string
104+
namespace:
105+
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
106+
type: string
107+
resourceVersion:
108+
description: 'Specific resourceVersion to which this reference
109+
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
110+
type: string
111+
uid:
112+
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
113+
type: string
114+
type: object
74115
selector:
75116
description: Label selector to match machines whose health will be
76117
exercised
@@ -150,6 +191,50 @@ spec:
150191
status:
151192
description: Most recently observed status of MachineHealthCheck resource
152193
properties:
194+
conditions:
195+
description: Conditions defines current service state of the MachineHealthCheck.
196+
items:
197+
description: Condition defines an observation of a Cluster API resource
198+
operational state.
199+
properties:
200+
lastTransitionTime:
201+
description: Last time the condition transitioned from one status
202+
to another. This should be when the underlying condition changed.
203+
If that is not known, then using the time when the API field
204+
changed is acceptable.
205+
format: date-time
206+
type: string
207+
message:
208+
description: A human readable message indicating details about
209+
the transition. This field may be empty.
210+
type: string
211+
reason:
212+
description: The reason for the condition's last transition
213+
in CamelCase. The specific API may choose whether or not this
214+
field is considered a guaranteed API. This field may not be
215+
empty.
216+
type: string
217+
severity:
218+
description: Severity provides an explicit classification of
219+
Reason code, so the users or machines can immediately understand
220+
the current situation and act accordingly. The Severity field
221+
MUST be set only when Status=False.
222+
type: string
223+
status:
224+
description: Status of the condition, one of True, False, Unknown.
225+
type: string
226+
type:
227+
description: Type of condition in CamelCase or in foo.example.com/CamelCase.
228+
Many .condition.type values are consistent across resources
229+
like Available, but because arbitrary conditions can be useful
230+
(see .node.status.conditions), the ability to deconflict is
231+
important.
232+
type: string
233+
required:
234+
- status
235+
- type
236+
type: object
237+
type: array
153238
currentHealthy:
154239
description: total number of healthy machines counted by this machine
155240
health check

controllers/external/testing.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,96 @@ var (
207207
},
208208
},
209209
}
210+
211+
TestGenericInfrastructureRemediationCRD = &apiextensionsv1.CustomResourceDefinition{
212+
TypeMeta: metav1.TypeMeta{
213+
APIVersion: apiextensionsv1.SchemeGroupVersion.String(),
214+
Kind: "CustomResourceDefinition",
215+
},
216+
ObjectMeta: metav1.ObjectMeta{
217+
Name: "infrastructureremediations.infrastructure.cluster.x-k8s.io",
218+
Labels: map[string]string{
219+
clusterv1.GroupVersion.String(): "v1alpha3",
220+
},
221+
},
222+
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
223+
Group: "infrastructure.cluster.x-k8s.io",
224+
Scope: apiextensionsv1.NamespaceScoped,
225+
Names: apiextensionsv1.CustomResourceDefinitionNames{
226+
Kind: "InfrastructureRemediation",
227+
Plural: "infrastructureremediations",
228+
},
229+
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
230+
{
231+
Name: "v1alpha3",
232+
Served: true,
233+
Storage: true,
234+
Subresources: &apiextensionsv1.CustomResourceSubresources{
235+
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
236+
},
237+
Schema: &apiextensionsv1.CustomResourceValidation{
238+
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
239+
Type: "object",
240+
Properties: map[string]apiextensionsv1.JSONSchemaProps{
241+
"spec": {
242+
Type: "object",
243+
XPreserveUnknownFields: pointer.BoolPtr(true),
244+
},
245+
"status": {
246+
Type: "object",
247+
XPreserveUnknownFields: pointer.BoolPtr(true),
248+
},
249+
},
250+
},
251+
},
252+
},
253+
},
254+
},
255+
}
256+
257+
TestGenericInfrastructureRemediationTemplateCRD = &apiextensionsv1.CustomResourceDefinition{
258+
TypeMeta: metav1.TypeMeta{
259+
APIVersion: apiextensionsv1.SchemeGroupVersion.String(),
260+
Kind: "CustomResourceDefinition",
261+
},
262+
ObjectMeta: metav1.ObjectMeta{
263+
Name: "infrastructureremediationtemplates.infrastructure.cluster.x-k8s.io",
264+
Labels: map[string]string{
265+
clusterv1.GroupVersion.String(): "v1alpha3",
266+
},
267+
},
268+
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
269+
Group: "infrastructure.cluster.x-k8s.io",
270+
Scope: apiextensionsv1.NamespaceScoped,
271+
Names: apiextensionsv1.CustomResourceDefinitionNames{
272+
Kind: "InfrastructureRemediationTemplate",
273+
Plural: "infrastructureremediationtemplates",
274+
},
275+
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
276+
{
277+
Name: "v1alpha3",
278+
Served: true,
279+
Storage: true,
280+
Subresources: &apiextensionsv1.CustomResourceSubresources{
281+
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
282+
},
283+
Schema: &apiextensionsv1.CustomResourceValidation{
284+
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
285+
Type: "object",
286+
Properties: map[string]apiextensionsv1.JSONSchemaProps{
287+
"spec": {
288+
Type: "object",
289+
XPreserveUnknownFields: pointer.BoolPtr(true),
290+
},
291+
"status": {
292+
Type: "object",
293+
XPreserveUnknownFields: pointer.BoolPtr(true),
294+
},
295+
},
296+
},
297+
},
298+
},
299+
},
300+
},
301+
}
210302
)

0 commit comments

Comments
 (0)