Skip to content
This repository has been archived by the owner on Jun 29, 2022. It is now read-only.

Introduce platform.PostApplyHook interface and implement it for AKS cluster #886

Merged
merged 3 commits into from
Sep 2, 2020

Conversation

invidian
Copy link
Member

@invidian invidian commented Sep 1, 2020

See commit messages for the details.

Closes #855

Copy link
Member

@knrt10 knrt10 left a comment

Choose a reason for hiding this comment

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

Just a NIT, rest LGTM.

knrt10
knrt10 previously approved these changes Sep 1, 2020
Copy link
Member

@knrt10 knrt10 left a comment

Choose a reason for hiding this comment

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

+1

Copy link
Contributor

@iaguis iaguis left a comment

Choose a reason for hiding this comment

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

Looks OK but I'd like to have @johananl's review before merging.

knrt10
knrt10 previously approved these changes Sep 1, 2020
@johananl
Copy link
Member

johananl commented Sep 1, 2020

I'm fine with this implementation for now if it solves the problem for us. Once we refactor the platform interface I think it could make more sense to have a method called PostApplyHook() (or even PostApplyHooks()?) on the platform interface which optionally returns the hook(s) to be executed. Doing so would make things more explicit compared to implementing another interface.

iaguis
iaguis previously approved these changes Sep 1, 2020
@invidian
Copy link
Member Author

invidian commented Sep 1, 2020

I'm fine with this implementation for now if it solves the problem for us. Once we refactor the platform interface I think it could make more sense to have a method called PostApplyHook() (or even PostApplyHooks()?) on the platform interface which optionally returns the hook(s) to be executed. Doing so would make things more explicit compared to implementing another interface.

Since the hook is optional, I think it's nice to have it separate, as it allows us to avoid adding boilerplate code to all platforms. This is not something every platform MUST implement, like e.g. generating Terraform code or Terraform plan (this could actually be optional too).

@johananl
Copy link
Member

johananl commented Sep 1, 2020

I'm fine with this implementation for now if it solves the problem for us. Once we refactor the platform interface I think it could make more sense to have a method called PostApplyHook() (or even PostApplyHooks()?) on the platform interface which optionally returns the hook(s) to be executed. Doing so would make things more explicit compared to implementing another interface.

Since the hook is optional, I think it's nice to have it separate, as it allows us to avoid adding boilerplate code to all platforms. This is not something every platform MUST implement, like e.g. generating Terraform code or Terraform plan (this could actually be optional too).

The price you're paying is clarity: Having an interface which can be optionally implemented leaves things implicit and more "magical" as far as the caller is concerned. It also doesn't make sense to me conceptually at the abstraction level: "A platform is a type of hook?" 🤔 This is very different from saying "AWS is a type of platform". Go interfaces are built for certain purposes and I don't think this use case is one of them. I think a hint which supports this is that you had to type-assert the interface rather than just executing a generic method.

I have no problem returning nil or an empty slice when no hooks are necessary on all platforms. To me this is much better than bending the abstraction to avoid "duplicating" a single line per platform.

@invidian
Copy link
Member Author

invidian commented Sep 1, 2020

I have no problem returning nil or an empty slice when no hooks are necessary on all platforms. To me this is much better than bending the abstraction to avoid "duplicating" a single line per platform.

Well, that's exectly the boilerplate I'm talking about. And it's not single line, but at least 4 😄

The price you're paying is clarity: Having an interface which can be optionally implemented leaves things implicit and more "magical" as far as the caller is concerned. It also doesn't make sense to me conceptually at the abstraction level: "A platform is a type of hook?" thinking This is very different from saying "AWS is a type of platform". Go interfaces are built for certain purposes and I don't think this use case is one of them. I think a hint which supports this is that you had to type-assert the interface rather than just executing a generic method.

Yeah, I agree that abstraction wise this is not great. (Actually, initially my interface was named PlatformPostApplyHook, but then linter complains, that you do platform.PlatformPostApplyHook.

And what do you think about:

type PlatformWithPostApplyHook interface {
  Platform
  PostApplyHook(kubeconfig []byte) error
}

I think it provides much better context then, as it extends the Platform interface and optionally ships this extra method. Name is something we should discuss of course :)

@iaguis
Copy link
Contributor

iaguis commented Sep 1, 2020

I think this discussion doesn't belong to this PR :)

@invidian
Copy link
Member Author

invidian commented Sep 1, 2020

I think this discussion doesn't belong to this PR :)

Well, I consider now changing this newly introduced interface to the version from #886 (comment) 😄

@johananl
Copy link
Member

johananl commented Sep 1, 2020

For the sake of moving this forward @invidian, please do whatever makes sense to you which solves the problem for now, and I'll do my best to integrate whatever you come up with into the new platform interface in a way which makes sense. We can continue the discussion there.

To address issue with AKS having delayed creation of default
StorageClass, which affects installing components which depend on the
storage, this commit introduces PlatformWithPostApplyHook interface, which platforms
will be able to implement to obtain kubeconfig file content after cluster
is installed to run their own sanity checks. In case of AKS, hook will
be looping and waiting until the default storage class appears on the
cluster.

Refs #855

Signed-off-by: Mateusz Gozdek <mateusz@kinvolk.io>
To address issue with AKS having delayed creation of default
StorageClass, which affects installing components which depend on the
storage, this commit adds support for running optional platform.PostApplyHook
after cluster has been installed.

Refs #855

Signed-off-by: Mateusz Gozdek <mateusz@kinvolk.io>
This commit implements newly introduced platform.PlatformWithPostApplyHook
for AKS clusters, to address issue, where components depending on the storage
gets installed when default storage class has not been yet created by
the AKS controller, as this causes components to get stuck, which makes
cluster provisioning to fail.

The implemented hook lists available storage classes on the cluster and
returns when class with default storage class annotation is found.
Usually default storage class appears on the cluster within 5 minutes
after cluster creation, so 10 minutes timeout seems like a sane default
for this operation.

Closes #855

Signed-off-by: Mateusz Gozdek <mateusz@kinvolk.io>
@invidian invidian dismissed stale reviews from iaguis and knrt10 via 1f0d703 September 1, 2020 15:02
@invidian invidian requested review from iaguis and knrt10 September 1, 2020 15:28
@invidian invidian added this to the v0.4.0 milestone Sep 2, 2020
@invidian invidian merged commit 27ec567 into master Sep 2, 2020
@invidian invidian deleted the invidian/fix-aks branch September 2, 2020 11:18
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AKS: prometheus-operator gets installed before default storage class object is created
4 participants