Skip to content
This repository has been archived by the owner on Jul 6, 2023. It is now read-only.

Commit

Permalink
Merge pull request #7 from gt732/react
Browse files Browse the repository at this point in the history
React
  • Loading branch information
gt732 authored Mar 26, 2023
2 parents 5cc6dd4 + b045df3 commit 844387f
Show file tree
Hide file tree
Showing 28 changed files with 522 additions and 40 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ FortiGPT Troubleshooting Assistant is a web app that helps network administrator
To use FortiGPT Troubleshooting Assistant, simply select a problem category (e.g. VPN issues) from the sidebar menu, and choose the problem type. The app will gather the debug output from your FortiGate firewall and send it to the ChatGPT API for analysis. The app will then provide you with troubleshooting advice based on the analysis results. If you are not happy with the response from chatGPT you can modify the prompts used in the server folder and rebuild the docker image.

## Categories currently available
- Performance - High Memory, High CPU
- System - Fortiguard, High Memory, High CPU
- Connectivity - Packet Flow
- Routing - BGP Down
- VPN - VPN Down
- Network - Interfaces

## Future Development
- If the community expresses interest in this tool, I will incorporate additional categories and problem types.
Expand Down
4 changes: 2 additions & 2 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 18 additions & 5 deletions client/src/components/main/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import React, { useContext } from 'react';
import { Flex, Heading, Text } from '@chakra-ui/react';
import { AppContext } from '../../AppContext';
import Vpn from '../vpn/Vpn';
import Highcpu from '../performance/Highcpu';
import Highmemory from '../performance/Highmemory';
import Highcpu from '../system/Highcpu';
import Highmemory from '../system/Highmemory';
import Bgp from '../routing/Bgp';
import Packetflow from '../connectivity/Packetflow';
import Interfaces from '../network/Interfaces';
import Fortiguard from '../system/Fortiguard';

export default function Main() {
const { appData } = useContext(AppContext);
Expand All @@ -20,9 +22,10 @@ export default function Main() {
🤖 FortiGPT Troubleshooting Assistant 🤖
</Heading>
{(appData.problemCategory === 'problemcategory' ||
appData.problemCategory === 'performance' ||
appData.problemCategory === 'system' ||
appData.problemCategory === 'connectivity' ||
appData.problemCategory === 'vpn' ||
appData.problemCategory === 'network' ||
appData.problemCategory === 'routing') &&
appData.problemType === 'problemtype' && (
<>
Expand All @@ -36,14 +39,24 @@ export default function Main() {
<br />
</>
)}
{appData.problemCategory === 'performance' &&
{appData.problemCategory === 'network' &&
appData.problemType === 'interfaces' && <Interfaces />}

{appData.problemCategory === 'system' &&
appData.problemType === 'fortiguard' && <Fortiguard />}

{appData.problemCategory === 'system' &&
appData.problemType === 'highcpu' && <Highcpu />}
{appData.problemCategory === 'performance' &&

{appData.problemCategory === 'system' &&
appData.problemType === 'highmemory' && <Highmemory />}

{appData.problemCategory === 'vpn' &&
appData.problemType === 'vpndown' && <Vpn />}

{appData.problemCategory === 'routing' &&
appData.problemType === 'bgp' && <Bgp />}

{appData.problemCategory === 'connectivity' &&
appData.problemType === 'packetflow' && <Packetflow />}
</Flex>
Expand Down
31 changes: 28 additions & 3 deletions client/src/components/main/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,11 @@ export default function Sidebar() {
<option style={{ background: '#202324' }} value="problemcategory">
Problem Category
</option>
<option style={{ background: '#202324' }} value="performance">
Performance
<option style={{ background: '#202324' }} value="network">
Network
</option>
<option style={{ background: '#202324' }} value="system">
System
</option>
<option style={{ background: '#202324' }} value="connectivity">
Connectivity
Expand All @@ -224,7 +227,26 @@ export default function Sidebar() {
</option>
</Select>

{appData.problemCategory === 'performance' && (
{appData.problemCategory === 'network' && (
<>
<Select
py="20px"
onChange={handleProblemType}
bg="#202324"
pt="5px"
color="white"
>
<option style={{ background: '#202324' }} value="problemtype">
Problem Type
</option>
<option style={{ background: '#202324' }} value="interfaces">
Interfaces
</option>
</Select>
</>
)}

{appData.problemCategory === 'system' && (
<>
<Select
py="20px"
Expand All @@ -236,6 +258,9 @@ export default function Sidebar() {
<option style={{ background: '#202324' }} value="problemtype">
Problem Type
</option>
<option style={{ background: '#202324' }} value="fortiguard">
Fortiguard
</option>
<option style={{ background: '#202324' }} value="highcpu">
High CPU
</option>
Expand Down
132 changes: 132 additions & 0 deletions client/src/components/network/Interfaces.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React, { useState, useEffect } from 'react';
import { Box, Button, Text, Textarea } from '@chakra-ui/react';
import Disclaimer from '../main/Disclaimer';
import Chatgpt from '../chatgpt/Chatgpt';

export default function Interfaces() {
const [intfs, setIntfs] = useState([]);
const [buttonLoading, setButtonLoading] = useState([]);
const [debugOutput, setDebugOutput] = useState('');
const [ChatGptPrompt, setChatGptPrompt] = useState('');
const [documentationLink, setDocumentationLink] = useState('');

function getInterfaces() {
// Fetch the list of BGP neighbors
fetch(`/network/get_interface_list`)
.then(response => response.json())
.then(data => {
const interfaceValuesArray = Object.values(data.results);
setIntfs(interfaceValuesArray);
setButtonLoading(interfaceValuesArray.map(() => false));
})
.catch(error => {
console.error(error);
});
}

function handleClick(intf, index) {
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
intf: intf,
}),
};
// Set loading state of the individual button to true
setButtonLoading(buttonLoading.map((val, i) => (i === index ? true : val)));

fetch('network/interface_issue_script', requestOptions)
.then(response => response.text())
.then(data => {
setDebugOutput(data);

// Set loading state of the individual button to false
setButtonLoading(
buttonLoading.map((val, i) => (i === index ? false : val))
);
})

.catch(error => {
setDebugOutput('Try Logging in again');

// Set loading state of the individual button to false
setButtonLoading(
buttonLoading.map((val, i) => (i === index ? false : val))
);
});
}

useEffect(() => {
// Fetch the chatgpt prompt
fetch('/chatgpt_prompts/network/interface_issue.txt')
.then(response => response.text())
.then(text => {
setChatGptPrompt(text);
})
.catch(error => {
console.error(error);
});
}, []);

useEffect(() => {
// Fetch the documentation link
fetch('/chatgpt_prompts/network/interface_issue_link.txt')
.then(response => response.text())
.then(text => {
setDocumentationLink(text);
})
.catch(error => {
console.error(error);
});
}, []);

useEffect(() => {
getInterfaces();
}, []);

return [
<Text p="10px" fontSize={15} color="white">
👉 Instructions: Click on the Interface to gather debugs and statistics,
once complete click on Run FortiGPT 👈
</Text>,

<Box my="4">
{intfs.map((intf, index) => (
<Button
onClick={() => handleClick(intf.name, index)}
colorScheme={intf.link == true ? 'green' : 'red'}
key={intf.name}
borderRadius="full"
m="2"
isLoading={buttonLoading[index]}
loadingText={intf.name}
>
{intf.name}
</Button>
))}
</Box>,

<Text p="15px" color="white" fontWeight="bold">
✨ DEBUG OUTPUT ✨
</Text>,

<Textarea
color="white"
bg="gray.800"
defaultValue={debugOutput}
my={4}
size="md"
maxWidth="2xl"
/>,
<>
<Disclaimer documentationLink={documentationLink} />
</>,
<>
{debugOutput && (
<Chatgpt debugOutput={debugOutput} chatGptPrompt={ChatGptPrompt} />
)}
</>,
];
}
9 changes: 0 additions & 9 deletions client/src/components/routing/Bgp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import React, { useState, useEffect } from 'react';
import { Box, Button, Text, Textarea } from '@chakra-ui/react';
import Disclaimer from '../main/Disclaimer';
import Chatgpt from '../chatgpt/Chatgpt';
import { useToast } from '@chakra-ui/react';

export default function Bgp() {
const [bgpNei, setBgpNei] = useState([]);
const [buttonLoading, setButtonLoading] = useState([]);
const [debugOutput, setDebugOutput] = useState('');
const [ChatGptPrompt, setChatGptPrompt] = useState('');
const [documentationLink, setDocumentationLink] = useState('');
const toast = useToast();

function getBgpNeighbors() {
// Fetch the list of BGP neighbors
Expand All @@ -21,13 +19,6 @@ export default function Bgp() {
setButtonLoading(data.results.map(() => false));
})
.catch(error => {
toast({
title: `Try logging in again`,
status: 'error',
duration: 5000,
position: 'bottom-right',
isClosable: true,
});
console.error(error);
});
}
Expand Down
99 changes: 99 additions & 0 deletions client/src/components/system/Fortiguard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, { useState, useEffect } from 'react';
import { Button, HStack, Text, Textarea } from '@chakra-ui/react';
import Disclaimer from '../main/Disclaimer';
import Chatgpt from '../chatgpt/Chatgpt';

export default function Fortiguard() {
const [debugOutput, setDebugOutput] = useState('');
const [loading, setLoading] = useState(false);
const [ChatGptPrompt, setChatGptPrompt] = useState('');
const [documentationLink, setDocumentationLink] = useState('');

function handleClick() {
// Run the fortiguard debug script
setLoading(true);
setDebugOutput('');
fetch('/system/fortiguard_script', {
method: 'POST',
})
.then(response => response.text())
.then(data => {
setDebugOutput(data);
setLoading(false);
})
.catch(error => {
console.error(error);
setDebugOutput('Try Logging in again');
setLoading(false);
});
}

useEffect(() => {
// Get the chatgpt prompt
fetch('/chatgpt_prompts/system/fortiguard.txt')
.then(response => response.text())
.then(text => {
setChatGptPrompt(text);
})
.catch(error => {
console.error(error);
});
}, []);

useEffect(() => {
// Get the documentation link
fetch('/chatgpt_prompts/system/fortiguard_link.txt')
.then(response => response.text())
.then(text => {
setDocumentationLink(text);
})
.catch(error => {
console.error(error);
});
}, []);

return (
<>
<Text p="10px" fontSize={15} color="white">
👉 Instructions: Click Start Debug to gather Fortiguard statistics, once
complete click on Run FortiGPT 👈
</Text>

<HStack>
<Text p="15px" color="white" fontWeight="bold">
✨ DEBUG OUTPUT ✨
</Text>
<Button
borderRadius="full"
colorScheme="blue"
size="md"
ml={4}
isLoading={loading}
onClick={handleClick}
loadingText="Start Debug"
>
Start Debug
</Button>
</HStack>

<Textarea
color="white"
bg="gray.800"
defaultValue={debugOutput}
my={4}
size="md"
maxWidth="2xl"
/>

<>
<Disclaimer documentationLink={documentationLink} />
</>

<>
{debugOutput && (
<Chatgpt debugOutput={debugOutput} chatGptPrompt={ChatGptPrompt} />
)}
</>
</>
);
}
Loading

0 comments on commit 844387f

Please sign in to comment.