mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Agentless Telemetry
This commit is contained in:
parent
78fb6883f1
commit
f4c9a700d5
4 changed files with 158 additions and 9 deletions
|
@ -3981,6 +3981,58 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"agentless_agents": {
|
||||
"properties": {
|
||||
"total_enrolled": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of enrolled agents, in any state"
|
||||
}
|
||||
},
|
||||
"healthy": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of enrolled agents in a healthy state"
|
||||
}
|
||||
},
|
||||
"unhealthy": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of enrolled agents in an unhealthy state"
|
||||
}
|
||||
},
|
||||
"updating": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of enrolled agents in an updating state"
|
||||
}
|
||||
},
|
||||
"offline": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of enrolled agents currently offline"
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of of enrolled agents currently inactive"
|
||||
}
|
||||
},
|
||||
"unenrolled": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of agents currently unenrolled"
|
||||
}
|
||||
},
|
||||
"total_all_statuses": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of agents in any state, both enrolled and inactive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
import type { SavedObjectsClient, ElasticsearchClient } from '@kbn/core/server';
|
||||
|
||||
import { AGENTS_INDEX } from '../../common';
|
||||
import { AGENTS_INDEX, LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE } from '../../common';
|
||||
import * as AgentService from '../services/agents';
|
||||
import { appContextService } from '../services';
|
||||
import { agentPolicyService, appContextService } from '../services';
|
||||
import { getAgentStatusForAgentPolicy } from '../services/agents';
|
||||
|
||||
export interface AgentStatus {
|
||||
|
@ -28,7 +28,8 @@ export interface AgentUsage extends AgentStatus {
|
|||
|
||||
export const getAgentUsage = async (
|
||||
soClient?: SavedObjectsClient,
|
||||
esClient?: ElasticsearchClient
|
||||
esClient?: ElasticsearchClient,
|
||||
onlyAgentless?: boolean
|
||||
): Promise<AgentUsage> => {
|
||||
// TODO: unsure if this case is possible at all.
|
||||
if (!soClient || !esClient) {
|
||||
|
@ -44,8 +45,26 @@ export const getAgentUsage = async (
|
|||
};
|
||||
}
|
||||
|
||||
let agentPolicyIds;
|
||||
if (onlyAgentless) {
|
||||
const agentPolicies = await agentPolicyService.list(soClient, {
|
||||
perPage: 1000, // avoiding pagination
|
||||
withPackagePolicies: true,
|
||||
kuery: `${LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE}.supports_agentless:true`,
|
||||
});
|
||||
|
||||
agentPolicyIds = agentPolicies.items.map((agentPolicy) => agentPolicy.id);
|
||||
}
|
||||
|
||||
const { total, inactive, online, error, offline, updating, unenrolled } =
|
||||
await AgentService.getAgentStatusForAgentPolicy(esClient, soClient);
|
||||
await AgentService.getAgentStatusForAgentPolicy(
|
||||
esClient,
|
||||
soClient,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
agentPolicyIds
|
||||
);
|
||||
return {
|
||||
total_enrolled: total,
|
||||
healthy: online,
|
||||
|
|
|
@ -12,12 +12,19 @@ import { getPackageSavedObjects } from '../services/epm/packages/get';
|
|||
import { agentPolicyService } from '../services';
|
||||
import type { NewPackagePolicy } from '../types';
|
||||
|
||||
import type { AgentUsage } from './agent_collectors';
|
||||
|
||||
export interface PackageUsage {
|
||||
name: string;
|
||||
version: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface AgentlessUsage {
|
||||
agentlessPackages: PackageUsage[];
|
||||
agentlessAgents: AgentUsage;
|
||||
}
|
||||
|
||||
export const getPackageUsage = async (soClient?: SavedObjectsClient): Promise<PackageUsage[]> => {
|
||||
if (!soClient) {
|
||||
return [];
|
||||
|
@ -34,17 +41,35 @@ export const getPackageUsage = async (soClient?: SavedObjectsClient): Promise<Pa
|
|||
const packagesInAgentPolicies = agentPolicies.items.map((agentPolicy) => {
|
||||
const packagePolicies: NewPackagePolicy[] = agentPolicy.package_policies as NewPackagePolicy[];
|
||||
return packagePolicies
|
||||
.map((packagePolicy) => packagePolicy.package?.name)
|
||||
.filter((packageName): packageName is string => packageName !== undefined);
|
||||
.filter(
|
||||
(packagePolicy): packagePolicy is NewPackagePolicy =>
|
||||
packagePolicy.package?.name !== undefined && packagePolicy.supports_agentless !== true
|
||||
)
|
||||
.map((packagePolicy) => packagePolicy.package?.name);
|
||||
});
|
||||
|
||||
const enabledPackages = _.uniq(_.flatten(packagesInAgentPolicies));
|
||||
|
||||
const packagesInAgentlessPolicies = agentPolicies.items.map((agentPolicy) => {
|
||||
const packagePolicies: NewPackagePolicy[] = agentPolicy.package_policies as NewPackagePolicy[];
|
||||
return packagePolicies
|
||||
.filter(
|
||||
(packagePolicy): packagePolicy is NewPackagePolicy =>
|
||||
packagePolicy.package?.name !== undefined && packagePolicy.supports_agentless === true
|
||||
)
|
||||
.map((packagePolicy) => packagePolicy.package?.name);
|
||||
});
|
||||
const enabledAgentlessPackages = _.uniq(_.flatten(packagesInAgentlessPolicies));
|
||||
|
||||
return packagesSavedObjects.saved_objects.map((p) => {
|
||||
const agentBased = enabledPackages.includes(p.attributes.name);
|
||||
const agentless = enabledAgentlessPackages.includes(p.attributes.name);
|
||||
const enabled = agentBased || agentless;
|
||||
return {
|
||||
name: p.attributes.name,
|
||||
version: p.attributes.version,
|
||||
enabled: enabledPackages.includes(p.attributes.name),
|
||||
enabled,
|
||||
...(enabled && agentBased && { agent_based: true }), // Only include if true
|
||||
...(enabled && agentless && { agentless: true }), // Only include if true
|
||||
};
|
||||
});
|
||||
};
|
||||
|
|
|
@ -34,6 +34,7 @@ export interface Usage {
|
|||
agents: AgentUsage;
|
||||
packages: PackageUsage[];
|
||||
fleet_server: FleetServerUsage;
|
||||
agentless_agents: AgentUsage;
|
||||
}
|
||||
|
||||
export interface FleetUsage extends Usage, AgentData {
|
||||
|
@ -75,18 +76,20 @@ export const fetchFleetUsage = async (
|
|||
license_issued_to: (await esClient.license.get()).license.issued_to,
|
||||
deployment_id: appContextService.getCloud()?.deploymentId,
|
||||
integrations_details: await getIntegrationsDetails(soClient),
|
||||
agentless_agents: await getAgentUsage(soClient, esClient, true),
|
||||
};
|
||||
return usage;
|
||||
};
|
||||
|
||||
// used by kibana daily collector
|
||||
const fetchUsage = async (core: CoreSetup, config: FleetConfigType) => {
|
||||
const fetchUsage = async (core: CoreSetup, config: FleetConfigType): Promise<Usage> => {
|
||||
const [soClient, esClient] = await getInternalClients(core);
|
||||
const usage = {
|
||||
agents_enabled: getIsAgentsEnabled(config),
|
||||
agents: await getAgentUsage(soClient, esClient),
|
||||
fleet_server: await getFleetServerUsage(soClient, esClient),
|
||||
packages: await getPackageUsage(soClient),
|
||||
agentless_agents: await getAgentUsage(soClient, esClient, true),
|
||||
};
|
||||
return usage;
|
||||
};
|
||||
|
@ -236,6 +239,56 @@ export function registerFleetUsageCollector(
|
|||
enabled: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
agentless_agents: {
|
||||
total_enrolled: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of enrolled agents, in any state',
|
||||
},
|
||||
},
|
||||
healthy: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of enrolled agents in a healthy state',
|
||||
},
|
||||
},
|
||||
unhealthy: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of enrolled agents in an unhealthy state',
|
||||
},
|
||||
},
|
||||
updating: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of enrolled agents in an updating state',
|
||||
},
|
||||
},
|
||||
offline: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of enrolled agents currently offline',
|
||||
},
|
||||
},
|
||||
inactive: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of of enrolled agents currently inactive',
|
||||
},
|
||||
},
|
||||
unenrolled: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of agents currently unenrolled',
|
||||
},
|
||||
},
|
||||
total_all_statuses: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of agents in any state, both enrolled and inactive',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue