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

refactor(kubernetes): Look up CRD details on-demand #4033

Merged
merged 10 commits into from
Sep 17, 2019
Merged

refactor(kubernetes): Look up CRD details on-demand #4033

merged 10 commits into from
Sep 17, 2019

Conversation

ezimanyi
Copy link
Contributor

  • refactor(kubernetes): Remove useless call to register kind

    On account creation, we iterate over all kinds in the account and call registerKind. Since we only have the name of the kind and no other information, we just assume the kind is namespaced and pass true.

    Since the kind registry will return a set of default properties
    (including isNamespaced set to true) for something not in the registry, skip the needless call to register these kinds with default properties.

  • refactor(kubernetes): Pass custom resources to registry constructor

    Each account has a set of custom resources that are statically defined in the account config. We register each of these into the KubernetesKindRegistry, but currently do so in a somewhat opaque way, by depending on a side-effect of the KubernetesResourceProperties.fromCustomResource function we use when creating a different property on the account.

    Remove the side effect from the fromCustomResource function and instead pass the list of custom resources to the constructor for KubernetesKindRegistry, allowing it to register resources there.

  • refactor(kubernetes): Use ObjectMapper to parse CRD

    The current logic for reading CRD details is full of unsafe casts and is hard to read. Define a class that has the fields we expect on a CRD and use ObjectMapper to convert the manifest back from the cluster into a typed object.

  • refactor(kubernetes): Allow KubernetesKindRegistry to look up CRDs

    To avoid needing to pre-register all CRDs into the kind registry, the registry should be able to look up kind information in the cluster if it comes across a kind that it does not have any information about.

    When creating a KubernetesKindRegistry, the caller can provide a Function<KubernetesKind, Optional>; when looking up a kind that is not in the registry, the registry will call that function to try to resolve the kind properties. If the function returns a result, the properties are recorded in the registry
    (so subsequent lookups of the same kind don't call the function again). If the function returns an empty Optional, we return a set of default properties as before.

    This commit does not actually use the new functionality; this will come in a later commit.

  • refactor(kubernetes): Look up CRD details on-demand

    Create a new function getCrdProperties that on-demand looks up the properties of a CRD and pass this to the constructor for the kind registry. This removes the need to pre-register kinds that are fround when listing CRDs as the registry will look up any kinds it needs, and also removes the last remaining side-effect of calling liveCrdSupplier.

    The only call to getCrds is from the unregistered CRD caching agent. Given that this happens once per caching cycle (along with a lot of other lookups) there's no real benefit to memoizing the result with a timed expiration. Remove the memoization and just have getCrds do a live lookup.

  • refactor(kubernetes): Rename getRegisteredKind to getKindProperties

    The term registered is confusing, and also somewhat redundant given that the method is on a kind regsitry. (It's also not entirely correct as the function can also live lookup properties and register them.)

    Let's rename the function getKindProperties to be more in line with what it does.

On account creation, we iterate over all kinds in the account
and call registerKind. Since we only have the name of the kind
and no other information, we just assume the kind is namespaced
and pass true.

Since the kind registry will return a set of default properties
(including isNamespaced set to true) for something not in the
registry, skip the needless call to register these kinds with
default properties.
Each account has a set of custom resources that are statically
defined in the account config. We register each of these into
the KubernetesKindRegistry, but currently do so in a somewhat
opaque way, by depending on a side-effect of the
KubernetesResourceProperties.fromCustomResource function we use
when creating a different property on the account.

Remove the side effect from the fromCustomResource function and
instead pass the list of custom resources to the constructor for
KubernetesKindRegistry, allowing it to register resources there.
The current logic for reading CRD details is full of unsafe
casts and is hard to read. Define a class that has the fields
we expect on a CRD and use ObjectMapper to convert the manifest
back from the cluster into a typed object.
To avoid needing to pre-register all CRDs into the kind registry, the
registry should be able to look up kind information in the cluster if
it comes across a kind that it does not have any information about.

When creating a KubernetesKindRegistry, the caller can provide a
Function<KubernetesKind, Optional<KubernetesKindProperties>>; when
looking up a kind that is not in the registry, the registry will
call that function to try to resolve the kind properties. If the
function returns a result, the properties are recorded in the registry
(so subsequent lookups of the same kind don't call the function again).
If the function returns an empty Optional, we return a set of default
properties as before.

This commit does not actually use the new functionality; this will
come in a later commit.
Create a new function getCrdProperties that on-demand looks
up the properties of a CRD and pass this to the constructor
for the kind registry. This removes the need to pre-register
kinds that are fround when listing CRDs as the registry will
look up any kinds it needs, and also removes the last remaining
side-effect of calling liveCrdSupplier.

The only call to getCrds is from the unregistered CRD caching
agent. Given that this happens once per caching cycle (along
with a lot of other lookups) there's no real benefit to
memoizing the result with a timed expiration. Remove the
memoization and just have getCrds do a live lookup.
The term registered is confusing, and also somewhat redundant given
that the method is on a kind regsitry. (It's also not entirely correct
as the function can also live lookup properties and register them.)

Let's rename the function getKindProperties to be more in line with
what it does.
Copy link
Contributor

@maggieneterval maggieneterval left a comment

Choose a reason for hiding this comment

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

Well my only useless comment is to remove an extra "the." Great job!
🔍 📜 📺
👨 🔨 🐛

ezimanyi and others added 2 commits September 17, 2019 14:29
Co-Authored-By: Maggie Neterval <mneterval@google.com>
Calling get() returns null when no resource is found rather than
throwing an exception. We should return Optional.empty() in that
case (rather than try to dereference the null in the following
logic) just as we do when we run into an exception.

Also add visibility by logging any exceptions in the exception block.
Copy link
Member

@plumpy plumpy left a comment

Choose a reason for hiding this comment

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

I don't even have an extra "the" to comment on. Nice!
🕺

The logic in an earlier commit to look up CRD properties was
incorrect as it was looking up CRDs via the command
kubectl get crd kind.apigroup; we need to use the *plural* version
of the kind in this command (as a CRD's name is based on the plural
kind).

There's unfortunately no good way to directly look up a CRD based
on the singular name. This commit works around it by just listing
all CRDs and filtering based on the name to the one we're interested
in. To avoid the performance implications of too many lookups of
the entire list of CRDs, also re-introduce memoizing.
Copy link
Contributor

@ethanfrogers ethanfrogers left a comment

Choose a reason for hiding this comment

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

WHOOP WHOOP!

@ezimanyi ezimanyi merged commit 4699fa2 into spinnaker:master Sep 17, 2019
@ezimanyi ezimanyi deleted the fix-live-lookups branch September 17, 2019 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants