Skip to content

Commit 201b25e

Browse files
authored
Fix xpack info and usage reports for operator privileges (#65867)
This is a follow-up PR for #65256 to fix the xpack info and usage reports for operator privilegs. In summary, this PR ensures: * _xpack does not report operator privileges because it is categorised under security * _xpack/usage reports operator privileges status under the security section * _license/feature_usage reports last used time of operator privileges. It is up to the downstream to filter out this report if necessary.
1 parent 7f61898 commit 201b25e

File tree

9 files changed

+35
-64
lines changed

9 files changed

+35
-64
lines changed

docs/reference/rest-api/info.asciidoc

-4
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ Example response:
103103
"available" : true,
104104
"enabled" : true
105105
},
106-
"operator_privileges": {
107-
"available": true,
108-
"enabled": false
109-
},
110106
"rollup": {
111107
"available": true,
112108
"enabled": true

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/XPackInfoFeatureAction.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,14 @@ public class XPackInfoFeatureAction extends ActionType<XPackInfoFeatureResponse>
4747
public static final XPackInfoFeatureAction DATA_STREAMS = new XPackInfoFeatureAction(XPackField.DATA_STREAMS);
4848
public static final XPackInfoFeatureAction DATA_TIERS = new XPackInfoFeatureAction(XPackField.DATA_TIERS);
4949
public static final XPackInfoFeatureAction AGGREGATE_METRIC = new XPackInfoFeatureAction(XPackField.AGGREGATE_METRIC);
50-
public static final XPackInfoFeatureAction OPERATOR_PRIVILEGES = new XPackInfoFeatureAction(XPackField.OPERATOR_PRIVILEGES);
5150

5251
public static final List<XPackInfoFeatureAction> ALL;
5352
static {
5453
final List<XPackInfoFeatureAction> actions = new ArrayList<>();
5554
actions.addAll(Arrays.asList(
5655
SECURITY, MONITORING, WATCHER, GRAPH, MACHINE_LEARNING, LOGSTASH, EQL, SQL, ROLLUP, INDEX_LIFECYCLE, SNAPSHOT_LIFECYCLE, CCR,
5756
TRANSFORM, VECTORS, VOTING_ONLY, FROZEN_INDICES, SPATIAL, ANALYTICS, ENRICH, DATA_STREAMS, SEARCHABLE_SNAPSHOTS, DATA_TIERS,
58-
AGGREGATE_METRIC, OPERATOR_PRIVILEGES
57+
AGGREGATE_METRIC
5958
));
6059
ALL = Collections.unmodifiableList(actions);
6160
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityFeatureSetUsage.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class SecurityFeatureSetUsage extends XPackFeatureSet.Usage {
2828
private static final String IP_FILTER_XFIELD = "ipfilter";
2929
private static final String ANONYMOUS_XFIELD = "anonymous";
3030
private static final String FIPS_140_XFIELD = "fips_140";
31+
private static final String OPERATOR_PRIVILEGES_XFIELD = XPackField.OPERATOR_PRIVILEGES;
3132

3233
private Map<String, Object> realmsUsage;
3334
private Map<String, Object> rolesStoreUsage;
@@ -39,6 +40,7 @@ public class SecurityFeatureSetUsage extends XPackFeatureSet.Usage {
3940
private Map<String, Object> anonymousUsage;
4041
private Map<String, Object> roleMappingStoreUsage;
4142
private Map<String, Object> fips140Usage;
43+
private Map<String, Object> operatorPrivilegesUsage;
4244

4345
public SecurityFeatureSetUsage(StreamInput in) throws IOException {
4446
super(in);
@@ -56,14 +58,17 @@ public SecurityFeatureSetUsage(StreamInput in) throws IOException {
5658
if (in.getVersion().onOrAfter(Version.V_7_5_0)) {
5759
fips140Usage = in.readMap();
5860
}
61+
if (in.getVersion().onOrAfter(Version.V_7_11_0)) {
62+
operatorPrivilegesUsage = in.readMap();
63+
}
5964
}
6065

6166
public SecurityFeatureSetUsage(boolean available, boolean enabled, Map<String, Object> realmsUsage,
6267
Map<String, Object> rolesStoreUsage, Map<String, Object> roleMappingStoreUsage,
6368
Map<String, Object> sslUsage, Map<String, Object> auditUsage,
6469
Map<String, Object> ipFilterUsage, Map<String, Object> anonymousUsage,
6570
Map<String, Object> tokenServiceUsage, Map<String, Object> apiKeyServiceUsage,
66-
Map<String, Object> fips140Usage) {
71+
Map<String, Object> fips140Usage, Map<String, Object> operatorPrivilegesUsage) {
6772
super(XPackField.SECURITY, available, enabled);
6873
this.realmsUsage = realmsUsage;
6974
this.rolesStoreUsage = rolesStoreUsage;
@@ -75,6 +80,7 @@ public SecurityFeatureSetUsage(boolean available, boolean enabled, Map<String, O
7580
this.ipFilterUsage = ipFilterUsage;
7681
this.anonymousUsage = anonymousUsage;
7782
this.fips140Usage = fips140Usage;
83+
this.operatorPrivilegesUsage = operatorPrivilegesUsage;
7884
}
7985

8086
@Override
@@ -99,6 +105,9 @@ public void writeTo(StreamOutput out) throws IOException {
99105
if (out.getVersion().onOrAfter(Version.V_7_5_0)) {
100106
out.writeMap(fips140Usage);
101107
}
108+
if (out.getVersion().onOrAfter(Version.V_7_11_0)) {
109+
out.writeMap(operatorPrivilegesUsage);
110+
}
102111
}
103112

104113
@Override
@@ -115,6 +124,7 @@ protected void innerXContent(XContentBuilder builder, Params params) throws IOEx
115124
builder.field(IP_FILTER_XFIELD, ipFilterUsage);
116125
builder.field(ANONYMOUS_XFIELD, anonymousUsage);
117126
builder.field(FIPS_140_XFIELD, fips140Usage);
127+
builder.field(OPERATOR_PRIVILEGES_XFIELD, operatorPrivilegesUsage);
118128
} else if (sslUsage.isEmpty() == false) {
119129
// A trial (or basic) license can have SSL without security.
120130
// This is because security defaults to disabled on that license, but that dynamic-default does not disable SSL.

x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java

-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ public class Constants {
244244
"cluster:monitor/xpack/info/logstash",
245245
"cluster:monitor/xpack/info/ml",
246246
"cluster:monitor/xpack/info/monitoring",
247-
"cluster:monitor/xpack/info/operator_privileges",
248247
"cluster:monitor/xpack/info/rollup",
249248
"cluster:monitor/xpack/info/searchable_snapshots",
250249
"cluster:monitor/xpack/info/security",

x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/OperatorPrivilegesIT.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ public void testEveryActionIsEitherOperatorOnlyOrNonOperator() throws IOExceptio
9292
}
9393

9494
@SuppressWarnings("unchecked")
95-
public void testOperatorPrivilegesXpackInfo() throws IOException {
96-
final Request xpackRequest = new Request("GET", "/_xpack");
95+
public void testOperatorPrivilegesXpackUsage() throws IOException {
96+
final Request xpackRequest = new Request("GET", "/_xpack/usage");
9797
final Map<String, Object> response = entityAsMap(client().performRequest(xpackRequest));
98-
final Map<String, Object> features = (Map<String, Object>) response.get("features");
98+
final Map<String, Object> features = (Map<String, Object>) response.get("security");
9999
final Map<String, Object> operatorPrivileges = (Map<String, Object>) features.get("operator_privileges");
100100
assertTrue((boolean) operatorPrivileges.get("available"));
101101
assertTrue((boolean) operatorPrivileges.get("enabled"));

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@
218218
import org.elasticsearch.xpack.security.operator.OperatorPrivileges;
219219
import org.elasticsearch.xpack.security.operator.OperatorPrivileges.OperatorPrivilegesService;
220220
import org.elasticsearch.xpack.security.operator.FileOperatorUsersStore;
221-
import org.elasticsearch.xpack.security.operator.OperatorPrivilegesInfoTransportAction;
222221
import org.elasticsearch.xpack.security.rest.SecurityRestFilter;
223222
import org.elasticsearch.xpack.security.rest.action.RestAuthenticateAction;
224223
import org.elasticsearch.xpack.security.rest.action.apikey.RestClearApiKeyCacheAction;
@@ -771,9 +770,8 @@ public void onIndexModule(IndexModule module) {
771770
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
772771
var usageAction = new ActionHandler<>(XPackUsageFeatureAction.SECURITY, SecurityUsageTransportAction.class);
773772
var infoAction = new ActionHandler<>(XPackInfoFeatureAction.SECURITY, SecurityInfoTransportAction.class);
774-
var opInfoAction = new ActionHandler<>(XPackInfoFeatureAction.OPERATOR_PRIVILEGES, OperatorPrivilegesInfoTransportAction.class);
775773
if (enabled == false) {
776-
return Arrays.asList(usageAction, infoAction, opInfoAction);
774+
return Arrays.asList(usageAction, infoAction);
777775
}
778776
return Arrays.asList(
779777
new ActionHandler<>(ClearRealmCacheAction.INSTANCE, TransportClearRealmCacheAction.class),
@@ -818,8 +816,7 @@ public void onIndexModule(IndexModule module) {
818816
new ActionHandler<>(GetApiKeyAction.INSTANCE, TransportGetApiKeyAction.class),
819817
new ActionHandler<>(DelegatePkiAuthenticationAction.INSTANCE, TransportDelegatePkiAuthenticationAction.class),
820818
usageAction,
821-
infoAction,
822-
opInfoAction);
819+
infoAction);
823820
}
824821

825822
@Override

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityUsageTransportAction.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.xpack.security.authc.Realms;
3030
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
3131
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
32+
import org.elasticsearch.xpack.security.operator.OperatorPrivileges;
3233
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
3334

3435
import java.util.Arrays;
@@ -77,6 +78,10 @@ protected void masterOperation(Task task, XPackUsageRequest request, ClusterStat
7778
Map<String, Object> ipFilterUsage = ipFilterUsage(ipFilter);
7879
Map<String, Object> anonymousUsage = singletonMap("enabled", AnonymousUser.isAnonymousEnabled(settings));
7980
Map<String, Object> fips140Usage = fips140Usage(settings);
81+
Map<String, Object> operatorPrivilegesUsage = Map.of(
82+
"available", licenseState.isAllowed(XPackLicenseState.Feature.OPERATOR_PRIVILEGES),
83+
"enabled", OperatorPrivileges.OPERATOR_PRIVILEGES_ENABLED.get(settings)
84+
);
8085

8186
final AtomicReference<Map<String, Object>> rolesUsageRef = new AtomicReference<>();
8287
final AtomicReference<Map<String, Object>> roleMappingUsageRef = new AtomicReference<>();
@@ -88,7 +93,7 @@ protected void masterOperation(Task task, XPackUsageRequest request, ClusterStat
8893
if (countDown.countDown()) {
8994
var usage = new SecurityFeatureSetUsage(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY), enabled,
9095
realmsUsageRef.get(), rolesUsageRef.get(), roleMappingUsageRef.get(), sslUsage, auditUsage,
91-
ipFilterUsage, anonymousUsage, tokenServiceUsage, apiKeyServiceUsage, fips140Usage);
96+
ipFilterUsage, anonymousUsage, tokenServiceUsage, apiKeyServiceUsage, fips140Usage, operatorPrivilegesUsage);
9297
listener.onResponse(new XPackUsageFeatureResponse(usage));
9398
}
9499
};

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/operator/OperatorPrivilegesInfoTransportAction.java

-47
This file was deleted.

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,10 @@ public void testUsage() throws Exception {
9494
final boolean authcAuthzAvailable = randomBoolean();
9595
final boolean explicitlyDisabled = randomBoolean();
9696
final boolean enabled = explicitlyDisabled == false && randomBoolean();
97+
final boolean operatorPrivilegesAvailable = randomBoolean();
9798
when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(authcAuthzAvailable);
9899
when(licenseState.isSecurityEnabled()).thenReturn(enabled);
100+
when(licenseState.isAllowed(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(operatorPrivilegesAvailable);
99101

100102
Settings.Builder settings = Settings.builder().put(this.settings);
101103

@@ -160,6 +162,10 @@ public void testUsage() throws Exception {
160162
if (fips140Enabled) {
161163
settings.put("xpack.security.fips_mode.enabled", true);
162164
}
165+
final boolean operatorPrivilegesEnabled = randomBoolean();
166+
if (operatorPrivilegesEnabled) {
167+
settings.put("xpack.security.operator_privileges.enabled", true);
168+
}
163169

164170
var usageAction = newUsageAction(settings.build());
165171
PlainActionFuture<XPackUsageFeatureResponse> future = new PlainActionFuture<>();
@@ -229,6 +235,10 @@ public void testUsage() throws Exception {
229235

230236
// FIPS 140
231237
assertThat(source.getValue("fips_140.enabled"), is(fips140Enabled));
238+
239+
// operator privileges
240+
assertThat(source.getValue("operator_privileges.available"), is(operatorPrivilegesAvailable));
241+
assertThat(source.getValue("operator_privileges.enabled"), is(operatorPrivilegesEnabled));
232242
} else {
233243
if (explicitlyDisabled) {
234244
assertThat(source.getValue("ssl"), is(nullValue()));
@@ -243,6 +253,7 @@ public void testUsage() throws Exception {
243253
assertThat(source.getValue("anonymous"), is(nullValue()));
244254
assertThat(source.getValue("ipfilter"), is(nullValue()));
245255
assertThat(source.getValue("roles"), is(nullValue()));
256+
assertThat(source.getValue("operator_privileges"), is(nullValue()));
246257
}
247258
}
248259
}
@@ -296,6 +307,7 @@ public void testUsageOnTrialLicenseWithSecurityDisabledByDefault() throws Except
296307
assertThat(source.getValue("anonymous"), is(nullValue()));
297308
assertThat(source.getValue("ipfilter"), is(nullValue()));
298309
assertThat(source.getValue("roles"), is(nullValue()));
310+
assertThat(source.getValue("operator_privileges"), is(nullValue()));
299311
}
300312
}
301313

0 commit comments

Comments
 (0)