Skip to content

Hack start single plugin locally #607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 1 addition & 30 deletions app/packages/app/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import Github from '@kobsio/github';
import Grafana from '@kobsio/grafana';
import Harbor from '@kobsio/harbor';
import Helm from '@kobsio/helm';
import Jaeger from '@kobsio/jaeger';
import Jira from '@kobsio/jira';
import Kiali from '@kobsio/kiali';
import Klogs from '@kobsio/klogs';
Expand All @@ -30,35 +29,7 @@ import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';

import '@kobsio/core/dist/style.css';
import '@kobsio/jaeger/dist/style.css';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<StrictMode>
<App
plugins={[
Azure,
Datadog,
Elasticsearch,
Flux,
Github,
Grafana,
Harbor,
Helm,
Jaeger,
Jira,
Kiali,
Klogs,
MongoDB,
Opsgenie,
Prometheus,
RSS,
Runbooks,
SignalSciences,
SonarQube,
SQL,
TechDocs,
Velero,
]}
/>
</StrictMode>,
<App plugins={[Klogs]}/>
);
2 changes: 1 addition & 1 deletion app/packages/app/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export default defineConfig(({ command, mode, ssrBuild }) => {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:15220',
target: 'http://localhost:3003',
},
},
strictPort: true,
Expand Down
105 changes: 25 additions & 80 deletions app/packages/core/src/components/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
import { CssBaseline, ThemeProvider, Box, CircularProgress } from '@mui/material';
import { useQuery } from '@tanstack/react-query';
import { FunctionComponent, ReactNode, useContext } from 'react';
import { Helmet } from 'react-helmet';
import { BrowserRouter, Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import {Box, CircularProgress} from '@mui/material';
import {useQuery} from '@tanstack/react-query';
import {FunctionComponent, ReactNode, useContext} from 'react';
import {BrowserRouter, Route, Routes, useLocation, useNavigate} from 'react-router-dom';

import Home from './Home';
import Layout from './layout/Layout';
import Signin from './signin/Signin';
import SigninOIDCCallback from './signin/SigninOIDCCallback';

import { APIContextProvider, APIContext, IAPIContext, APIError, IAPIUser } from '../../context/APIContext';
import { AppContextProvider, IAppIcons } from '../../context/AppContext';
import { PluginContextProvider, IPlugin } from '../../context/PluginContext';
import { QueryClientProvider } from '../../context/QueryClientProvider';
import theme from '../../utils/theme';
import ApplicationPage from '../applications/ApplicationPage';
import ApplicationsPage from '../applications/ApplicationsPage';
import TopologyPage from '../applications/TopologyPage';
import DashboardsPage from '../dashboards/DashboardsPage';
import EditPage from '../edit/EditPage';
import {APIContext, APIError, IAPIContext, IAPIUser} from '../../context/APIContext';
import {IAppIcons} from '../../context/AppContext';
import {IPlugin} from '../../context/PluginContext';
import {QueryClientProvider} from '../../context/QueryClientProvider';
import PluginPage from '../plugins/PluginPage';
import PluginsPage from '../plugins/PluginsPage';
import ResourcesLogsPage from '../resources/ResourcesLogsPage';
import ResourcesPage from '../resources/ResourcesPage';
import ResourcesTerminalPage from '../resources/ResourcesTerminalPage';
import TeamPage from '../teams/TeamPage';
import TeamsPage from '../teams/TeamsPage';

/**
* `IAuthWrapper` is the interface which defines the properties for the `AuthWrapper` component. We only have to provide
Expand All @@ -41,20 +23,20 @@ interface IAuthWrapper {
* returns the authenticated user. If we can not get a user within the `auth` method and our API returns a unauthorized
* error we automatically redirecting the user to the sign in page.
*/
const AuthWrapper: FunctionComponent<IAuthWrapper> = ({ children }) => {
const AuthWrapper: FunctionComponent<IAuthWrapper> = ({children}) => {
const navigate = useNavigate();
const location = useLocation();
const apiContext = useContext<IAPIContext>(APIContext);

const { isLoading, isError, error } = useQuery<IAPIUser, APIError>(['core/authwrapper'], async () => {
const {isLoading, isError, error} = useQuery<IAPIUser, APIError>(['core/authwrapper'], async () => {
return apiContext.client.auth();
});

if (isLoading) {
return (
<Box minHeight="100vh" minWidth="100%" display="flex" flexDirection="column" justifyContent="center">
<Box sx={{ display: 'inline-flex', mx: 'auto' }}>
<CircularProgress />
<Box sx={{display: 'inline-flex', mx: 'auto'}}>
<CircularProgress/>
</Box>
</Box>
);
Expand All @@ -66,17 +48,17 @@ const AuthWrapper: FunctionComponent<IAuthWrapper> = ({ children }) => {

return (
<Box minHeight="100vh" minWidth="100%" display="flex" flexDirection="column" justifyContent="center">
<Box sx={{ display: 'inline-flex', mx: 'auto' }}>
<CircularProgress />
<Box sx={{display: 'inline-flex', mx: 'auto'}}>
<CircularProgress/>
</Box>
</Box>
);
}

return (
<Box minHeight="100vh" minWidth="100%" display="flex" flexDirection="column" justifyContent="center">
<Box sx={{ display: 'inline-flex', mx: 'auto' }}>
<CircularProgress />
<Box sx={{display: 'inline-flex', mx: 'auto'}}>
<CircularProgress/>
</Box>
</Box>
);
Expand All @@ -98,52 +80,15 @@ interface IAppProps {
* The `App` component defines, defines all the contexts and routes we are using in our app. The `App` component is also
* responsible for defining our layout and registering the theme.
*/
export const App: FunctionComponent<IAppProps> = ({ icons, plugins }) => {
export const App: FunctionComponent<IAppProps> = ({icons, plugins}) => {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Helmet titleTemplate="kobs - %s" defaultTitle="kobs" />
<QueryClientProvider>
<AppContextProvider icons={icons}>
<APIContextProvider>
<BrowserRouter>
<Routes>
<Route path="/auth" element={<Signin />} />
<Route path="/auth/callback" element={<SigninOIDCCallback />} />
<Route
path="*"
element={
<AuthWrapper>
<PluginContextProvider plugins={plugins}>
<Layout>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/applications" element={<ApplicationsPage />} />
<Route
path="/applications/cluster/:cluster/namespace/:namespace/name/:name"
element={<ApplicationPage />}
/>
<Route path="/topology" element={<TopologyPage />} />
<Route path="/teams" element={<TeamsPage />} />
<Route path="/teams/:id" element={<TeamPage />} />
<Route path="/dashboards/:page" element={<DashboardsPage />} />
<Route path="/resources" element={<ResourcesPage />} />
<Route path="/resources/logs" element={<ResourcesLogsPage />} />
<Route path="/resources/terminal" element={<ResourcesTerminalPage />} />
<Route path="/plugins" element={<PluginsPage />} />
<Route path="/plugins/:cluster/:type/:name/*" element={<PluginPage />} />
<Route path="/edit/:type" element={<EditPage />} />
</Routes>
</Layout>
</PluginContextProvider>
</AuthWrapper>
}
/>
</Routes>
</BrowserRouter>
</APIContextProvider>
</AppContextProvider>
</QueryClientProvider>
</ThemeProvider>
<QueryClientProvider>
<BrowserRouter>
<Routes>
<Route path="*" element={<PluginPage/>}>
</Route>
</Routes>
</BrowserRouter>
</QueryClientProvider>
);
};
12 changes: 10 additions & 2 deletions app/packages/core/src/components/plugins/PluginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useNavigate } from 'react-router-dom';
import { useParams } from 'react-router-dom';

import { PluginContext } from '../../context/PluginContext';
import Klogs from '@kobsio/klogs';

interface IPluginPageParams extends Record<string, string | undefined> {
cluster?: string;
Expand All @@ -25,8 +26,15 @@ const PluginPage: FunctionComponent = () => {
const type = params['type'];
const name = params['name'];

const instance = name ? getInstance(`/cluster/${cluster}/type/${type}/name/${name}`) : undefined;
const Page = instance ? getPlugin(instance.type)?.page : undefined;
// const instance = name ? getInstance(`/cluster/${cluster}/type/${type}/name/${name}`) : undefined;
const instance = {
cluster: "dev-de1-fake",
id: "id-fake",
name: "klogs-fake",
type: "type-klogs-fake"
}
// const Page = instance ? getPlugin(instance.type)?.page : undefined;
const Page = Klogs.page

return (
<ErrorBoundary
Expand Down
39 changes: 20 additions & 19 deletions app/packages/klogs/src/components/LogsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -333,21 +333,23 @@ const LogsPage: FunctionComponent<IPluginPageProps> = ({ instance }) => {
timeStart: Math.floor(Date.now() / 1000) - 900,
});

const { isError, isLoading, error, data, refetch } = useQuery<ILogsData, APIError>(
['klogs/logs', options.query, options.order, options.orderBy, options.timeStart, options.timeEnd],
() => {
const path = `/api/plugins/klogs/logs?query=${encodeURIComponent(options.query)}&order=${
options.order
}&orderBy=${encodeURIComponent(options.orderBy)}&timeStart=${options.timeStart}&timeEnd=${options.timeEnd}`;

return apiContext.client.get<ILogsData>(path, {
headers: {
'x-kobs-cluster': instance.cluster,
'x-kobs-plugin': instance.name,
},
});
},
);
const data: ILogsData = {/* TODO: provide mock data here */}

// const { isError, isLoading, error, data, refetch } = useQuery<ILogsData, APIError>(
// ['klogs/logs', options.query, options.order, options.orderBy, options.timeStart, options.timeEnd],
// () => {
// const path = `/api/plugins/klogs/logs?query=${encodeURIComponent(options.query)}&order=${
// options.order
// }&orderBy=${encodeURIComponent(options.orderBy)}&timeStart=${options.timeStart}&timeEnd=${options.timeEnd}`;
//
// return apiContext.client.get<ILogsData>(path, {
// headers: {
// 'x-kobs-cluster': instance.cluster,
// 'x-kobs-plugin': instance.name,
// },
// });
// },
// );

/**
* selectField is used to add a field as parameter, when it isn't present and to remove a fields from as parameter,
Expand Down Expand Up @@ -416,10 +418,9 @@ const LogsPage: FunctionComponent<IPluginPageProps> = ({ instance }) => {
actions={<LogsActions instance={instance} options={options} />}
>
<UseQueryWrapper
error={error}
isError={isError}
isLoading={isLoading}
refetch={refetch}
error={null}
isError={false}
isLoading={false}
errorTitle="Failed to get logs"
isNoData={!data || !data.documents || data.documents.length === 0}
noDataTitle="No logs were found"
Expand Down