Skip to content
Snippets Groups Projects
Commit 10fda140 authored by geant-release-service's avatar geant-release-service
Browse files

Finished release 2.8.

parents 4eed15c8 645ed77a
No related branches found
No related tags found
No related merge requests found
Pipeline #89622 passed
ENVIRONMENT_NAME=Development
PROCESS_DETAIL_REFETCH_INTERVAL=3000
ORCHESTRATOR_API_HOST=http://localhost:8080
ORCHESTRATOR_API_PATH=/api
ORCHESTRATOR_GRAPHQL_HOST=http://localhost:8080
ORCHESTRATOR_GRAPHQL_PATH=/api/graphql
ORCHESTRATOR_WEBSOCKET_URL=ws://localhost:8080
USE_WEB_SOCKETS=true
USE_THEME_TOGGLE=true
SHOW_WORKFLOW_INFORMATION_LINK=true
WORKFLOW_INFORMATION_LINK_URL="https://workfloworchestrator.org/"
AUTH_ACTIVE=true
NEXTAUTH_URL=http://localhost:3000/api/auth
# OIDC Authentication Settings
NEXTAUTH_ID="oidc"
NEXTAUTH_CLIENT_ID="APP-A43E6FB7-1EEF-49CB-95B9-9AFF6FA7EF66"
NEXTAUTH_CLIENT_SECRET="YOUR_OIDC_CLIENT_SECRET"
NEXTAUTH_SECRET="SOhxHLn53mV7ML7y8L6rL5oOQxOVb0V4p2Ez0ZSIuOs=" # openssl rand -base64 32
NEXTAUTH_ISSUER="https://proxy.aai.geant.org"
NEXTAUTH_WELL_KNOWN_OVERRIDE="https://proxy.aai.geant.org/.well-known/openid-configuration"
# Auth variables
OAUTH2_ACTIVE=true
NEXTAUTH_PROVIDER_ID="oidc"
NEXTAUTH_PROVIDER_NAME="GÉANT Identity Provider"
NEXTAUTH_AUTHORIZATION_SCOPE_OVERRIDE="openid profile email aarc offline_access"
OAUTH2_CLIENT_ID="APP-A43E6FB7-1EEF-49CB-95B9-9AFF6FA7EF66"
OAUTH2_CLIENT_SECRET=""
OIDC_CONF_FULL_WELL_KNOWN_URL="https://proxy.aai.geant.org/.well-known/openid-configuration"
OIDC_TOKEN_ENDPOINT="https://proxy.aai.geant.org/OIDC/token"
# docker-compose variables
# KEYCLOAK_ADMIN=admin
# KEYCLOAK_ADMIN_PASSWORD=admin
# KEYCLOAK_PORT=8085
# OPA Settings
OPA_PUBLIC_BUNDLE_URL="http://localhost:8000/policy.wasm"
USE_WEBSOCKET=true
USE_THEME_TOGGLE=true
\ No newline at end of file
#Maps Settings
NETWORK_TOPOLOGY_API_URL="http://localhost:8080/api/v1/networks/topology"
# Required by the Nextauth middleware
NEXTAUTH_URL=http://localhost:3000/api/auth
NEXTAUTH_SECRET="LR1a4CU9UVFr1OcVeu4ULDX/VHMMiI+s3wNvOkf6fdE=" # openssl rand -base64 32
......@@ -2,9 +2,13 @@
All notable changes to this project will be documented in this file.
## [2.8] - 2024-10-10
- Add the newest GUI
## [2.6] - 2024-09-30
- Rollback to old GUI but with refresh token
- Rollback to old GUI but with refresh token
## [2.5] - 2024-09-18
......
import { getEnvironmentVariables } from '@/utils/getEnvironmentVariables';
import {
Environment,
OrchestratorConfig,
getEnvironmentVariables,
} from '@orchestrator-ui/orchestrator-ui-components';
const DEFAULT_GRAPHQL_CORE_ENDPOINT = 'http://localhost:8080/api/graphql';
const DEFAULT_ORCHESTRATOR_API_BASE_URL = 'http://localhost:8080/api';
const DEFAULT_ORCHESTRATOR_WEBSOCKET_URL = 'ws://localhost:8080';
const ENGINE_STATUS_ENDPOINT = '/settings/status';
const PROCESSES_ENDPOINT = '/processes';
const SUBSCRIPTION_PROCESSES_ENDPOINT =
'/processes/process-subscriptions-by-subscription-id';
const DEFAULT_WORKFLOW_INFORMATION_LINK_URL = 'http://localhost:8080';
type OrchestratorEnvVars = {
ORCHESTRATOR_GRAPHQL_HOST: string;
ORCHESTRATOR_GRAPHQL_PATH: string;
ORCHESTRATOR_API_HOST: string;
ORCHESTRATOR_API_PATH: string;
ENVIRONMENT_NAME: string;
ORCHESTRATOR_WEBSOCKET_URL: string;
AUTH_ACTIVE: string;
USE_WEB_SOCKETS: string;
USE_THEME_TOGGLE: string;
WORKFLOW_INFORMATION_LINK_URL: string;
SHOW_WORKFLOW_INFORMATION_LINK: string;
};
export const getInitialOrchestratorConfig = (): OrchestratorConfig => {
const env = getEnvironmentVariables<OrchestratorEnvVars>([
'ORCHESTRATOR_GRAPHQL_HOST',
'ORCHESTRATOR_GRAPHQL_PATH',
const {
USE_THEME_TOGGLE,
ENVIRONMENT_NAME,
ORCHESTRATOR_API_HOST,
ORCHESTRATOR_API_PATH,
ORCHESTRATOR_GRAPHQL_HOST,
ORCHESTRATOR_GRAPHQL_PATH,
ORCHESTRATOR_WEBSOCKET_URL,
USE_WEB_SOCKETS,
WORKFLOW_INFORMATION_LINK_URL,
SHOW_WORKFLOW_INFORMATION_LINK,
OAUTH2_ACTIVE,
ENABLE_SUPPORT_MENU_ITEM,
SUPPORT_MENU_ITEM_URL,
} = getEnvironmentVariables([
'USE_THEME_TOGGLE',
'ENVIRONMENT_NAME',
'ORCHESTRATOR_API_HOST',
'ORCHESTRATOR_API_PATH',
'ENVIRONMENT_NAME',
'ORCHESTRATOR_GRAPHQL_HOST',
'ORCHESTRATOR_GRAPHQL_PATH',
'ORCHESTRATOR_WEBSOCKET_URL',
'AUTH_ACTIVE',
'USE_WEB_SOCKETS',
'USE_THEME_TOGGLE',
'WORKFLOW_INFORMATION_LINK_URL',
'SHOW_WORKFLOW_INFORMATION_LINK',
'OAUTH2_ACTIVE',
'ENABLE_SUPPORT_MENU_ITEM',
'SUPPORT_MENU_ITEM_URL',
]);
const orchestratorGraphqlBaseUrl =
env.ORCHESTRATOR_GRAPHQL_HOST && env.ORCHESTRATOR_GRAPHQL_PATH
? `${env.ORCHESTRATOR_GRAPHQL_HOST}${env.ORCHESTRATOR_GRAPHQL_PATH}`
: DEFAULT_GRAPHQL_CORE_ENDPOINT;
const orchestratorApiBaseUrl =
env.ORCHESTRATOR_API_HOST && env.ORCHESTRATOR_API_PATH
? `${env.ORCHESTRATOR_API_HOST}${env.ORCHESTRATOR_API_PATH}`
: DEFAULT_ORCHESTRATOR_API_BASE_URL;
const graphqlEndpointCore = `${ORCHESTRATOR_GRAPHQL_HOST}${ORCHESTRATOR_GRAPHQL_PATH}`;
const orchestratorApiBaseUrl = `${ORCHESTRATOR_API_HOST}${ORCHESTRATOR_API_PATH}`;
return {
orchestratorApiBaseUrl,
engineStatusEndpoint: `${orchestratorApiBaseUrl}${ENGINE_STATUS_ENDPOINT}`,
graphqlEndpointCore: orchestratorGraphqlBaseUrl,
processesEndpoint: `${orchestratorApiBaseUrl}${PROCESSES_ENDPOINT}`,
environmentName: env.ENVIRONMENT_NAME ?? Environment.DEVELOPMENT,
subscriptionProcessesEndpoint: `${orchestratorApiBaseUrl}${SUBSCRIPTION_PROCESSES_ENDPOINT}`,
orchestratorWebsocketUrl:
env.ORCHESTRATOR_WEBSOCKET_URL ?? DEFAULT_ORCHESTRATOR_WEBSOCKET_URL,
authActive: env.AUTH_ACTIVE?.toLowerCase() !== 'false',
useWebSockets: env.USE_WEB_SOCKETS?.toLowerCase() === 'true',
useThemeToggle: env.USE_THEME_TOGGLE?.toLowerCase() === 'true',
workflowInformationLinkUrl:
env.WORKFLOW_INFORMATION_LINK_URL ??
DEFAULT_WORKFLOW_INFORMATION_LINK_URL,
graphqlEndpointCore,
environmentName: ENVIRONMENT_NAME ?? Environment.DEVELOPMENT,
orchestratorWebsocketUrl: ORCHESTRATOR_WEBSOCKET_URL,
authActive: OAUTH2_ACTIVE?.toLowerCase() != 'false',
useWebSockets: USE_WEB_SOCKETS?.toLowerCase() === 'true',
useThemeToggle: USE_THEME_TOGGLE?.toLowerCase() === 'true',
workflowInformationLinkUrl: WORKFLOW_INFORMATION_LINK_URL,
showWorkflowInformationLink:
env.SHOW_WORKFLOW_INFORMATION_LINK?.toLowerCase() === 'true',
SHOW_WORKFLOW_INFORMATION_LINK?.toLowerCase() === 'true',
enableSupportMenuItem: ENABLE_SUPPORT_MENU_ITEM?.toLowerCase() === 'true',
supportMenuItemUrl: SUPPORT_MENU_ITEM_URL,
};
};
import axios from 'axios';
import { signOut } from 'next-auth/react';
import { useEffect } from 'react';
const useAxiosInterceptor = () => {
useEffect(() => {
const responseInterceptor = axios.interceptors.response.use(
(response) => response,
(error) => {
if (error.response && error.response.status === 401) {
const currentUrl = window.location.href;
signOut({
callbackUrl: `/api/auth/signin?error=SessionRequired&callbackUrl=${encodeURIComponent(
currentUrl,
)}`,
});
}
return Promise.reject(error);
},
);
return () => {
axios.interceptors.response.eject(responseInterceptor);
};
}, []);
};
export default useAxiosInterceptor;
import { signOut } from 'next-auth/react';
import { useEffect } from 'react';
const useFetchInterceptor = () => {
useEffect(() => {
const handleResponse = (response: Response) => {
if (response.status === 401) {
const currentUrl = window.location.href;
signOut({
callbackUrl: `/api/auth/signin?error=SessionRequired&callbackUrl=${encodeURIComponent(
currentUrl,
)}`,
});
}
return response;
};
const originalFetch = global.fetch.bind(global);
global.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
const response = await originalFetch(input, init);
return handleResponse(response);
};
return () => {
global.fetch = originalFetch;
};
}, []);
};
export default useFetchInterceptor;
......@@ -10,6 +10,6 @@ module.exports = {
transpilePackages: ['@orchestrator-ui/orchestrator-ui-components'],
publicRuntimeConfig: {
OPA_PUBLIC_BUNDLE_URL: process.env.OPA_PUBLIC_BUNDLE_URL,
NEXTAUTH_CLIENT_ID: process.env.NEXTAUTH_CLIENT_ID,
OAUTH2_CLIENT_ID: process.env.OAUTH2_CLIENT_ID,
},
};
This diff is collapsed.
......@@ -3,25 +3,21 @@ import { getAppLogo } from '@/components/AppLogo/AppLogo';
import { WfoAuthWithPolicy } from '@/components/WfoAuthWithPolicy';
import { getInitialOrchestratorConfig } from '@/configuration';
import { GsoConfigProvider, GsoConfig } from '@/contexts/GsoConfigContext';
import useAxiosInterceptor from '@/hooks/useAxiosInterceptor';
import useFetchInterceptor from '@/hooks/useFetchInterceptor';
import { TranslationsProvider } from '@/translations/translationsProvider';
import type { EuiSideNavItemType } from '@elastic/eui';
import { EuiProvider, EuiThemeColorMode } from '@elastic/eui';
import '@elastic/eui/dist/eui_theme_dark.min.css';
import '@elastic/eui/dist/eui_theme_light.min.css';
import { EuiSideNavItemType } from '@elastic/eui/src/components/side_nav/side_nav_types';
import {
ApiClientContextProvider,
ColorModes,
ConfirmationDialogContextWrapper,
OrchestratorConfig,
OrchestratorConfigProvider,
StoreProvider,
WfoErrorBoundary,
WfoMenuItemLink,
WfoPageTemplate,
WfoToastsList,
defaultOrchestratorTheme,
WfoMenuItemLink,
} from '@orchestrator-ui/orchestrator-ui-components';
import { SessionProvider } from 'next-auth/react';
import { NextAdapter } from 'next-query-params';
......@@ -30,36 +26,17 @@ import Head from 'next/head';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import NoSSR from 'react-no-ssr';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import { QueryClientConfig } from 'react-query/types/core/types';
import { QueryParamProvider } from 'use-query-params';
type AppOwnProps = { orchestratorConfig: OrchestratorConfig };
const queryClientConfig: QueryClientConfig = {
defaultOptions: {
queries: {
cacheTime: 5 * 1000,
refetchOnWindowFocus: true,
},
},
};
const useAuthInterceptor = () => {
useFetchInterceptor();
useAxiosInterceptor();
};
function CustomApp({
Component,
pageProps,
orchestratorConfig,
}: AppProps & AppOwnProps) {
const router = useRouter();
useAuthInterceptor();
const [queryClient] = useState(() => new QueryClient(queryClientConfig));
const [themeMode, setThemeMode] = useState<EuiThemeColorMode>(
ColorModes.LIGHT,
);
......@@ -128,40 +105,32 @@ function CustomApp({
colorMode={themeMode}
modify={defaultOrchestratorTheme}
>
<ApiClientContextProvider>
<QueryClientProvider
client={queryClient}
contextSharing={true}
>
<TranslationsProvider>
<Head>
<link rel="icon" href="/favicon.png" />
<title>GÉANT Service Orchestrator</title>
</Head>
<main className="app">
<ConfirmationDialogContextWrapper>
<WfoPageTemplate
getAppLogo={getAppLogo}
onThemeSwitch={handleThemeSwitch}
overrideMenuItems={addMenuItems}
>
<QueryParamProvider
adapter={NextAdapter}
options={{
removeDefaultsFromUrl: false,
enableBatching: true,
}}
>
<Component {...pageProps} />
</QueryParamProvider>
</WfoPageTemplate>
<WfoToastsList />
</ConfirmationDialogContextWrapper>
<ReactQueryDevtools initialIsOpen={false} />
</main>
</TranslationsProvider>
</QueryClientProvider>
</ApiClientContextProvider>
<TranslationsProvider>
<Head>
<link rel="icon" href="/favicon.png" />
<title>GÉANT Service Orchestrator</title>
</Head>
<main className="app">
<ConfirmationDialogContextWrapper>
<WfoPageTemplate
getAppLogo={getAppLogo}
onThemeSwitch={handleThemeSwitch}
overrideMenuItems={addMenuItems}
>
<QueryParamProvider
adapter={NextAdapter}
options={{
removeDefaultsFromUrl: false,
enableBatching: true,
}}
>
<Component {...pageProps} />
</QueryParamProvider>
</WfoPageTemplate>
<WfoToastsList />
</ConfirmationDialogContextWrapper>
</main>
</TranslationsProvider>
</EuiProvider>
</WfoAuthWithPolicy>
</GsoConfigProvider>
......
import { getEnvironmentVariables } from '@/utils/getEnvironmentVariables';
import {
WfoSession,
WfoUserProfile,
getEnvironmentVariables,
} from '@orchestrator-ui/orchestrator-ui-components';
import NextAuth, { AuthOptions } from 'next-auth';
import { JWT } from 'next-auth/jwt';
......
import { getEnvironmentVariables } from '@orchestrator-ui/orchestrator-ui-components';
import { NextApiRequest, NextApiResponse } from 'next';
interface RuntimeConfig {
......@@ -6,14 +7,21 @@ interface RuntimeConfig {
networkTopologyApiUrl: string;
}
const { OPA_PUBLIC_BUNDLE_URL, OAUTH2_CLIENT_ID, NETWORK_TOPOLOGY_API_URL } =
getEnvironmentVariables([
'OPA_PUBLIC_BUNDLE_URL',
'OAUTH2_CLIENT_ID',
'NETWORK_TOPOLOGY_API_URL',
]);
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<RuntimeConfig | { error: string }>,
) {
const config: RuntimeConfig = {
opaPublicBundleUrl: process.env.OPA_PUBLIC_BUNDLE_URL || '',
oidcClientId: process.env.NEXTAUTH_CLIENT_ID || '',
networkTopologyApiUrl: process.env.NETWORK_TOPOLOGY_API_URL || '',
opaPublicBundleUrl: OPA_PUBLIC_BUNDLE_URL || '',
oidcClientId: OAUTH2_CLIENT_ID || '',
networkTopologyApiUrl: NETWORK_TOPOLOGY_API_URL || '',
};
res.status(200).json(config);
......
......@@ -3,7 +3,7 @@ from setuptools import setup
setup(
name="geant-service-orchestrator-gui",
py_modules=[],
version="2.6",
version="2.8",
author="GÉANT Orchestration and Automation Team",
author_email="goat@geant.org",
description="GÉANT Service Orchestrator GUI dummy package",
......
import process from 'process';
// By convention, only this function should be used to access the process.env object.
// It logs a warning if one or more variables are not set
export function getEnvironmentVariables<T>(
envVars: (keyof T)[],
): Record<keyof T, string> {
const missingEnvironmentVariables: string[] = [];
const environmentVariablesWithValues = envVars.reduce((acc, currentKey) => {
const value = process.env[currentKey.toString()];
if (value === undefined) {
missingEnvironmentVariables.push(currentKey.toString());
}
return {
...acc,
[currentKey]: value || '',
};
}, {} as Record<keyof T, string>);
if (missingEnvironmentVariables.length > 0) {
console.warn(
`Warning: Missing required environment variables: ${missingEnvironmentVariables.join(
', ',
)}`,
);
}
return environmentVariablesWithValues;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment