-
Notifications
You must be signed in to change notification settings - Fork 24.6k
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
Add max_resource_units to enterprise license #50735
Changes from 7 commits
71f029a
0bcba71
7a26ca3
3019233
0c03b5c
8147c82
1cfc630
736057a
f3c54d6
c7e537d
a02c11d
fbfe58c
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 | ||||
---|---|---|---|---|---|---|
|
@@ -113,13 +113,19 @@ static boolean isBasic(String typeName) { | |||||
static boolean isTrial(String typeName) { | ||||||
return TRIAL.getTypeName().equals(typeName); | ||||||
} | ||||||
|
||||||
static boolean isEnterprise(String typeName) { | ||||||
return ENTERPRISE.getTypeName().equals(typeName); | ||||||
} | ||||||
|
||||||
} | ||||||
|
||||||
public static final int VERSION_START = 1; | ||||||
public static final int VERSION_NO_FEATURE_TYPE = 2; | ||||||
public static final int VERSION_START_DATE = 3; | ||||||
public static final int VERSION_CRYPTO_ALGORITHMS = 4; | ||||||
public static final int VERSION_CURRENT = VERSION_CRYPTO_ALGORITHMS; | ||||||
public static final int VERSION_ENTERPRISE = 5; | ||||||
public static final int VERSION_CURRENT = VERSION_ENTERPRISE; | ||||||
|
||||||
/** | ||||||
* XContent param name to deserialize license(s) with | ||||||
|
@@ -153,13 +159,14 @@ static boolean isTrial(String typeName) { | |||||
private final long expiryDate; | ||||||
private final long startDate; | ||||||
private final int maxNodes; | ||||||
private final int maxResourceUnits; | ||||||
private final OperationMode operationMode; | ||||||
|
||||||
/** | ||||||
* Decouples operation mode of a license from the license type value. | ||||||
* <p> | ||||||
* Note: The mode indicates features that should be made available, but it does not indicate whether the license is active! | ||||||
* | ||||||
* <p> | ||||||
* The id byte is used for ordering operation modes | ||||||
*/ | ||||||
public enum OperationMode { | ||||||
|
@@ -176,13 +183,16 @@ public enum OperationMode { | |||||
this.id = id; | ||||||
} | ||||||
|
||||||
/** Returns non-zero positive number when <code>opMode1</code> is greater than <code>opMode2</code> */ | ||||||
/** | ||||||
* Returns non-zero positive number when <code>opMode1</code> is greater than <code>opMode2</code> | ||||||
*/ | ||||||
public static int compare(OperationMode opMode1, OperationMode opMode2) { | ||||||
return Integer.compare(opMode1.id, opMode2.id); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Determine the operating mode for a license type | ||||||
* | ||||||
* @see LicenseType#resolve(License) | ||||||
* @see #parse(String) | ||||||
*/ | ||||||
|
@@ -211,6 +221,7 @@ public static OperationMode resolve(LicenseType type) { | |||||
* Parses an {@code OperatingMode} from a String. | ||||||
* The string must name an operating mode, and not a licensing level (that is, it cannot parse old style license levels | ||||||
* such as "dev" or "silver"). | ||||||
* | ||||||
* @see #description() | ||||||
*/ | ||||||
public static OperationMode parse(String mode) { | ||||||
|
@@ -227,8 +238,8 @@ public String description() { | |||||
} | ||||||
} | ||||||
|
||||||
private License(int version, String uid, String issuer, String issuedTo, long issueDate, String type, | ||||||
String subscriptionType, String feature, String signature, long expiryDate, int maxNodes, long startDate) { | ||||||
private License(int version, String uid, String issuer, String issuedTo, long issueDate, String type, String subscriptionType, | ||||||
String feature, String signature, long expiryDate, int maxNodes, int maxResourceUnits, long startDate) { | ||||||
this.version = version; | ||||||
this.uid = uid; | ||||||
this.issuer = issuer; | ||||||
|
@@ -246,6 +257,7 @@ private License(int version, String uid, String issuer, String issuedTo, long is | |||||
this.expiryDate = expiryDate; | ||||||
} | ||||||
this.maxNodes = maxNodes; | ||||||
this.maxResourceUnits = maxResourceUnits; | ||||||
this.startDate = startDate; | ||||||
this.operationMode = OperationMode.resolve(LicenseType.resolve(this)); | ||||||
validate(); | ||||||
|
@@ -294,12 +306,21 @@ public long expiryDate() { | |||||
} | ||||||
|
||||||
/** | ||||||
* @return the maximum number of nodes this license has been issued for | ||||||
* @return the maximum number of nodes this license has been issued for, or {@code -1} if this license is not node based. | ||||||
*/ | ||||||
public int maxNodes() { | ||||||
return maxNodes; | ||||||
} | ||||||
|
||||||
/** | ||||||
* @return the maximum number of "resource units" this license has been issued for, or {@code -1} if this license is not resource based. | ||||||
* A "resource unit" is a measure of computing power (RAM/CPU), the definition of which is maintained outside of the license format, | ||||||
* or this class. | ||||||
*/ | ||||||
public int maxResourceUnits() { | ||||||
return maxResourceUnits; | ||||||
} | ||||||
|
||||||
/** | ||||||
* @return a string representing the entity this licenses has been issued to | ||||||
*/ | ||||||
|
@@ -386,20 +407,38 @@ private void validate() { | |||||
throw new IllegalStateException("uid can not be null"); | ||||||
} else if (feature == null && version == VERSION_START) { | ||||||
throw new IllegalStateException("feature can not be null"); | ||||||
} else if (maxNodes == -1) { | ||||||
throw new IllegalStateException("maxNodes has to be set"); | ||||||
} else if (expiryDate == -1) { | ||||||
throw new IllegalStateException("expiryDate has to be set"); | ||||||
} else if (expiryDate == LicenseService.BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS && LicenseType.isBasic(type) == false) { | ||||||
throw new IllegalStateException("only basic licenses are allowed to have no expiration"); | ||||||
} | ||||||
|
||||||
if (LicenseType.isEnterprise(type) && version < VERSION_ENTERPRISE) { | ||||||
throw new IllegalStateException("license type [" + type + "] is not a valid for version [" + version + "] licenses"); | ||||||
} | ||||||
validateLimits(type, maxNodes, maxResourceUnits); | ||||||
} | ||||||
|
||||||
private static void validateLimits(String type, int maxNodes, int maxResourceUnits) { | ||||||
if (LicenseType.isEnterprise(type)) { | ||||||
if (maxResourceUnits == -1) { | ||||||
throw new IllegalStateException("maxResourceUnits must be set for enterprise licenses"); | ||||||
} else if (maxNodes != -1) { | ||||||
throw new IllegalStateException("maxNodes may not be set for enterprise licenses"); | ||||||
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.
Suggested change
|
||||||
} | ||||||
} else { | ||||||
if (maxNodes == -1) { | ||||||
throw new IllegalStateException("maxNodes has to be set"); | ||||||
} else if (maxResourceUnits != -1) { | ||||||
throw new IllegalStateException("maxResourceUnits may only be set for enterprise licenses"); | ||||||
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.
Suggested change
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. This suggestion is backwards. I could change it to say that they 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. Sure, makes sense, sorry for the half-baked suggestion |
||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
public static License readLicense(StreamInput in) throws IOException { | ||||||
int version = in.readVInt(); // Version for future extensibility | ||||||
if (version > VERSION_CURRENT) { | ||||||
throw new ElasticsearchException("Unknown license version found, please upgrade all nodes to the latest elasticsearch-license" + | ||||||
" plugin"); | ||||||
throw new ElasticsearchException("Unknown license version found, please upgrade all nodes to the latest elasticsearch release"); | ||||||
} | ||||||
Builder builder = builder(); | ||||||
builder.version(version); | ||||||
|
@@ -414,6 +453,9 @@ public static License readLicense(StreamInput in) throws IOException { | |||||
} | ||||||
builder.expiryDate(in.readLong()); | ||||||
builder.maxNodes(in.readInt()); | ||||||
if (version >= VERSION_ENTERPRISE) { | ||||||
builder.maxResourceUnits(in.readInt()); | ||||||
} | ||||||
builder.issuedTo(in.readString()); | ||||||
builder.issuer(in.readString()); | ||||||
builder.signature(in.readOptionalString()); | ||||||
|
@@ -436,6 +478,9 @@ public void writeTo(StreamOutput out) throws IOException { | |||||
} | ||||||
out.writeLong(expiryDate); | ||||||
out.writeInt(maxNodes); | ||||||
if (version >= VERSION_ENTERPRISE) { | ||||||
out.writeInt(maxResourceUnits); | ||||||
} | ||||||
out.writeString(issuedTo); | ||||||
out.writeString(issuer); | ||||||
out.writeOptionalString(signature); | ||||||
|
@@ -496,7 +541,14 @@ public XContentBuilder toInnerXContent(XContentBuilder builder, Params params) t | |||||
if (expiryDate != LicenseService.BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS) { | ||||||
builder.timeField(Fields.EXPIRY_DATE_IN_MILLIS, Fields.EXPIRY_DATE, expiryDate); | ||||||
} | ||||||
builder.field(Fields.MAX_NODES, maxNodes); | ||||||
|
||||||
if (version >= VERSION_ENTERPRISE) { | ||||||
builder.field(Fields.MAX_NODES, maxNodes == -1 ? null : maxNodes); | ||||||
builder.field(Fields.MAX_RESOURCE_UNITS, maxResourceUnits == -1 ? null : maxResourceUnits); | ||||||
} else { | ||||||
builder.field(Fields.MAX_NODES, maxNodes); | ||||||
} | ||||||
|
||||||
builder.field(Fields.ISSUED_TO, issuedTo); | ||||||
builder.field(Fields.ISSUER, issuer); | ||||||
if (!licenseSpecMode && !restViewMode && signature != null) { | ||||||
|
@@ -541,6 +593,8 @@ public static License fromXContent(XContentParser parser) throws IOException { | |||||
builder.startDate(parser.longValue()); | ||||||
} else if (Fields.MAX_NODES.equals(currentFieldName)) { | ||||||
builder.maxNodes(parser.intValue()); | ||||||
} else if (Fields.MAX_RESOURCE_UNITS.equals(currentFieldName)) { | ||||||
builder.maxResourceUnits(parser.intValue()); | ||||||
} else if (Fields.ISSUED_TO.equals(currentFieldName)) { | ||||||
builder.issuedTo(parser.text()); | ||||||
} else if (Fields.ISSUER.equals(currentFieldName)) { | ||||||
|
@@ -583,7 +637,7 @@ public static License fromXContent(XContentParser parser) throws IOException { | |||||
throw new ElasticsearchException("malformed signature for license [" + builder.uid + "]"); | ||||||
} else if (version > VERSION_CURRENT) { | ||||||
throw new ElasticsearchException("Unknown license version found, please upgrade all nodes to the latest " + | ||||||
"elasticsearch-license plugin"); | ||||||
"elasticsearch-license plugin"); | ||||||
} | ||||||
// signature version is the source of truth | ||||||
builder.version(version); | ||||||
|
@@ -615,8 +669,7 @@ public static License fromSource(BytesReference bytes, XContentType xContentType | |||||
// EMPTY is safe here because we don't call namedObject | ||||||
try (InputStream byteStream = bytes.streamInput(); | ||||||
XContentParser parser = xContentType.xContent() | ||||||
.createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, byteStream)) | ||||||
{ | ||||||
.createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, byteStream)) { | ||||||
License license = null; | ||||||
if (parser.nextToken() == XContentParser.Token.START_OBJECT) { | ||||||
if (parser.nextToken() == XContentParser.Token.FIELD_NAME) { | ||||||
|
@@ -665,7 +718,7 @@ public boolean equals(Object o) { | |||||
|
||||||
if (issueDate != license.issueDate) return false; | ||||||
if (expiryDate != license.expiryDate) return false; | ||||||
if (startDate!= license.startDate) return false; | ||||||
if (startDate != license.startDate) return false; | ||||||
if (maxNodes != license.maxNodes) return false; | ||||||
if (version != license.version) return false; | ||||||
if (uid != null ? !uid.equals(license.uid) : license.uid != null) return false; | ||||||
|
@@ -690,7 +743,7 @@ public int hashCode() { | |||||
result = 31 * result + (feature != null ? feature.hashCode() : 0); | ||||||
result = 31 * result + (signature != null ? signature.hashCode() : 0); | ||||||
result = 31 * result + (int) (expiryDate ^ (expiryDate >>> 32)); | ||||||
result = 31 * result + (int) (startDate ^ (startDate>>> 32)); | ||||||
result = 31 * result + (int) (startDate ^ (startDate >>> 32)); | ||||||
result = 31 * result + maxNodes; | ||||||
result = 31 * result + version; | ||||||
return result; | ||||||
|
@@ -709,6 +762,7 @@ public static final class Fields { | |||||
public static final String START_DATE_IN_MILLIS = "start_date_in_millis"; | ||||||
public static final String START_DATE = "start_date"; | ||||||
public static final String MAX_NODES = "max_nodes"; | ||||||
public static final String MAX_RESOURCE_UNITS = "max_resource_units"; | ||||||
public static final String ISSUED_TO = "issued_to"; | ||||||
public static final String ISSUER = "issuer"; | ||||||
public static final String VERSION = "version"; | ||||||
|
@@ -752,6 +806,7 @@ public static class Builder { | |||||
private long expiryDate = -1; | ||||||
private long startDate = -1; | ||||||
private int maxNodes = -1; | ||||||
private int maxResourceUnits = -1; | ||||||
|
||||||
public Builder uid(String uid) { | ||||||
this.uid = uid; | ||||||
|
@@ -807,6 +862,11 @@ public Builder maxNodes(int maxNodes) { | |||||
return this; | ||||||
} | ||||||
|
||||||
public Builder maxResourceUnits(int maxUnits) { | ||||||
this.maxResourceUnits = maxUnits; | ||||||
return this; | ||||||
} | ||||||
|
||||||
public Builder signature(String signature) { | ||||||
if (signature != null) { | ||||||
this.signature = signature; | ||||||
|
@@ -821,17 +881,18 @@ public Builder startDate(long startDate) { | |||||
|
||||||
public Builder fromLicenseSpec(License license, String signature) { | ||||||
return uid(license.uid()) | ||||||
.version(license.version()) | ||||||
.issuedTo(license.issuedTo()) | ||||||
.issueDate(license.issueDate()) | ||||||
.startDate(license.startDate()) | ||||||
.type(license.type()) | ||||||
.subscriptionType(license.subscriptionType) | ||||||
.feature(license.feature) | ||||||
.maxNodes(license.maxNodes()) | ||||||
.expiryDate(license.expiryDate()) | ||||||
.issuer(license.issuer()) | ||||||
.signature(signature); | ||||||
.version(license.version()) | ||||||
.issuedTo(license.issuedTo()) | ||||||
.issueDate(license.issueDate()) | ||||||
.startDate(license.startDate()) | ||||||
.type(license.type()) | ||||||
.subscriptionType(license.subscriptionType) | ||||||
.feature(license.feature) | ||||||
.maxNodes(license.maxNodes()) | ||||||
.maxResourceUnits(license.maxResourceUnits()) | ||||||
.expiryDate(license.expiryDate()) | ||||||
.issuer(license.issuer()) | ||||||
.signature(signature); | ||||||
} | ||||||
|
||||||
/** | ||||||
|
@@ -840,15 +901,15 @@ public Builder fromLicenseSpec(License license, String signature) { | |||||
*/ | ||||||
public Builder fromPre20LicenseSpec(License pre20License) { | ||||||
return uid(pre20License.uid()) | ||||||
.issuedTo(pre20License.issuedTo()) | ||||||
.issueDate(pre20License.issueDate()) | ||||||
.maxNodes(pre20License.maxNodes()) | ||||||
.expiryDate(pre20License.expiryDate()); | ||||||
.issuedTo(pre20License.issuedTo()) | ||||||
.issueDate(pre20License.issueDate()) | ||||||
.maxNodes(pre20License.maxNodes()) | ||||||
.expiryDate(pre20License.expiryDate()); | ||||||
} | ||||||
|
||||||
public License build() { | ||||||
return new License(version, uid, issuer, issuedTo, issueDate, type, | ||||||
subscriptionType, feature, signature, expiryDate, maxNodes, startDate); | ||||||
subscriptionType, feature, signature, expiryDate, maxNodes, maxResourceUnits, startDate); | ||||||
} | ||||||
|
||||||
public Builder validate() { | ||||||
|
@@ -864,11 +925,10 @@ public Builder validate() { | |||||
throw new IllegalStateException("uid can not be null"); | ||||||
} else if (signature == null) { | ||||||
throw new IllegalStateException("signature can not be null"); | ||||||
} else if (maxNodes == -1) { | ||||||
throw new IllegalStateException("maxNodes has to be set"); | ||||||
} else if (expiryDate == -1) { | ||||||
throw new IllegalStateException("expiryDate has to be set"); | ||||||
} | ||||||
validateLimits(type, maxNodes, maxResourceUnits); | ||||||
return this; | ||||||
} | ||||||
|
||||||
|
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.
nit: