-
Notifications
You must be signed in to change notification settings - Fork 25.7k
[ML] Require basic licence for the Elastic Inference Service #137434
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
Changes from 4 commits
c8619b4
f33473e
9f16092
55e7d61
1c7837b
2e37465
05fb843
996d014
05ffb2f
64c029d
c84e138
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| pr: 137434 | ||
| summary: Require basic licence for the Elastic Inference Service | ||
| area: Machine Learning | ||
| type: enhancement | ||
| issues: [] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| package org.elasticsearch.xpack.inference; | ||
|
|
||
| import org.elasticsearch.ElasticsearchSecurityException; | ||
| import org.elasticsearch.license.LicenseUtils; | ||
| import org.elasticsearch.license.XPackLicenseState; | ||
| import org.elasticsearch.xpack.core.XPackField; | ||
| import org.elasticsearch.xpack.inference.services.elastic.ElasticInferenceService; | ||
|
|
||
| import static org.elasticsearch.xpack.inference.InferencePlugin.EIS_INFERENCE_FEATURE; | ||
| import static org.elasticsearch.xpack.inference.InferencePlugin.INFERENCE_API_FEATURE; | ||
|
|
||
| public class InferenceLicenceCheck { | ||
|
|
||
| private InferenceLicenceCheck() {} | ||
|
|
||
| public static boolean isServiceLicenced(String serviceName, XPackLicenseState licenseState) { | ||
| if (ElasticInferenceService.NAME.equals(serviceName)) { | ||
| return EIS_INFERENCE_FEATURE.check(licenseState); | ||
| } else { | ||
| return INFERENCE_API_FEATURE.check(licenseState); | ||
| } | ||
| } | ||
|
|
||
| public static ElasticsearchSecurityException complianceException(String serviceName) { | ||
| if (ElasticInferenceService.NAME.equals(serviceName)) { | ||
| return LicenseUtils.newComplianceException(XPackField.ELASTIC_INFERENCE_SERVICE); | ||
| } else { | ||
| return LicenseUtils.newComplianceException(XPackField.INFERENCE); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,19 +29,18 @@ | |
| import org.elasticsearch.inference.ModelConfigurations; | ||
| import org.elasticsearch.inference.TaskType; | ||
| import org.elasticsearch.injection.guice.Inject; | ||
| import org.elasticsearch.license.LicenseUtils; | ||
| import org.elasticsearch.license.XPackLicenseState; | ||
| import org.elasticsearch.rest.RestStatus; | ||
| import org.elasticsearch.tasks.Task; | ||
| import org.elasticsearch.threadpool.ThreadPool; | ||
| import org.elasticsearch.transport.TransportService; | ||
| import org.elasticsearch.xcontent.XContentParser; | ||
| import org.elasticsearch.xcontent.XContentParserConfiguration; | ||
| import org.elasticsearch.xpack.core.XPackField; | ||
| import org.elasticsearch.xpack.core.inference.action.PutInferenceModelAction; | ||
| import org.elasticsearch.xpack.core.ml.inference.assignment.TrainedModelAssignmentUtils; | ||
| import org.elasticsearch.xpack.core.ml.job.messages.Messages; | ||
| import org.elasticsearch.xpack.core.ml.utils.ExceptionsHelper; | ||
| import org.elasticsearch.xpack.inference.InferenceLicenceCheck; | ||
| import org.elasticsearch.xpack.inference.InferencePlugin; | ||
| import org.elasticsearch.xpack.inference.registry.ModelRegistry; | ||
| import org.elasticsearch.xpack.inference.services.ServiceUtils; | ||
|
|
@@ -53,7 +52,6 @@ | |
| import java.util.Map; | ||
|
|
||
| import static org.elasticsearch.core.Strings.format; | ||
| import static org.elasticsearch.xpack.inference.InferencePlugin.INFERENCE_API_FEATURE; | ||
| import static org.elasticsearch.xpack.inference.services.elasticsearch.ElasticsearchInternalService.OLD_ELSER_SERVICE_NAME; | ||
|
|
||
| public class TransportPutInferenceModelAction extends TransportMasterNodeAction< | ||
|
|
@@ -106,11 +104,6 @@ protected void masterOperation( | |
| ClusterState state, | ||
| ActionListener<PutInferenceModelAction.Response> listener | ||
| ) throws Exception { | ||
| if (INFERENCE_API_FEATURE.check(licenseState) == false) { | ||
| listener.onFailure(LicenseUtils.newComplianceException(XPackField.INFERENCE)); | ||
| return; | ||
| } | ||
|
|
||
| if (modelRegistry.containsDefaultConfigId(request.getInferenceEntityId())) { | ||
| listener.onFailure( | ||
| new ElasticsearchStatusException( | ||
|
|
@@ -136,6 +129,11 @@ protected void masterOperation( | |
| return; | ||
| } | ||
|
|
||
| if (InferenceLicenceCheck.isServiceLicenced(serviceName, licenseState) == false) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I wonder if we should move the reserved ID check to below this check? |
||
| listener.onFailure(InferenceLicenceCheck.complianceException(serviceName)); | ||
| return; | ||
| } | ||
|
|
||
| if (List.of(OLD_ELSER_SERVICE_NAME, ElasticsearchInternalService.NAME).contains(serviceName)) { | ||
| // required for BWC of elser service in elasticsearch service TODO remove when elser service deprecated | ||
| requestAsMap.put(ModelConfigurations.SERVICE, serviceName); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,7 +48,6 @@ | |
| import org.elasticsearch.inference.Model; | ||
| import org.elasticsearch.inference.UnparsedModel; | ||
| import org.elasticsearch.inference.telemetry.InferenceStats; | ||
| import org.elasticsearch.license.LicenseUtils; | ||
| import org.elasticsearch.license.XPackLicenseState; | ||
| import org.elasticsearch.rest.RestStatus; | ||
| import org.elasticsearch.tasks.Task; | ||
|
|
@@ -57,10 +56,10 @@ | |
| import org.elasticsearch.xcontent.XContentParser; | ||
| import org.elasticsearch.xcontent.XContentParserConfiguration; | ||
| import org.elasticsearch.xcontent.XContentType; | ||
| import org.elasticsearch.xpack.core.XPackField; | ||
| import org.elasticsearch.xpack.core.inference.chunking.ChunkingSettingsBuilder; | ||
| import org.elasticsearch.xpack.core.inference.results.ChunkedInferenceError; | ||
| import org.elasticsearch.xpack.inference.InferenceException; | ||
| import org.elasticsearch.xpack.inference.InferenceLicenceCheck; | ||
| import org.elasticsearch.xpack.inference.mapper.SemanticTextField; | ||
| import org.elasticsearch.xpack.inference.mapper.SemanticTextFieldMapper; | ||
| import org.elasticsearch.xpack.inference.mapper.SemanticTextUtils; | ||
|
|
@@ -78,7 +77,6 @@ | |
| import java.util.stream.Collectors; | ||
|
|
||
| import static org.elasticsearch.inference.telemetry.InferenceStats.serviceAndResponseAttributes; | ||
| import static org.elasticsearch.xpack.inference.InferencePlugin.INFERENCE_API_FEATURE; | ||
| import static org.elasticsearch.xpack.inference.mapper.SemanticTextField.toSemanticTextFieldChunks; | ||
| import static org.elasticsearch.xpack.inference.mapper.SemanticTextField.toSemanticTextFieldChunksLegacy; | ||
|
|
||
|
|
@@ -383,6 +381,19 @@ public void onFailure(Exception exc) { | |
| modelRegistry.getModelWithSecrets(inferenceId, modelLoadingListener); | ||
| return; | ||
| } | ||
|
|
||
| if (InferenceLicenceCheck.isServiceLicenced(inferenceProvider.service.name(), licenseState) == false) { | ||
| try (onFinish) { | ||
| for (FieldInferenceRequest request : requests) { | ||
| addInferenceResponseFailure( | ||
| request.bulkItemIndex, | ||
| InferenceLicenceCheck.complianceException(inferenceProvider.service.name()) | ||
| ); | ||
| } | ||
| return; | ||
| } | ||
| } | ||
|
Comment on lines
385
to
393
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @carlosdelest what do you think of this? It seems OK to me. Both the old and new license check failures are per bulk item request. Now we just delay it until we have the inference provider loaded.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense - we're checking the inference provider service when we have it. As requests are grouped by inference provider, we can fail all of them at once in case it's not compliant. 👍 |
||
|
|
||
| final List<ChunkInferenceInput> inputs = requests.stream() | ||
| .map(r -> new ChunkInferenceInput(r.input, r.chunkingSettings)) | ||
| .collect(Collectors.toList()); | ||
|
|
@@ -571,11 +582,6 @@ private long addFieldInferenceRequests(BulkItemRequest item, int itemIndex, Map< | |
| break; | ||
| } | ||
|
|
||
| if (INFERENCE_API_FEATURE.check(licenseState) == false) { | ||
| addInferenceResponseFailure(itemIndex, LicenseUtils.newComplianceException(XPackField.INFERENCE)); | ||
| break; | ||
| } | ||
|
|
||
| List<FieldInferenceRequest> requests = requestsMap.computeIfAbsent(inferenceId, k -> new ArrayList<>()); | ||
| int offsetAdjustment = 0; | ||
| for (String v : values) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a bit confusing to me, the
ElasticInferenceService.NAMEiselastic, but our license service name iseis. So the user configureselasticto get the license with nameeis.Could we name this
elasticto match the name of theElasticInferenceService.NAME?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed this to the proper name "Elastic Inference Service"
The error the user sees if the licence is not compatible is either:
Or