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

Simplify ml license checking with XpackLicenseState internals #52684

Merged
merged 2 commits into from
Feb 26, 2020

Conversation

ywangd
Copy link
Member

@ywangd ywangd commented Feb 23, 2020

This change reduces TrainedModelConfig#isAvailableWithLicense method to a single call to XPackLicenseState#isAllowedByLicense. It is made possible by the recent enhancements to license checking logic.

Please note there are subtle change to the code logic. But they seem to be the right changes:

  1. Trial license is always allowed.
  2. Platinum license no longer guarantees availability since there is now a dedicated Enterprise license.
  3. No explicit check when the license requirement is basic. Since basic license is always available, this check is unnecessary.

@ywangd ywangd added >enhancement :ml Machine learning :Security/License License functionality for commercial features v8.0.0 labels Feb 23, 2020
@ywangd ywangd requested a review from tvernum February 23, 2020 23:56
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security (:Security/License)

@elasticmachine
Copy link
Collaborator

Pinging @elastic/ml-core (:ml)


// catch the rest, if the license is active and is at least the required model license
return licenseState.isAllowedByLicense(licenseLevel, true, false);
return licenseState.isAllowedByLicense(licenseLevel);
Copy link
Member

Choose a reason for hiding this comment

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

isAllowedByLicense(OperationMode) calls isAllowedByLicense(minimumMode, true, true) which is different to the previous code.

Copy link
Member Author

@ywangd ywangd Feb 24, 2020

Choose a reason for hiding this comment

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

Thanks David. You are right that this call is different from the previous code. The difference is that the previous one does not allow trial license while the current one does. But their behaviours are actually not different when examined in the context of preceding code.

In the previous version, above this line, there is another check:

if (licenseState.isAllowedByLicense(License.OperationMode.PLATINUM)) {
    return true;
}

If the license is trial mode, it will be allowed already by the above check and will never reach the second check, i.e. it makes no difference whether the 2nd isAllowedByLicense is called with true or false for trial license, since the 1st check short-curcuits the logic for trial license.

With above being said, there is indeed a behaviour difference: previously platinum license is considered as highest and is guaranteed to be allowed. With this change, only Enterprise is guaranteed to be allowed. While writing this, I think we can achieve the same behaviour by change the code to:

return License.OperationMode.PLATINUM.compareTo(licenseState.getOperationMode()) <= 0 
    || licenseState.isAllowedByLicense(licenseLevel);

Copy link
Member Author

Choose a reason for hiding this comment

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

Above suggest code snippet has a racing issue as the licenseState could change between two calls. To remove potential racing issue was a motivation for this PR. Sorry yet I suggested another one. A better one should be as the follows:

final License.OperationMode minimumMode =
    License.OperationMode.PLATINUM.compareTo(licenseLevel) < 0 
        ? License.OperationMode.PLATINUM : licenseLevel;
return licenseState.isAllowedByLicense(minimumMode);

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation it makes sense, there is no need for the additional platinum level check what you have written is better for future proofing. Will you backport this to 7.7?

@grabowskit do you know why we did not deem a trial licence sufficient for model inference?

Copy link
Member Author

Choose a reason for hiding this comment

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

Just noticed the v7.7.0 label is not applied. But yes I plan to backport this to 7.7.

Copy link
Member

@davidkyle davidkyle Feb 24, 2020

Choose a reason for hiding this comment

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

👍

There is an argument to backport the trail licence change to 7.6.1 as it would be considered a bug if that is not what we intended. Thanks for finding this

Copy link
Member Author

Choose a reason for hiding this comment

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

If the intention is "trial license should always allow access", this bug does not really manifest itself in 7.6 since the the buggy code is never really triggered. If this is the case, I'd prefer to not backport this to 7.6.1 as it requires a number of other PRs.

But if the intention is to "block trial license for access", we do need fix it then. In this case, I'd prefer to have a separate PR to fix 7.6.1 specifically to avoid cascading backports.

@tvernum Do you wanna comment on this? Thanks

Copy link
Contributor

Choose a reason for hiding this comment

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

If the intention is "trial license should always allow access"

A trial license should allow all platinum features to be used (see for example https://www.elastic.co/trialextension and https://www.elastic.co/guide/en/elasticsearch/reference/current/start-trial.html#_description_15). It's a mistake if this wasn't the case before.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks @droberts195 That's my understanding as well. In this case, the bug will never be triggered as it is short-circuited by its preceding check.

return true;
}
);
assertTrue(builder.setLicenseLevel(License.OperationMode.ENTERPRISE.description()).build().isAvailableWithLicense(licenseState));
Copy link
Member

Choose a reason for hiding this comment

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

The licensing for inference models is not straightforward as different models can be licensed at different levels can we keep these assertions please so we know exactly what the behaviour is. The test that this code calls another piece of code is not sufficient. And for the gold tests below please

Copy link
Member Author

Choose a reason for hiding this comment

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

These assertions were removed because the method to be tested was reduced to just a single line which simply makes a call to XPackLicenseState#isAllowedByLicense(licenseLevel). Since tests use mock object, there really was no other logic to be tested for this method.

But if we add some of the original logic back, e.g. the platinum license check as discussed above, the relevant tests are then become necessary again and need to be added back as well.

Copy link
Member

@davidkyle davidkyle Feb 24, 2020

Choose a reason for hiding this comment

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

I know it's a one liner and the mocking makes the test awkward but it may not always be a one-liner if someone refactors the function and I'd prefer to have the safety net of asserting the expected behaviour.

That said, the best kind of code is deleted code so why not remove the method completely and call XPackLicenseState#isAllowedByLicense() directly then the tests can go.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a great suggestion. I updated the code accordingly.

@ywangd ywangd added the v7.7.0 label Feb 24, 2020
Copy link
Member

@davidkyle davidkyle left a comment

Choose a reason for hiding this comment

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

LGTM.

Can you wait for a sanity check from @benwtrent or @grabowskit regarding the trial licence change before merging please

@ywangd
Copy link
Member Author

ywangd commented Feb 24, 2020

Can you wait for a sanity check from @benwtrent or @grabowskit regarding the trial licence change before merging please

Thanks David. No problem I'll wait for all necessary checks. Plus I'll be offline soon. So no rush.

@benwtrent
Copy link
Member

benwtrent commented Feb 24, 2020

trial licence change before merging please

        if (licenseState.isAllowedByLicense(License.OperationMode.PLATINUM)) {
            return true;
        }

The original conditional did check for a trial license.

see XPackLicenseState#isAllowedByOperationMode

if (allowTrial && OperationMode.TRIAL == operationMode) {
            return true;
        }

So, I don't think the original code had a bug at all. Consequently, I think it should only be backported to 7.7.

Regardless, the change looks good to me. Simplifies things for future additional licenses.

@ywangd ywangd merged commit a629efe into elastic:master Feb 26, 2020
ywangd added a commit to ywangd/elasticsearch that referenced this pull request Feb 27, 2020
…c#52684)

This change removes TrainedModelConfig#isAvailableWithLicense method with calls to
XPackLicenseState#isAllowedByLicense.

Please note there are subtle changes to the code logic. But they are the right changes:
* Instead of Platinum license, Enterprise license nows guarantees availability.
* No explicit check when the license requirement is basic. Since basic license is always available, this check is unnecessary.
* Trial license is always allowed.
ywangd added a commit that referenced this pull request Feb 27, 2020
#52863)

This change removes TrainedModelConfig#isAvailableWithLicense method with calls to
XPackLicenseState#isAllowedByLicense.

Please note there are subtle changes to the code logic. But they are the right changes:
* Instead of Platinum license, Enterprise license nows guarantees availability.
* No explicit check when the license requirement is basic. Since basic license is always available, this check is unnecessary.
* Trial license is always allowed.
@ywangd
Copy link
Member Author

ywangd commented Feb 27, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>enhancement :ml Machine learning :Security/License License functionality for commercial features v7.7.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants