mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 17:05:18 +00:00
4e8c5e7f86
This PR adds a new Host details page as part of the Hosts UI project #162 Summary of changes: - New component <HostDetailsPage /> - Move "Query" and "Delete" buttons from the hosts list to the Host details page - Add new button variants label and text-link - Add react-tooltip package to the project (v4.2.13)
263 lines
6.7 KiB
JavaScript
263 lines
6.7 KiB
JavaScript
import { flatMap, omit, pick, size } from 'lodash';
|
|
import md5 from 'js-md5';
|
|
import moment from 'moment';
|
|
|
|
const ORG_INFO_ATTRS = ['org_name', 'org_logo_url'];
|
|
const ADMIN_ATTRS = ['email', 'name', 'password', 'password_confirmation', 'username'];
|
|
|
|
export const addGravatarUrlToResource = (resource) => {
|
|
const { email } = resource;
|
|
|
|
const emailHash = md5(email.toLowerCase());
|
|
const gravatarURL = `https://www.gravatar.com/avatar/${emailHash}?d=blank&size=200`;
|
|
|
|
return {
|
|
...resource,
|
|
gravatarURL,
|
|
};
|
|
};
|
|
|
|
const labelSlug = (label) => {
|
|
const { id, name } = label;
|
|
|
|
if (name === 'All Hosts') {
|
|
return 'all-hosts';
|
|
}
|
|
|
|
return `labels/${id}`;
|
|
};
|
|
|
|
const labelStubs = [
|
|
{
|
|
id: 'new',
|
|
count: 0,
|
|
description: 'Hosts that have been enrolled to Fleet in the last 24 hours.',
|
|
display_text: 'New',
|
|
slug: 'new',
|
|
statusLabelKey: 'new_count',
|
|
title_description: '(added in last 24hrs)',
|
|
type: 'status',
|
|
},
|
|
{
|
|
id: 'online',
|
|
count: 0,
|
|
description: 'Hosts that have recently checked-in to Fleet and are ready to run queries.',
|
|
display_text: 'Online',
|
|
slug: 'online',
|
|
statusLabelKey: 'online_count',
|
|
type: 'status',
|
|
},
|
|
{
|
|
id: 'offline',
|
|
count: 0,
|
|
description: 'Hosts that have not checked-in to Fleet recently.',
|
|
display_text: 'Offline',
|
|
slug: 'offline',
|
|
statusLabelKey: 'offline_count',
|
|
type: 'status',
|
|
},
|
|
{
|
|
id: 'mia',
|
|
count: 0,
|
|
description: 'Hosts that have not been seen by Fleet in more than 30 days.',
|
|
display_text: 'MIA',
|
|
slug: 'mia',
|
|
statusLabelKey: 'mia_count',
|
|
title_description: '(offline > 30 days)',
|
|
type: 'status',
|
|
},
|
|
];
|
|
|
|
const filterTarget = (targetType) => {
|
|
return (target) => {
|
|
return target.target_type === targetType ? [target.id] : [];
|
|
};
|
|
};
|
|
|
|
export const formatConfigDataForServer = (config) => {
|
|
const orgInfoAttrs = pick(config, ['org_logo_url', 'org_name']);
|
|
const serverSettingsAttrs = pick(config, ['kolide_server_url', 'osquery_enroll_secret', 'live_query_disabled']);
|
|
const smtpSettingsAttrs = pick(config, [
|
|
'authentication_method', 'authentication_type', 'domain', 'enable_ssl_tls',
|
|
'enable_start_tls', 'password', 'port', 'sender_address', 'server', 'user_name', 'verify_ssl_certs',
|
|
'enable_smtp',
|
|
]);
|
|
const ssoSettingsAttrs = pick(config, ['entity_id', 'issuer_uri', 'idp_image_url', 'metadata',
|
|
'metadata_url', 'idp_name', 'enable_sso',
|
|
]);
|
|
const hostExpirySettingsAttrs = pick(config, ['host_expiry_enabled', 'host_expiry_window']);
|
|
|
|
const orgInfo = size(orgInfoAttrs) && { org_info: orgInfoAttrs };
|
|
const serverSettings = size(serverSettingsAttrs) && { server_settings: serverSettingsAttrs };
|
|
const smtpSettings = size(smtpSettingsAttrs) && { smtp_settings: smtpSettingsAttrs };
|
|
const ssoSettings = size(ssoSettingsAttrs) && { sso_settings: ssoSettingsAttrs };
|
|
const hostExpirySettings = size(hostExpirySettingsAttrs) && { host_expiry_settings: hostExpirySettingsAttrs };
|
|
|
|
if (hostExpirySettings) {
|
|
hostExpirySettings.host_expiry_settings.host_expiry_window = Number(hostExpirySettings.host_expiry_settings.host_expiry_window);
|
|
}
|
|
|
|
return {
|
|
...orgInfo,
|
|
...serverSettings,
|
|
...smtpSettings,
|
|
...ssoSettings,
|
|
...hostExpirySettings,
|
|
};
|
|
};
|
|
|
|
const formatLabelResponse = (response) => {
|
|
const labelTypeForDisplayText = {
|
|
'All Hosts': 'all',
|
|
'MS Windows': 'platform',
|
|
'CentOS Linux': 'platform',
|
|
macOS: 'platform',
|
|
'Ubuntu Linux': 'platform',
|
|
};
|
|
|
|
const labels = response.labels.map((label) => {
|
|
return {
|
|
...label,
|
|
slug: labelSlug(label),
|
|
type: labelTypeForDisplayText[label.display_text] || 'custom',
|
|
};
|
|
});
|
|
|
|
return labels.concat(labelStubs);
|
|
};
|
|
|
|
export const formatSelectedTargetsForApi = (selectedTargets, appendID = false) => {
|
|
const targets = selectedTargets || [];
|
|
const hosts = flatMap(targets, filterTarget('hosts'));
|
|
const labels = flatMap(targets, filterTarget('labels'));
|
|
|
|
if (appendID) {
|
|
return { host_ids: hosts, label_ids: labels };
|
|
}
|
|
|
|
return { hosts, labels };
|
|
};
|
|
|
|
export const formatScheduledQueryForServer = (scheduledQuery) => {
|
|
const {
|
|
interval,
|
|
logging_type: loggingType,
|
|
pack_id: packID,
|
|
platform,
|
|
query_id: queryID,
|
|
shard,
|
|
} = scheduledQuery;
|
|
const result = omit(scheduledQuery, ['logging_type']);
|
|
|
|
if (platform === 'all') {
|
|
result.platform = '';
|
|
}
|
|
|
|
if (interval) {
|
|
result.interval = Number(interval);
|
|
}
|
|
|
|
if (loggingType) {
|
|
result.removed = loggingType === 'differential';
|
|
result.snapshot = loggingType === 'snapshot';
|
|
}
|
|
|
|
if (packID) {
|
|
result.pack_id = Number(packID);
|
|
}
|
|
|
|
if (queryID) {
|
|
result.query_id = Number(queryID);
|
|
}
|
|
|
|
if (shard) {
|
|
result.shard = Number(shard);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
export const formatScheduledQueryForClient = (scheduledQuery) => {
|
|
if (scheduledQuery.platform === '') {
|
|
scheduledQuery.platform = 'all';
|
|
}
|
|
|
|
if (scheduledQuery.snapshot) {
|
|
scheduledQuery.logging_type = 'snapshot';
|
|
} else {
|
|
scheduledQuery.snapshot = false;
|
|
if (scheduledQuery.removed === false) {
|
|
scheduledQuery.logging_type = 'differential_ignore_removals';
|
|
} else {
|
|
// If both are unset, we should default to differential (like osquery does)
|
|
scheduledQuery.logging_type = 'differential';
|
|
}
|
|
}
|
|
|
|
if (scheduledQuery.shard === null) {
|
|
scheduledQuery.shard = undefined;
|
|
}
|
|
|
|
return scheduledQuery;
|
|
};
|
|
|
|
const setupData = (formData) => {
|
|
const orgInfo = pick(formData, ORG_INFO_ATTRS);
|
|
const adminInfo = pick(formData, ADMIN_ATTRS);
|
|
|
|
return {
|
|
kolide_server_url: formData.kolide_server_url,
|
|
org_info: {
|
|
...orgInfo,
|
|
},
|
|
admin: {
|
|
admin: true,
|
|
...adminInfo,
|
|
},
|
|
};
|
|
};
|
|
|
|
const BYTES_PER_GIGABYTE = 1074000000;
|
|
const NANOSECONDS_PER_MILLISECOND = 1000000;
|
|
|
|
const inGigaBytes = (bytes) => {
|
|
return (bytes / BYTES_PER_GIGABYTE).toFixed(1);
|
|
};
|
|
|
|
const inMilliseconds = (nanoseconds) => {
|
|
return nanoseconds / NANOSECONDS_PER_MILLISECOND;
|
|
};
|
|
|
|
export const humanHostUptime = (uptimeInNanoseconds) => {
|
|
const milliseconds = inMilliseconds(uptimeInNanoseconds);
|
|
|
|
return moment.duration(milliseconds, 'milliseconds').humanize();
|
|
};
|
|
|
|
export const humanHostLastSeen = (lastSeen) => {
|
|
return moment(lastSeen).format('MMM D YYYY, HH:mm:ss');
|
|
};
|
|
|
|
export const humanHostEnrolled = (enrolled) => {
|
|
return moment(enrolled).format('MMM D YYYY, HH:mm:ss');
|
|
};
|
|
|
|
export const humanHostMemory = (bytes) => {
|
|
return `${inGigaBytes(bytes)} GB`;
|
|
};
|
|
|
|
export default {
|
|
addGravatarUrlToResource,
|
|
formatConfigDataForServer,
|
|
formatLabelResponse,
|
|
formatScheduledQueryForClient,
|
|
formatScheduledQueryForServer,
|
|
formatSelectedTargetsForApi,
|
|
humanHostUptime,
|
|
humanHostLastSeen,
|
|
humanHostEnrolled,
|
|
humanHostMemory,
|
|
labelSlug,
|
|
setupData,
|
|
};
|