Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Minimal MachineHealthCheck Reconciler skeleton #2101

Merged

Conversation

JoelSpeed
Copy link
Contributor

Note: This PR is currently containing the commits #2049 and is blocked on that. I've separated the two so that the new controller and functionality can be reviewed in smaller chunks. If reviewing, ignore anything outside of the controllers folder.

What this PR does / why we need it:

This adds the controller structure for the Machine HealthChecking controller. It is not currently registered in main.go so will not be active even after this is merged, that will be done once all business logic is implemented.

So far, all that this does is setup the controller, fetch the instance, check the cluster it refers to exists and isn't paused and labels the MachineHealthCheck with the cluster name as per the other types within v1alpha3.

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Skeleton reconcile logic from tracking issue #1990

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jan 20, 2020
@k8s-ci-robot k8s-ci-robot requested review from chuckha and ncdc January 20, 2020 11:42
@JoelSpeed
Copy link
Contributor Author

/hold

#2049 Should be merged before this, I will rebase once that is done

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 20, 2020
@vincepri
Copy link
Member

@JoelSpeed Can you please merge the two PRs so they can be reviewed together?

@JoelSpeed
Copy link
Contributor Author

@vincepri I assumed it would be easier to review if it were two separate PRs, reviewing the first before merging the second?

If you'd rather review them together, then this PR contains all commits from the previous one, so I could close the previous in favour of this? (Though I noticed my last commit needs a fixup)

@vincepri
Copy link
Member

Closing the other one seems fine to me, let's keep the commits separate until we're ready to merge the PR in, usually we require to squash at the end.

@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from 91ac792 to 730bca2 Compare January 22, 2020 10:11
@JoelSpeed
Copy link
Contributor Author

/unhold

Ready for review whenever people have time

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 22, 2020
@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from 730bca2 to 57a637c Compare January 24, 2020 10:51
@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jan 24, 2020
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Jan 28, 2020
@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from 8f46a38 to 19cac02 Compare January 28, 2020 11:08
api/v1alpha3/machinehealthcheck_types.go Outdated Show resolved Hide resolved
api/v1alpha3/machinehealthcheck_types.go Outdated Show resolved Hide resolved
api/v1alpha3/machinehealthcheck_webhook_test.go Outdated Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
Comment on lines 38 to 50
By("Ensuring the namespace exists")
if err := k8sClient.Get(ctx, client.ObjectKey{Name: namespace.GetName()}, namespace.DeepCopy()); apierrors.IsNotFound(err) {
Expect(k8sClient.Create(ctx, namespace.DeepCopy())).To(Succeed())
}
By("Creating the Cluster")
Expect(k8sClient.Create(ctx, testCluster.DeepCopy())).To(Succeed())
})

AfterEach(func() {
By("Deleting any MachineHealthChecks")
Expect(cleanupTestMachineHealthChecks(ctx, k8sClient)).To(Succeed())
By("Deleting the Cluster")
Expect(k8sClient.Delete(ctx, testCluster.DeepCopy())).To(Succeed())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why all the DeepCopy() calls?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to avoid modifying the namespace and testCluster variables so they would be clean for each test, and they would be populated correctly when Ginkgo is building it's test graph, but I've managed to refactor to avoid the deepcopy's

return err
}
for _, mhc := range mhcList.Items {
err = c.Delete(ctx, mhc.DeepCopy())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why DeepCopy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is because I needed a pointer and mhc is a range variable, I've declared a second variable in the scope and that works, don't know if that's better or not?

controllers/machinehealthcheck_controller_test.go Outdated Show resolved Hide resolved
Copy link
Contributor Author

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ncdc thanks for the review, I've addressed your feedback

api/v1alpha3/machinehealthcheck_webhook_test.go Outdated Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
Comment on lines 38 to 50
By("Ensuring the namespace exists")
if err := k8sClient.Get(ctx, client.ObjectKey{Name: namespace.GetName()}, namespace.DeepCopy()); apierrors.IsNotFound(err) {
Expect(k8sClient.Create(ctx, namespace.DeepCopy())).To(Succeed())
}
By("Creating the Cluster")
Expect(k8sClient.Create(ctx, testCluster.DeepCopy())).To(Succeed())
})

AfterEach(func() {
By("Deleting any MachineHealthChecks")
Expect(cleanupTestMachineHealthChecks(ctx, k8sClient)).To(Succeed())
By("Deleting the Cluster")
Expect(k8sClient.Delete(ctx, testCluster.DeepCopy())).To(Succeed())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to avoid modifying the namespace and testCluster variables so they would be clean for each test, and they would be populated correctly when Ginkgo is building it's test graph, but I've managed to refactor to avoid the deepcopy's

return err
}
for _, mhc := range mhcList.Items {
err = c.Delete(ctx, mhc.DeepCopy())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is because I needed a pointer and mhc is a range variable, I've declared a second variable in the scope and that works, don't know if that's better or not?

api/v1alpha3/machinehealthcheck_types.go Show resolved Hide resolved
api/v1alpha3/machinehealthcheck_types.go Show resolved Hide resolved
api/v1alpha3/machinehealthcheck_types.go Show resolved Hide resolved
api/v1alpha3/machinehealthcheck_types.go Outdated Show resolved Hide resolved
api/v1alpha3/machinehealthcheck_types.go Outdated Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Show resolved Hide resolved
api/v1alpha3/machinehealthcheck_webhook.go Show resolved Hide resolved
@ncdc ncdc added this to the v0.3.0 milestone Jan 28, 2020
@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch 3 times, most recently from a89504f to 93400e3 Compare January 29, 2020 14:22
}

// PopulateDefaultsMachineHealthCheck fills in default field values.
func PopulateDefaultsMachineHealthCheck(m *MachineHealthCheck) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete this function and move its contents into Default() above.


// PopulateDefaultsMachineHealthCheck fills in default field values.
func PopulateDefaultsMachineHealthCheck(m *MachineHealthCheck) {
defaultMaxUnhealthy := intstr.FromString("100%")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do this inside the if check

func (m *MachineHealthCheck) ValidateUpdate(old runtime.Object) error {
mhc, ok := old.(*MachineHealthCheck)
if !ok {
return fmt.Errorf("expected a MachineHealthCheck but got a %T", old)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return apierrors.NewInvalid(...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump

)

const (
mhcClusterNameIndex = "mhcClusterNameIndex"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mhcClusterNameIndex = "mhcClusterNameIndex"
mhcClusterNameIndex = "spec.clusterName"

controllers/machinehealthcheck_controller.go Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
Scheme: scheme.Scheme,
MetricsBindAddress: "0",
NewCache: func(config *rest.Config, opts cache.Options) (cache.Cache, error) {
syncPeriod := 1 * time.Second
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the motivation for having a sync period?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I copied the manager set up over from suite_test assuming there was some good reason for it 😅 I don't think it will make a difference to these tests and will get rid of it

@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from 93623f0 to 7e354eb Compare January 31, 2020 13:32
Copy link
Contributor Author

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ncdc I've fixed up all of your suggestions :)

Scheme: scheme.Scheme,
MetricsBindAddress: "0",
NewCache: func(config *rest.Config, opts cache.Options) (cache.Cache, error) {
syncPeriod := 1 * time.Second
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I copied the manager set up over from suite_test assuming there was some good reason for it 😅 I don't think it will make a difference to these tests and will get rid of it

func (m *MachineHealthCheck) ValidateUpdate(old runtime.Object) error {
mhc, ok := old.(*MachineHealthCheck)
if !ok {
return fmt.Errorf("expected a MachineHealthCheck but got a %T", old)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump

)

const (
mhcClusterNameIndex = "spec.ClusterName"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mhcClusterNameIndex = "spec.ClusterName"
mhcClusterNameIndex = "spec.clusterName"

controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
controllers/machinehealthcheck_controller.go Outdated Show resolved Hide resolved
@ncdc
Copy link
Contributor

ncdc commented Jan 31, 2020

I think I just have 2 small outstanding items and then I say we merge & iterate in future PRs

@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from 7e354eb to 10a7dc1 Compare January 31, 2020 16:54
@JoelSpeed
Copy link
Contributor Author

@ncdc Apologies, I somehow missed commiting what I had done on the apierrors.NewInvalid(...), I'm not sure I've done it right though, can you advise?

mhc, ok := old.(*MachineHealthCheck)
if !ok {
err := field.Invalid(&field.Path{}, old, fmt.Sprintf("expected a MachineHealthCheck but got a %T", old))
return apierrors.NewInvalid(GroupVersion.WithKind("MachineHealthCheck").GroupKind(), "", field.ErrorList{err})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah... maybe we should use NewBadRequest(reason) instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is much cleaner! Fixed

// clusterToMachineHealthCheck maps events from Cluster objects to
// MachineHealthCheck objects that belong to the Cluster
func (r *MachineHealthCheckReconciler) clusterToMachineHealthCheck(o handler.MapObject) []reconcile.Request {
m, ok := o.Object.(*clusterv1.Cluster)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: replace m with c

@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from ac1954c to 1b7bfbb Compare February 3, 2020 11:04
@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from 1b7bfbb to c5634e9 Compare February 3, 2020 16:41
@ncdc
Copy link
Contributor

ncdc commented Feb 3, 2020

LGTM, please squash!!!

@JoelSpeed
Copy link
Contributor Author

Should I do one commit for the types and another for the reconciler or just all in one?

@ncdc
Copy link
Contributor

ncdc commented Feb 3, 2020

I'm fine with 1 commit

@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from c5634e9 to 5a8da83 Compare February 3, 2020 16:49
@JoelSpeed
Copy link
Contributor Author

Great, squashed :)

@ncdc
Copy link
Contributor

ncdc commented Feb 3, 2020

/lgtm

🎉🎉🎉🎉

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 3, 2020
func (r *MachineHealthCheckReconciler) clusterToMachineHealthCheck(o handler.MapObject) []reconcile.Request {
c, ok := o.Object.(*clusterv1.Cluster)
if !ok {
r.Log.Error(errors.New("incorrect type"), "expected a MachineHealthCheck", "type", fmt.Sprintf("%T", o))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ncdc Sorry, I just realised I've made a typo here, will fix-up and re-push

Suggested change
r.Log.Error(errors.New("incorrect type"), "expected a MachineHealthCheck", "type", fmt.Sprintf("%T", o))
r.Log.Error(errors.New("incorrect type"), "expected a Cluster", "type", fmt.Sprintf("%T", o))

@JoelSpeed JoelSpeed force-pushed the machinehealthcheck-reconcile branch from 5a8da83 to 6ad9dfa Compare February 3, 2020 17:06
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 3, 2020
@ncdc
Copy link
Contributor

ncdc commented Feb 3, 2020

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 3, 2020
@k8s-ci-robot k8s-ci-robot merged commit 8fb847f into kubernetes-sigs:master Feb 3, 2020
@JoelSpeed JoelSpeed deleted the machinehealthcheck-reconcile branch May 5, 2020 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants