Skip to content

Commit

Permalink
Creating flare index on first configuration and let user change their…
Browse files Browse the repository at this point in the history
… cron job index in the configuration screen
  • Loading branch information
Marc-Antoine Hinse committed Nov 18, 2024
1 parent b1c1f39 commit 3416924
Show file tree
Hide file tree
Showing 14 changed files with 226 additions and 127 deletions.
28 changes: 23 additions & 5 deletions packages/configuration-screen/src/ConfigurationScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { useEffect, useState, FC } from 'react';
import {
appName,
createFlareIndex,
redirectToHomepage,
retrieveApiKey,
retrieveAvailableIndexNames,
retrieveCurrentIndexName,
retrieveIngestMetadataOnly,
retrieveTenantId,
retrieveUserTenants,
Expand All @@ -25,11 +29,13 @@ const TOAST_TENANT_SUCCESS = 'tenant_success';
const ConfigurationScreen: FC<{ theme: string }> = ({ theme }) => {
const [apiKey, setApiKey] = useState('');
const [tenantId, setTenantId] = useState(-1);
const [indexName, setIndexName] = useState(appName);
const [errorMessage, setErrorMessage] = useState('');
const [tenants, setUserTenants] = useState<Tenant[]>([]);
const [isIngestingMetadataOnly, setIsIngestingMetadataOnly] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [isCompleted, setIsCompleted] = useState(false);
const [indexNames, setIndexNames] = useState<string[]>([]);

toastManager.setTheme(theme);

Expand All @@ -54,6 +60,7 @@ const ConfigurationScreen: FC<{ theme: string }> = ({ theme }) => {

const handleApiKeyChange = (e): void => setApiKey(e.target.value);
const handleTenantIdChange = (e): void => setTenantId(parseInt(e.target.value, 10));
const handleIndexNameChange = (e): void => setIndexName(e.target.value);
const handleIsIngestingMetadataChange = (e): void => {
setIsIngestingMetadataOnly(e.target.checked);
};
Expand Down Expand Up @@ -95,7 +102,7 @@ const ConfigurationScreen: FC<{ theme: string }> = ({ theme }) => {

const handleSubmitTenant = (): void => {
setIsLoading(true);
saveConfiguration(apiKey, tenantId, isIngestingMetadataOnly)
saveConfiguration(apiKey, tenantId, indexName, isIngestingMetadataOnly)
.then(() => {
setIsLoading(false);
setIsCompleted(true);
Expand Down Expand Up @@ -128,13 +135,21 @@ const ConfigurationScreen: FC<{ theme: string }> = ({ theme }) => {
if (isCompleted) {
return;
}
Promise.all([retrieveApiKey(), retrieveTenantId(), retrieveIngestMetadataOnly()]).then(
([key, id, ingestMetadataOnly]) => {
createFlareIndex().then(() => {
Promise.all([
retrieveApiKey(),
retrieveTenantId(),
retrieveIngestMetadataOnly(),
retrieveCurrentIndexName(),
retrieveAvailableIndexNames(),
]).then(([key, id, ingestMetadataOnly, index, availableIndexNames]) => {
setApiKey(key);
setTenantId(id);
setIsIngestingMetadataOnly(ingestMetadataOnly);
}
);
setIndexName(index);
setIndexNames(availableIndexNames);
});
});
}, [isCompleted]);

useEffect(() => {
Expand Down Expand Up @@ -178,11 +193,14 @@ const ConfigurationScreen: FC<{ theme: string }> = ({ theme }) => {
show={currentConfigurationStep === ConfigurationSteps.UserPreferences}
selectedTenantId={tenantId}
tenants={tenants}
selectedIndexName={indexName}
indexNames={indexNames}
isLoading={isLoading}
isIngestingMetadataOnly={isIngestingMetadataOnly}
onNavigateBackClick={handleBackButton}
onSubmitUserPreferencesClick={handleSubmitTenant}
onTenantIdChange={handleTenantIdChange}
onIndexNameChange={handleIndexNameChange}
onIngestingMetadataChange={handleIsIngestingMetadataChange}
/>
<ConfigurationCompletedStep
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useEffect, useState } from 'react';
import React, { FC } from 'react';
import Button from './Button';
import { getFlareDataUrl } from '../utils/setupConfiguration';
import ArrowRightIcon from './icons/ArrowRightIcon';
Expand All @@ -10,12 +10,6 @@ const ConfigurationCompletedStep: FC<{
tenantName: string;
onEditConfigurationClick: () => void;
}> = ({ show, tenantName, onEditConfigurationClick }) => {
const [indexName, setIndexName] = useState<string>();

useEffect(() => {
getFlareDataUrl().then((name) => setIndexName(name));
}, []);

return (
<div hidden={!show}>
<h5>
Expand All @@ -29,7 +23,7 @@ const ConfigurationCompletedStep: FC<{
Edit Configuration
</Button>
<div className="link">
<a href={indexName}>View Flare Data</a>
<a href={getFlareDataUrl()}>View Flare Data</a>
<ArrowRightIcon remSize={1} />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-top: 2.5rem;
margin-top: 1.5rem;
gap: 1rem;
}

Expand All @@ -13,6 +13,13 @@
width: 100%;
align-items: flex-start;
margin-top: 1rem;
gap: 1rem;
}

.form-item {
display: flex;
flex-direction: column;
align-items: flex-start;
}

.progress-bar-container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,30 @@ const ConfigurationInitialStep: FC<{
<div hidden={!show}>
<h5>Enter your API key</h5>
<div className="form-group">
<div className="label-tooltip">
<Label isRequired>API Key</Label>
<Tooltip>
<div>
{'You can find your API Keys in your '}
<a target="_blank" href="https://app.flare.io/#/profile">
Flare Profile
</a>
</div>
</Tooltip>
</div>
<input
id="apiKey"
type="password"
value={apiKey}
onChange={onApiKeyChange}
className={`input ${errorMessage.length > 0 ? 'border-error' : ''}`}
placeholder="Your API Key"
/>
<div className="error-container" hidden={errorMessage.length === 0}>
<ErrorIcon remSize={1} />
<small>Error. {errorMessage}</small>
<div className="form-item">
<div className="label-tooltip">
<Label isRequired>API Key</Label>
<Tooltip>
<div>
{'You can find your API Keys in your '}
<a target="_blank" href="https://app.flare.io/#/profile">
Flare Profile
</a>
</div>
</Tooltip>
</div>
<input
id="apiKey"
type="password"
value={apiKey}
onChange={onApiKeyChange}
className={`input ${errorMessage.length > 0 ? 'border-error' : ''}`}
placeholder="Your API Key"
/>
<div className="error-container" hidden={errorMessage.length === 0}>
<ErrorIcon remSize={1} />
<small>Error. {errorMessage}</small>
</div>
</div>
<div className="button-group">
<Button onClick={(): void => onCancelConfigurationClick()} isSecondary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
font-size: 0.75rem;
color: var(--secondary-text-color);
margin-top: 5px;
margin-bottom: 1rem;
}

.switch-layout {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,66 @@ const ConfigurationUserPreferencesStep: FC<{
show: boolean;
tenants: Tenant[];
selectedTenantId: number;
indexNames: string[];
selectedIndexName: string;
isLoading: boolean;
isIngestingMetadataOnly: boolean;
onNavigateBackClick: () => void;
onSubmitUserPreferencesClick: () => void;
onTenantIdChange: (e: ChangeEvent) => void;
onIndexNameChange: (e: ChangeEvent) => void;
onIngestingMetadataChange: (e: ChangeEvent) => void;
}> = ({
show,
tenants,
selectedTenantId,
indexNames,
selectedIndexName,
isLoading,
isIngestingMetadataOnly,
onNavigateBackClick,
onSubmitUserPreferencesClick,
onTenantIdChange,
onIndexNameChange,
onIngestingMetadataChange,
}) => {
return (
<div hidden={!show}>
<h5>Please select the Tenant you want to ingest events from</h5>
<div className="form-group">
<Label isRequired>Tenant</Label>
<Select id="tenants" onChange={onTenantIdChange} value={selectedTenantId}>
{tenants.map((tenant) => {
return (
<option key={tenants.indexOf(tenant)} value={tenant.id}>
{tenant.name}
</option>
);
})}
</Select>
<small className="note">You can only monitor one tenant at a time.</small>
<div className="switch-layout">
<span>Only ingest the metadata of events</span>
<Switch value={isIngestingMetadataOnly} onChange={onIngestingMetadataChange} />
<div className="form-item">
<Label>Tenant</Label>
<Select id="tenants" onChange={onTenantIdChange} value={selectedTenantId}>
{tenants.map((tenant) => {
return (
<option key={tenants.indexOf(tenant)} value={tenant.id}>
{tenant.name}
</option>
);
})}
</Select>
<small className="note">You can only monitor one tenant at a time.</small>
</div>
<div className="form-item">
<Label>Splunk Index for event ingestion</Label>
<Select id="indexes" onChange={onIndexNameChange} value={selectedIndexName}>
{indexNames.map((indexName) => {
return (
<option key={indexNames.indexOf(indexName)} value={indexName}>
{indexName}
</option>
);
})}
</Select>
</div>
<div className="form-item">
<div className="switch-layout">
<span>Only ingest the metadata of events</span>
<Switch
value={isIngestingMetadataOnly}
onChange={onIngestingMetadataChange}
/>
</div>
</div>
<div className="button-group">
<Button onClick={(): void => onNavigateBackClick()} isSecondary>
Expand Down
2 changes: 1 addition & 1 deletion packages/configuration-screen/src/components/Select.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ select {
border: 1px solid var(--secondary-text-color);
border-radius: 40px;
padding-right: 1rem;
margin-top: 1rem;
margin-top: 0.5rem;
}

.select-container:hover {
Expand Down
2 changes: 1 addition & 1 deletion packages/configuration-screen/src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ input {
input {
border: 1px solid var(--secondary-text-color);
border-radius: 40px;
margin-top: 1rem;
margin-top: 0.5rem;
}

input:hover {
Expand Down
14 changes: 12 additions & 2 deletions packages/configuration-screen/src/models/splunk.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import '../vendor/splunk.min.js';

export interface SplunkApplicationNamespace {
app?: string;
owner?: string;
Expand All @@ -13,6 +11,10 @@ export interface SplunkPassword {
};
}

export interface SplunkIndex {
name: string;
}

export interface SplunkAppAccessor {
reload: () => void;
}
Expand Down Expand Up @@ -51,6 +53,13 @@ export interface ConfigurationsAccessor {
list: () => Array<{ name: string }>;
}

export interface SplunkIndexesAccessor {
fetch: () => SplunkIndexesAccessor;
create: (indexName: string, data: any) => void;
item: (indexName: string) => SplunkIndex;
list: () => Array<SplunkIndex>;
}

export interface SplunkStoragePasswordAccessors {
fetch: () => SplunkStoragePasswordAccessors;
item: (applicationName: string) => SplunkAppAccessor;
Expand All @@ -63,6 +72,7 @@ export interface SplunkService {
configurations: (params: SplunkApplicationNamespace) => ConfigurationsAccessor;
apps: () => SplunkAppsAccessor;
storagePasswords: () => SplunkStoragePasswordAccessors;
indexes: () => SplunkIndexesAccessor;
post: (
splunkUrlPath: string,
data: any,
Expand Down
22 changes: 13 additions & 9 deletions packages/configuration-screen/src/utils/configurationFileHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,30 +139,34 @@ export async function updateConfigurationFile(
await updateStanzaProperties(configurationStanzaAccessor, properties);
}

export async function getCurrentIndexName(service: SplunkService): Promise<string> {
export async function getConfigurationStanzaValue(
service: SplunkService,
configurationFilename: string,
stanzaName: string,
propertyName: string,
defaultValue: string
): Promise<string> {
// Retrieve the accessor used to get a configuration file
let configurations = service.configurations({
// Name space information not provided
});
configurations = await promisify(configurations.fetch)();

// Retrieves the configuration file accessor
let configurationFileAccessor = getConfigurationFile(configurations, 'inputs');
let configurationFileAccessor = getConfigurationFile(configurations, configurationFilename);
configurationFileAccessor = await promisify(configurationFileAccessor.fetch)();

// Retrieves the configuration stanza accessor
let configurationStanzaAccessor = getConfigurationFileStanza(
configurationFileAccessor,
'script://$SPLUNK_HOME/etc/apps/flare/bin/cron_job_ingest_events.py'
stanzaName
);
configurationStanzaAccessor = await promisify(configurationStanzaAccessor.fetch)();

if (
!('index' in configurationStanzaAccessor._properties) ||
configurationStanzaAccessor._properties.index === 'default'
) {
return 'main';
let propertyValue = defaultValue;
if (propertyName in configurationStanzaAccessor._properties) {
propertyValue = configurationStanzaAccessor._properties[propertyName];
}

return configurationStanzaAccessor._properties.index;
return propertyValue;
}
Loading

0 comments on commit 3416924

Please sign in to comment.