-
Notifications
You must be signed in to change notification settings - Fork 24.7k
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
Use a licensed feature per realm-type (+custom) #78810
Use a licensed feature per realm-type (+custom) #78810
Conversation
This commit changes the licensed feature usage tracking for realms to record each realm type as its own separate feature. Custom realms continue to fall under a single catch-all feature.
Pinging @elastic/es-security (Team:Security) |
1 similar comment
This comment has been minimized.
This comment has been minimized.
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.
LGTM
I don't think it belongs to this PR. But those names used in Realms and friends confused me again. There are "internal", "builtin", "native", "fallback", "standard", "basic" etc. We really need formalize and clean them up in a future PR.
// Standard realms (LDAP, AD, PKI, etc) are Gold+ | ||
// Some realms (LDAP, AD, PKI) are Gold+ | ||
public static final LicensedFeature.Persistent LDAP_REALM_FEATURE = | ||
LicensedFeature.persistentLenient(null, "security_ldap_realm", License.OperationMode.GOLD); |
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 believe @rjernst purposely uses dash (-
) instead of (underscore
) to different the new names from old ones.
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 also think we should have a family of “security” or “security-realms”, and the feature name can just be eg “ldap-realm”.
x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/Realms.java
Show resolved
Hide resolved
* @throws IllegalArgumentException if the provided type is not an {@link #isInternalRealm(String) internal realm} | ||
*/ | ||
static LicensedFeature.Persistent getLicensedFeature(String type) { | ||
if (Strings.isNullOrEmpty(type)) { |
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.
Should we use Strings.hasText
here similar to what is used in Realms#getLicensedFeatureForRealm
. It has better coverage for blank strings.
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.
Blanks will still fail below when opt
is null, as will any other string with whitespace (e.g. " ldap"
).
This code forces clear failures in things that don't implement a type (e.g. poorly configured mocks), but I don't think we need to go out of our way to deal with whitespace there.
// In theory this could be "standard" too, but there aren't any realms on that license level | ||
assertThat(feature.getMinimumOperationMode(), is(License.OperationMode.GOLD)); |
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 don't quite get what this comment try to say. Could you please elaborate?
assertThat(feature.getMinimumOperationMode(), is(License.OperationMode.GOLD)); | ||
} else { | ||
assertThat(feature, notNullValue()); | ||
// In theory this could be "enterprise" too, but there aren't any realms on that license level |
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.
Same as above.
assertThat( | ||
iae.getMessage(), | ||
is( | ||
equalTo( | ||
"multiple realms [realm_1, realm_2] configured of type [kerberos], [kerberos] can only have one such realm configured" | ||
) | ||
) | ||
); |
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.
Is this spotless format change?
* @return The licensed feature for the given realm type, or {@code null} if the realm does not require a specific license type | ||
* @throws IllegalArgumentException if the provided type is not an {@link #isInternalRealm(String) internal realm} | ||
*/ | ||
static LicensedFeature.Persistent getLicensedFeature(String type) { |
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 am not sure about this method. It exists really just for Relams.getLicensedFeatureForRealm
and is not meant to be used standalone.
I'd personally move it as a private method in Realms
. This also removes the need to have XPACK_TYPES
as a Map
which could be a good thing beause using Optional.of()
to accomodate null
value seems to be an indication of forcing things together.
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.
My concern in that we already have too many places that try and keep track of all the builtin realm types. I don't think it's wise for both Realms
and InternalRealms
to know about what realm types exist.
I can rework InternalRealms
to have multiple maps instead if that helps, but I think it's a bad idea to force Realms
to be aware of each internal realm type and the mapping to a feature.
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 changed things around a bit.
The separation between Realms
and InternalRealms
is a bit weird, and many of the methods on InternalRealms
are redundant in production code, but are used widely in tests.
We ought to refactor things a bit, but this isn't the PR for it.
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.
One thing to note is that getFactories
duplicates the list of realm types, so I think we might want something like:
private static class InternalRealm {
String type;
Realm.Factory factory;
@Nullable LicensedFeature.Persistent licensedFeature;
}
And then have a Map
of those.
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.
Thanks Tim. You proposal of having a class of InternalRealm
to represent the Realm at the concept level* sounds good to me. And I agree it does not belong to this PR.
* "Concept level" may not be really descriptive for its purpose. My intention is to differentiate it from the runtime class Realm
and the configuration class RealmConfig
.
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.
A couple general thoughts but I defer to Yang for details.
// Standard realms (LDAP, AD, PKI, etc) are Gold+ | ||
// Some realms (LDAP, AD, PKI) are Gold+ | ||
public static final LicensedFeature.Persistent LDAP_REALM_FEATURE = | ||
LicensedFeature.persistentLenient(null, "security_ldap_realm", License.OperationMode.GOLD); |
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 also think we should have a family of “security” or “security-realms”, and the feature name can just be eg “ldap-realm”.
} else { | ||
Security.ALL_REALMS_FEATURE.stopTracking(licenseStateSnapshot, realm.name()); | ||
final LicensedFeature.Persistent feature = getLicensedFeatureForRealm(realm.type()); | ||
if (feature != null) { |
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.
When is null possible? Shouldn’t it always have a feature object since unknown should fallback to custom?
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.
It will be null
if it's basic licensed.
In master that shouldn't happen because a basic licensed realm cannot become inactive at runtime. In 7.x it can because of the hoops we jump through to provide a default set of basic licensed realms if the configured realms are unlicensed (and the reverse behaviour when the configured realms become licensed again will mean that those basic realms are no longer active).
I'll switch to an assert here instead, but convert it to an if
on backport.
public static final LicensedFeature.Persistent LDAP_REALM_FEATURE = | ||
LicensedFeature.persistentLenient(REALMS_FEATURE_FAMILY, "ldap", License.OperationMode.GOLD); | ||
public static final LicensedFeature.Persistent AD_REALM_FEATURE = | ||
LicensedFeature.persistentLenient(REALMS_FEATURE_FAMILY, "active_directory", License.OperationMode.GOLD); |
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.
Can we please use active-directory
here for consistency with other new features that are using dashes instead of underscore?
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 can, but the realm type in settings is active_directory
so we'll lose that consistency.
💔 Backport failed
You can use sqren/backport to manually backport by running |
This commit changes the licensed feature usage tracking for realms to record each realm type as its own separate feature. Custom realms continue to fall under a single catch-all feature. Backport of: elastic#78810
This commit changes the licensed feature usage tracking for realms to record each realm type as its own separate feature. Custom realms continue to fall under a single catch-all feature. Backport of: #78810
This commit changes the licensed feature usage tracking for realms to
record each realm type as its own separate feature.
Custom realms continue to fall under a single catch-all feature.