mirror of https://github.com/portainer/portainer
refactor(edge): move edge codebase to react (#7781)
parent
75f40fe485
commit
1e4c4e2616
|
@ -1 +0,0 @@
|
||||||
export { EdgeDevicesView } from './EdgeDevicesView';
|
|
|
@ -1,17 +1,11 @@
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
|
|
||||||
import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
|
||||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
|
||||||
import edgeStackModule from './views/edge-stacks';
|
import edgeStackModule from './views/edge-stacks';
|
||||||
import { componentsModule } from './components';
|
|
||||||
import { WaitingRoomView } from './EdgeDevices/WaitingRoomView';
|
|
||||||
import { reactModule } from './react';
|
import { reactModule } from './react';
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('portainer.edge', [edgeStackModule, componentsModule, reactModule])
|
.module('portainer.edge', [edgeStackModule, reactModule])
|
||||||
.component('waitingRoomView', r2a(withUIRouter(withReactQuery(withCurrentUser(WaitingRoomView))), []))
|
|
||||||
.config(function config($stateRegistryProvider) {
|
.config(function config($stateRegistryProvider) {
|
||||||
const edge = {
|
const edge = {
|
||||||
name: 'edge',
|
name: 'edge',
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
|
||||||
import { useSettings } from '@/react/portainer/settings/queries';
|
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
|
||||||
|
|
||||||
import { FormControl, Size } from '@@/form-components/FormControl';
|
|
||||||
import { Select } from '@@/form-components/Input';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
value: number;
|
|
||||||
onChange(value: number): void;
|
|
||||||
isDefaultHidden?: boolean;
|
|
||||||
label?: string;
|
|
||||||
tooltip?: string;
|
|
||||||
readonly?: boolean;
|
|
||||||
size?: Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const checkinIntervalOptions = [
|
|
||||||
{ label: 'Use default interval', value: 0 },
|
|
||||||
{
|
|
||||||
label: '5 seconds',
|
|
||||||
value: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '10 seconds',
|
|
||||||
value: 10,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '30 seconds',
|
|
||||||
value: 30,
|
|
||||||
},
|
|
||||||
{ label: '5 minutes', value: 300 },
|
|
||||||
{ label: '1 hour', value: 3600 },
|
|
||||||
{ label: '1 day', value: 86400 },
|
|
||||||
];
|
|
||||||
|
|
||||||
export function EdgeCheckinIntervalField({
|
|
||||||
value,
|
|
||||||
readonly,
|
|
||||||
onChange,
|
|
||||||
isDefaultHidden = false,
|
|
||||||
label = 'Poll frequency',
|
|
||||||
tooltip = 'Interval used by this Edge agent to check in with the Portainer instance. Affects Edge environment management and Edge compute features.',
|
|
||||||
size = 'small',
|
|
||||||
}: Props) {
|
|
||||||
const options = useOptions(isDefaultHidden);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormControl
|
|
||||||
inputId="edge_checkin"
|
|
||||||
label={label}
|
|
||||||
tooltip={tooltip}
|
|
||||||
size={size}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
value={value}
|
|
||||||
onChange={(e) => {
|
|
||||||
onChange(parseInt(e.currentTarget.value, 10));
|
|
||||||
}}
|
|
||||||
options={options}
|
|
||||||
disabled={readonly}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const EdgeCheckinIntervalFieldAngular = r2a(
|
|
||||||
withReactQuery(EdgeCheckinIntervalField),
|
|
||||||
[
|
|
||||||
'value',
|
|
||||||
'onChange',
|
|
||||||
'isDefaultHidden',
|
|
||||||
'tooltip',
|
|
||||||
'label',
|
|
||||||
'readonly',
|
|
||||||
'size',
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
function useOptions(isDefaultHidden: boolean) {
|
|
||||||
const [options, setOptions] = useState(checkinIntervalOptions);
|
|
||||||
|
|
||||||
const settingsQuery = useSettings(
|
|
||||||
(settings) => settings.EdgeAgentCheckinInterval
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDefaultHidden) {
|
|
||||||
setOptions(checkinIntervalOptions.filter((option) => option.value !== 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDefaultHidden && typeof settingsQuery.data !== 'undefined') {
|
|
||||||
setOptions((options) => {
|
|
||||||
let label = `${settingsQuery.data} seconds`;
|
|
||||||
const option = options.find((o) => o.value === settingsQuery.data);
|
|
||||||
if (option) {
|
|
||||||
label = option.label;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
label: `Use default interval (${label})`,
|
|
||||||
},
|
|
||||||
...options.slice(1),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [settingsQuery.data, setOptions, isDefaultHidden]);
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
import angular from 'angular';
|
|
||||||
|
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
|
||||||
import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm';
|
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
|
||||||
|
|
||||||
import { EdgeCheckinIntervalFieldAngular } from './EdgeCheckInIntervalField';
|
|
||||||
|
|
||||||
export const componentsModule = angular
|
|
||||||
.module('app.edge.components', [])
|
|
||||||
.component(
|
|
||||||
'edgeScriptForm',
|
|
||||||
r2a(withReactQuery(EdgeScriptForm), [
|
|
||||||
'edgeInfo',
|
|
||||||
'commands',
|
|
||||||
'isNomadTokenVisible',
|
|
||||||
])
|
|
||||||
)
|
|
||||||
.component('edgeCheckinIntervalField', EdgeCheckinIntervalFieldAngular).name;
|
|
|
@ -1,11 +1,46 @@
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
|
|
||||||
import { EdgeGroupsSelector } from '@/react/edge/components/EdgeGroupsSelector';
|
import { EdgeGroupsSelector } from '@/react/edge/edge-stacks/components/EdgeGroupsSelector';
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
import { r2a } from '@/react-tools/react2angular';
|
||||||
|
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||||
|
import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField';
|
||||||
|
import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm';
|
||||||
|
import { EdgeAsyncIntervalsForm } from '@/react/edge/components/EdgeAsyncIntervalsForm';
|
||||||
|
|
||||||
export const componentsModule = angular
|
export const componentsModule = angular
|
||||||
.module('portainer.edge.react.components', [])
|
.module('portainer.edge.react.components', [])
|
||||||
.component(
|
.component(
|
||||||
'edgeGroupsSelector',
|
'edgeGroupsSelector',
|
||||||
r2a(EdgeGroupsSelector, ['items', 'onChange', 'value'])
|
r2a(EdgeGroupsSelector, ['items', 'onChange', 'value'])
|
||||||
|
)
|
||||||
|
.component(
|
||||||
|
'edgeScriptForm',
|
||||||
|
r2a(withReactQuery(EdgeScriptForm), [
|
||||||
|
'edgeInfo',
|
||||||
|
'commands',
|
||||||
|
'isNomadTokenVisible',
|
||||||
|
'hideAsyncMode',
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.component(
|
||||||
|
'edgeCheckinIntervalField',
|
||||||
|
r2a(withReactQuery(EdgeCheckinIntervalField), [
|
||||||
|
'value',
|
||||||
|
'onChange',
|
||||||
|
'isDefaultHidden',
|
||||||
|
'tooltip',
|
||||||
|
'label',
|
||||||
|
'readonly',
|
||||||
|
'size',
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.component(
|
||||||
|
'edgeAsyncIntervalsForm',
|
||||||
|
r2a(withReactQuery(EdgeAsyncIntervalsForm), [
|
||||||
|
'values',
|
||||||
|
'onChange',
|
||||||
|
'isDefaultHidden',
|
||||||
|
'readonly',
|
||||||
|
'fieldSettings',
|
||||||
|
])
|
||||||
).name;
|
).name;
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
|
|
||||||
import { EdgeDevicesView } from '@/edge/EdgeDevices/EdgeDevicesView';
|
|
||||||
import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
import { r2a } from '@/react-tools/react2angular';
|
||||||
|
import { ListView } from '@/react/edge/edge-devices/ListView';
|
||||||
|
import { withCurrentUser } from '@/react-tools/withCurrentUser';
|
||||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||||
import { withUIRouter } from '@/react-tools/withUIRouter';
|
import { withUIRouter } from '@/react-tools/withUIRouter';
|
||||||
|
import { WaitingRoomView } from '@/react/edge/edge-devices/WaitingRoomView';
|
||||||
|
|
||||||
export const viewsModule = angular
|
export const viewsModule = angular
|
||||||
.module('portainer.edge.react.views', [])
|
.module('portainer.edge.react.views', [])
|
||||||
|
.component(
|
||||||
|
'waitingRoomView',
|
||||||
|
r2a(withUIRouter(withReactQuery(withCurrentUser(WaitingRoomView))), [])
|
||||||
|
)
|
||||||
.component(
|
.component(
|
||||||
'edgeDevicesView',
|
'edgeDevicesView',
|
||||||
r2a(withUIRouter(withReactQuery(withCurrentUser(EdgeDevicesView))), [])
|
r2a(withUIRouter(withReactQuery(withCurrentUser(ListView))), [])
|
||||||
).name;
|
).name;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import { number, object, SchemaOf } from 'yup';
|
import { number, object, SchemaOf } from 'yup';
|
||||||
|
|
||||||
import { r2a } from '@/react-tools/react2angular';
|
|
||||||
|
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
||||||
import { Select } from '@@/form-components/Input';
|
import { Select } from '@@/form-components/Input';
|
||||||
|
|
||||||
|
@ -153,11 +151,3 @@ export function edgeAsyncIntervalsValidation(): SchemaOf<EdgeAsyncIntervalsValue
|
||||||
.oneOf(intervals),
|
.oneOf(intervals),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EdgeAsyncIntervalsFormAngular = r2a(EdgeAsyncIntervalsForm, [
|
|
||||||
'values',
|
|
||||||
'onChange',
|
|
||||||
'isDefaultHidden',
|
|
||||||
'readonly',
|
|
||||||
'fieldSettings',
|
|
||||||
]);
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { FormControl, Size } from '@@/form-components/FormControl';
|
||||||
|
import { Select } from '@@/form-components/Input';
|
||||||
|
|
||||||
|
import { Options, useIntervalOptions } from './useIntervalOptions';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
value: number;
|
||||||
|
onChange(value: number): void;
|
||||||
|
isDefaultHidden?: boolean;
|
||||||
|
label?: string;
|
||||||
|
tooltip?: string;
|
||||||
|
readonly?: boolean;
|
||||||
|
size?: Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const checkinIntervalOptions: Options = [
|
||||||
|
{ label: 'Use default interval', value: 0, isDefault: true },
|
||||||
|
{
|
||||||
|
label: '5 seconds',
|
||||||
|
value: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '10 seconds',
|
||||||
|
value: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '30 seconds',
|
||||||
|
value: 30,
|
||||||
|
},
|
||||||
|
{ label: '5 minutes', value: 300 },
|
||||||
|
{ label: '1 hour', value: 3600 },
|
||||||
|
{ label: '1 day', value: 86400 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function EdgeCheckinIntervalField({
|
||||||
|
value,
|
||||||
|
readonly,
|
||||||
|
onChange,
|
||||||
|
isDefaultHidden = false,
|
||||||
|
label = 'Poll frequency',
|
||||||
|
tooltip = 'Interval used by this Edge agent to check in with the Portainer instance. Affects Edge environment management and Edge compute features.',
|
||||||
|
size = 'small',
|
||||||
|
}: Props) {
|
||||||
|
const options = useIntervalOptions(
|
||||||
|
'EdgeAgentCheckinInterval',
|
||||||
|
checkinIntervalOptions,
|
||||||
|
isDefaultHidden
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
inputId="edge_checkin"
|
||||||
|
label={label}
|
||||||
|
tooltip={tooltip}
|
||||||
|
size={size}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => {
|
||||||
|
onChange(parseInt(e.currentTarget.value, 10));
|
||||||
|
}}
|
||||||
|
options={options}
|
||||||
|
disabled={readonly}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}
|
|
@ -14,18 +14,21 @@ const edgePropertiesFormInitialValues: ScriptFormValues = {
|
||||||
platform: 'k8s' as Platform,
|
platform: 'k8s' as Platform,
|
||||||
nomadToken: '',
|
nomadToken: '',
|
||||||
authEnabled: true,
|
authEnabled: true,
|
||||||
|
tlsEnabled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
edgeInfo: EdgeInfo;
|
edgeInfo: EdgeInfo;
|
||||||
commands: CommandTab[] | Partial<Record<OS, CommandTab[]>>;
|
commands: CommandTab[] | Partial<Record<OS, CommandTab[]>>;
|
||||||
isNomadTokenVisible?: boolean;
|
isNomadTokenVisible?: boolean;
|
||||||
|
hideAsyncMode?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EdgeScriptForm({
|
export function EdgeScriptForm({
|
||||||
edgeInfo,
|
edgeInfo,
|
||||||
commands,
|
commands,
|
||||||
isNomadTokenVisible,
|
isNomadTokenVisible,
|
||||||
|
hideAsyncMode,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const showOsSelector = !(commands instanceof Array);
|
const showOsSelector = !(commands instanceof Array);
|
||||||
|
|
||||||
|
@ -60,6 +63,7 @@ export function EdgeScriptForm({
|
||||||
onPlatformChange={(platform) =>
|
onPlatformChange={(platform) =>
|
||||||
setFieldValue('platform', platform)
|
setFieldValue('platform', platform)
|
||||||
}
|
}
|
||||||
|
hideAsyncMode={hideAsyncMode}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -6,6 +6,17 @@ export function validationSchema(isNomadTokenVisible?: boolean) {
|
||||||
return object().shape({
|
return object().shape({
|
||||||
allowSelfSignedCertificates: boolean(),
|
allowSelfSignedCertificates: boolean(),
|
||||||
envVars: string(),
|
envVars: string(),
|
||||||
...(isNomadTokenVisible ? nomadTokenValidation() : {}),
|
...nomadValidation(isNomadTokenVisible),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nomadValidation(isNomadTokenVisible?: boolean) {
|
||||||
|
if (!isNomadTokenVisible) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
tlsEnabled: boolean().default(false),
|
||||||
|
...nomadTokenValidation(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Field, useFormikContext } from 'formik';
|
import { useFormikContext, Field } from 'formik';
|
||||||
|
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
||||||
import { Input } from '@@/form-components/Input';
|
import { Input } from '@@/form-components/Input';
|
||||||
|
@ -47,7 +47,22 @@ export function EdgeScriptSettingsFieldset({
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isNomadTokenVisible && <NomadTokenField />}
|
{isNomadTokenVisible && (
|
||||||
|
<>
|
||||||
|
<NomadTokenField />
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="col-sm-12">
|
||||||
|
<SwitchField
|
||||||
|
label="TLS"
|
||||||
|
labelClass="col-sm-3 col-lg-2"
|
||||||
|
checked={values.tlsEnabled}
|
||||||
|
onChange={(checked) => setFieldValue('tlsEnabled', checked)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Environment variables"
|
label="Environment variables"
|
||||||
|
|
|
@ -16,6 +16,7 @@ interface Props {
|
||||||
commands: CommandTab[];
|
commands: CommandTab[];
|
||||||
platform?: Platform;
|
platform?: Platform;
|
||||||
onPlatformChange?(platform: Platform): void;
|
onPlatformChange?(platform: Platform): void;
|
||||||
|
hideAsyncMode?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ScriptTabs({
|
export function ScriptTabs({
|
||||||
|
@ -24,6 +25,7 @@ export function ScriptTabs({
|
||||||
edgeId,
|
edgeId,
|
||||||
commands,
|
commands,
|
||||||
platform,
|
platform,
|
||||||
|
hideAsyncMode = false,
|
||||||
onPlatformChange = () => {},
|
onPlatformChange = () => {},
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const agentDetails = useAgentDetails();
|
const agentDetails = useAgentDetails();
|
||||||
|
@ -38,10 +40,17 @@ export function ScriptTabs({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { agentSecret, agentVersion } = agentDetails;
|
const { agentSecret, agentVersion, useEdgeAsyncMode } = agentDetails;
|
||||||
|
|
||||||
const options = commands.map((c) => {
|
const options = commands.map((c) => {
|
||||||
const cmd = c.command(agentVersion, edgeKey, values, edgeId, agentSecret);
|
const cmd = c.command(
|
||||||
|
agentVersion,
|
||||||
|
edgeKey,
|
||||||
|
values,
|
||||||
|
!hideAsyncMode && useEdgeAsyncMode,
|
||||||
|
edgeId,
|
||||||
|
agentSecret
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: c.id,
|
id: c.id,
|
||||||
|
|
|
@ -8,6 +8,7 @@ type CommandGenerator = (
|
||||||
agentVersion: string,
|
agentVersion: string,
|
||||||
edgeKey: string,
|
edgeKey: string,
|
||||||
properties: ScriptFormValues,
|
properties: ScriptFormValues,
|
||||||
|
useAsyncMode: boolean,
|
||||||
edgeId?: string,
|
edgeId?: string,
|
||||||
agentSecret?: string
|
agentSecret?: string
|
||||||
) => string;
|
) => string;
|
||||||
|
@ -34,6 +35,11 @@ export const commandsTabs: Record<string, CommandTab> = {
|
||||||
label: 'Docker Standalone',
|
label: 'Docker Standalone',
|
||||||
command: buildLinuxStandaloneCommand,
|
command: buildLinuxStandaloneCommand,
|
||||||
},
|
},
|
||||||
|
nomadLinux: {
|
||||||
|
id: 'nomad',
|
||||||
|
label: 'Nomad',
|
||||||
|
command: buildLinuxNomadCommand,
|
||||||
|
},
|
||||||
swarmWindows: {
|
swarmWindows: {
|
||||||
id: 'swarm',
|
id: 'swarm',
|
||||||
label: 'Docker Swarm',
|
label: 'Docker Swarm',
|
||||||
|
@ -58,6 +64,7 @@ export function buildLinuxStandaloneCommand(
|
||||||
agentVersion: string,
|
agentVersion: string,
|
||||||
edgeKey: string,
|
edgeKey: string,
|
||||||
properties: ScriptFormValues,
|
properties: ScriptFormValues,
|
||||||
|
useAsyncMode: boolean,
|
||||||
edgeId?: string,
|
edgeId?: string,
|
||||||
agentSecret?: string
|
agentSecret?: string
|
||||||
) {
|
) {
|
||||||
|
@ -69,7 +76,8 @@ export function buildLinuxStandaloneCommand(
|
||||||
edgeKey,
|
edgeKey,
|
||||||
allowSelfSignedCertificates,
|
allowSelfSignedCertificates,
|
||||||
!edgeIdGenerator ? edgeId : undefined,
|
!edgeIdGenerator ? edgeId : undefined,
|
||||||
agentSecret
|
agentSecret,
|
||||||
|
useAsyncMode
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -92,6 +100,7 @@ export function buildWindowsStandaloneCommand(
|
||||||
agentVersion: string,
|
agentVersion: string,
|
||||||
edgeKey: string,
|
edgeKey: string,
|
||||||
properties: ScriptFormValues,
|
properties: ScriptFormValues,
|
||||||
|
useAsyncMode: boolean,
|
||||||
edgeId?: string,
|
edgeId?: string,
|
||||||
agentSecret?: string
|
agentSecret?: string
|
||||||
) {
|
) {
|
||||||
|
@ -103,7 +112,8 @@ export function buildWindowsStandaloneCommand(
|
||||||
edgeKey,
|
edgeKey,
|
||||||
allowSelfSignedCertificates,
|
allowSelfSignedCertificates,
|
||||||
edgeIdGenerator ? '$Env:PORTAINER_EDGE_ID' : edgeId,
|
edgeIdGenerator ? '$Env:PORTAINER_EDGE_ID' : edgeId,
|
||||||
agentSecret
|
agentSecret,
|
||||||
|
useAsyncMode
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -127,6 +137,7 @@ export function buildLinuxSwarmCommand(
|
||||||
agentVersion: string,
|
agentVersion: string,
|
||||||
edgeKey: string,
|
edgeKey: string,
|
||||||
properties: ScriptFormValues,
|
properties: ScriptFormValues,
|
||||||
|
useAsyncMode: boolean,
|
||||||
edgeId?: string,
|
edgeId?: string,
|
||||||
agentSecret?: string
|
agentSecret?: string
|
||||||
) {
|
) {
|
||||||
|
@ -137,7 +148,8 @@ export function buildLinuxSwarmCommand(
|
||||||
edgeKey,
|
edgeKey,
|
||||||
allowSelfSignedCertificates,
|
allowSelfSignedCertificates,
|
||||||
!edgeIdGenerator ? edgeId : undefined,
|
!edgeIdGenerator ? edgeId : undefined,
|
||||||
agentSecret
|
agentSecret,
|
||||||
|
useAsyncMode
|
||||||
),
|
),
|
||||||
'AGENT_CLUSTER_ADDR=tasks.portainer_edge_agent',
|
'AGENT_CLUSTER_ADDR=tasks.portainer_edge_agent',
|
||||||
]);
|
]);
|
||||||
|
@ -167,6 +179,7 @@ export function buildWindowsSwarmCommand(
|
||||||
agentVersion: string,
|
agentVersion: string,
|
||||||
edgeKey: string,
|
edgeKey: string,
|
||||||
properties: ScriptFormValues,
|
properties: ScriptFormValues,
|
||||||
|
useAsyncMode: boolean,
|
||||||
edgeId?: string,
|
edgeId?: string,
|
||||||
agentSecret?: string
|
agentSecret?: string
|
||||||
) {
|
) {
|
||||||
|
@ -177,7 +190,8 @@ export function buildWindowsSwarmCommand(
|
||||||
edgeKey,
|
edgeKey,
|
||||||
allowSelfSignedCertificates,
|
allowSelfSignedCertificates,
|
||||||
edgeIdGenerator ? '$Env:PORTAINER_EDGE_ID' : edgeId,
|
edgeIdGenerator ? '$Env:PORTAINER_EDGE_ID' : edgeId,
|
||||||
agentSecret
|
agentSecret,
|
||||||
|
useAsyncMode
|
||||||
),
|
),
|
||||||
'AGENT_CLUSTER_ADDR=tasks.portainer_edge_agent',
|
'AGENT_CLUSTER_ADDR=tasks.portainer_edge_agent',
|
||||||
]);
|
]);
|
||||||
|
@ -208,13 +222,17 @@ export function buildLinuxKubernetesCommand(
|
||||||
agentVersion: string,
|
agentVersion: string,
|
||||||
edgeKey: string,
|
edgeKey: string,
|
||||||
properties: ScriptFormValues,
|
properties: ScriptFormValues,
|
||||||
|
useAsyncMode: boolean,
|
||||||
edgeId?: string,
|
edgeId?: string,
|
||||||
agentSecret?: string
|
agentSecret?: string
|
||||||
) {
|
) {
|
||||||
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
||||||
|
|
||||||
const agentShortVersion = getAgentShortVersion(agentVersion);
|
const agentShortVersion = getAgentShortVersion(agentVersion);
|
||||||
const envVarsTrimmed = envVars.trim();
|
let envVarsTrimmed = envVars.trim();
|
||||||
|
if (useAsyncMode) {
|
||||||
|
envVarsTrimmed += `EDGE_ASYNC=1`;
|
||||||
|
}
|
||||||
const idEnvVar = edgeIdGenerator
|
const idEnvVar = edgeIdGenerator
|
||||||
? `PORTAINER_EDGE_ID=$(${edgeIdGenerator}) \n\n`
|
? `PORTAINER_EDGE_ID=$(${edgeIdGenerator}) \n\n`
|
||||||
: '';
|
: '';
|
||||||
|
@ -224,11 +242,43 @@ export function buildLinuxKubernetesCommand(
|
||||||
return `${idEnvVar}curl https://downloads.portainer.io/ee${agentShortVersion}/portainer-edge-agent-setup.sh | bash -s -- "${edgeIdVar}" "${edgeKey}" "${selfSigned}" "${agentSecret}" "${envVarsTrimmed}"`;
|
return `${idEnvVar}curl https://downloads.portainer.io/ee${agentShortVersion}/portainer-edge-agent-setup.sh | bash -s -- "${edgeIdVar}" "${edgeKey}" "${selfSigned}" "${agentSecret}" "${envVarsTrimmed}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildLinuxNomadCommand(
|
||||||
|
agentVersion: string,
|
||||||
|
edgeKey: string,
|
||||||
|
properties: ScriptFormValues,
|
||||||
|
useAsyncMode: boolean,
|
||||||
|
edgeId?: string,
|
||||||
|
agentSecret?: string
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
allowSelfSignedCertificates,
|
||||||
|
edgeIdGenerator,
|
||||||
|
envVars,
|
||||||
|
nomadToken = '',
|
||||||
|
tlsEnabled,
|
||||||
|
} = properties;
|
||||||
|
|
||||||
|
const agentShortVersion = getAgentShortVersion(agentVersion);
|
||||||
|
let envVarsTrimmed = envVars.trim();
|
||||||
|
if (useAsyncMode) {
|
||||||
|
envVarsTrimmed += `EDGE_ASYNC=1`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selfSigned = allowSelfSignedCertificates ? '1' : '0';
|
||||||
|
const idEnvVar = edgeIdGenerator
|
||||||
|
? `PORTAINER_EDGE_ID=$(${edgeIdGenerator}) \n\n`
|
||||||
|
: '';
|
||||||
|
const edgeIdVar = !edgeIdGenerator && edgeId ? edgeId : '$PORTAINER_EDGE_ID';
|
||||||
|
|
||||||
|
return `${idEnvVar}curl https://downloads.portainer.io/ee${agentShortVersion}/portainer-edge-agent-nomad-setup.sh | bash -s -- "${nomadToken}" "${edgeIdVar}" "${edgeKey}" "${selfSigned}" "${envVarsTrimmed}" "${agentSecret}" "${tlsEnabled}"`;
|
||||||
|
}
|
||||||
|
|
||||||
function buildDefaultEnvVars(
|
function buildDefaultEnvVars(
|
||||||
edgeKey: string,
|
edgeKey: string,
|
||||||
allowSelfSignedCerts: boolean,
|
allowSelfSignedCerts: boolean,
|
||||||
edgeId = '$PORTAINER_EDGE_ID',
|
edgeId = '$PORTAINER_EDGE_ID',
|
||||||
agentSecret = ''
|
agentSecret = '',
|
||||||
|
useAsyncMode = false
|
||||||
) {
|
) {
|
||||||
return _.compact([
|
return _.compact([
|
||||||
'EDGE=1',
|
'EDGE=1',
|
||||||
|
@ -236,5 +286,6 @@ function buildDefaultEnvVars(
|
||||||
`EDGE_KEY=${edgeKey}`,
|
`EDGE_KEY=${edgeKey}`,
|
||||||
`EDGE_INSECURE_POLL=${allowSelfSignedCerts ? 1 : 0}`,
|
`EDGE_INSECURE_POLL=${allowSelfSignedCerts ? 1 : 0}`,
|
||||||
agentSecret ? `AGENT_SECRET=${agentSecret}` : ``,
|
agentSecret ? `AGENT_SECRET=${agentSecret}` : ``,
|
||||||
|
useAsyncMode ? 'EDGE_ASYNC=1' : '',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ export type OS = 'win' | 'linux';
|
||||||
export interface ScriptFormValues {
|
export interface ScriptFormValues {
|
||||||
nomadToken: string;
|
nomadToken: string;
|
||||||
authEnabled: boolean;
|
authEnabled: boolean;
|
||||||
|
tlsEnabled: boolean;
|
||||||
|
|
||||||
allowSelfSignedCertificates: boolean;
|
allowSelfSignedCertificates: boolean;
|
||||||
envVars: string;
|
envVars: string;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { usePagination, useTable } from 'react-table';
|
import { usePagination, useTable } from 'react-table';
|
||||||
|
|
||||||
import { Device } from '@/portainer/hostmanagement/open-amt/model';
|
import { Device } from '@/portainer/hostmanagement/open-amt/model';
|
||||||
import { useAMTDevices } from '@/edge/EdgeDevices/EdgeDevicesView/AMTDevicesDatatable/useAMTDevices';
|
|
||||||
import { RowProvider } from '@/edge/EdgeDevices/EdgeDevicesView/AMTDevicesDatatable/columns/RowContext';
|
|
||||||
import { EnvironmentId } from '@/react/portainer/environments/types';
|
import { EnvironmentId } from '@/react/portainer/environments/types';
|
||||||
import PortainerError from '@/portainer/error';
|
import PortainerError from '@/portainer/error';
|
||||||
|
|
||||||
import { InnerDatatable } from '@@/datatables/InnerDatatable';
|
import { InnerDatatable } from '@@/datatables/InnerDatatable';
|
||||||
import { Table, TableContainer, TableHeaderRow, TableRow } from '@@/datatables';
|
import { Table, TableContainer, TableHeaderRow, TableRow } from '@@/datatables';
|
||||||
|
|
||||||
|
import { useAMTDevices } from './useAMTDevices';
|
||||||
|
import { RowProvider } from './columns/RowContext';
|
||||||
import { useColumns } from './columns';
|
import { useColumns } from './columns';
|
||||||
|
|
||||||
export interface AMTDevicesTableProps {
|
export interface AMTDevicesTableProps {
|
|
@ -0,0 +1 @@
|
||||||
|
export { AMTDevicesDatatable } from './AMTDevicesDatatable';
|
|
@ -3,7 +3,6 @@ import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { Environment } from '@/react/portainer/environments/types';
|
import { Environment } from '@/react/portainer/environments/types';
|
||||||
import { AMTDevicesDatatable } from '@/edge/EdgeDevices/EdgeDevicesView/AMTDevicesDatatable/AMTDevicesDatatable';
|
|
||||||
import { EnvironmentGroup } from '@/react/portainer/environments/environment-groups/types';
|
import { EnvironmentGroup } from '@/react/portainer/environments/environment-groups/types';
|
||||||
|
|
||||||
import { PaginationControls } from '@@/PaginationControls';
|
import { PaginationControls } from '@@/PaginationControls';
|
||||||
|
@ -26,6 +25,7 @@ import { TableFooter } from '@@/datatables/TableFooter';
|
||||||
import { SelectedRowsCount } from '@@/datatables/SelectedRowsCount';
|
import { SelectedRowsCount } from '@@/datatables/SelectedRowsCount';
|
||||||
import { TextTip } from '@@/Tip/TextTip';
|
import { TextTip } from '@@/Tip/TextTip';
|
||||||
|
|
||||||
|
import { AMTDevicesDatatable } from './AMTDevicesDatatable';
|
||||||
import { EdgeDevicesDatatableActions } from './EdgeDevicesDatatableActions';
|
import { EdgeDevicesDatatableActions } from './EdgeDevicesDatatableActions';
|
||||||
import { EdgeDevicesDatatableSettings } from './EdgeDevicesDatatableSettings';
|
import { EdgeDevicesDatatableSettings } from './EdgeDevicesDatatableSettings';
|
||||||
import { RowProvider } from './columns/RowContext';
|
import { RowProvider } from './columns/RowContext';
|
|
@ -5,7 +5,7 @@ import { useRouter, useSref } from '@uirouter/react';
|
||||||
import { Environment } from '@/react/portainer/environments/types';
|
import { Environment } from '@/react/portainer/environments/types';
|
||||||
import { snapshotEndpoint } from '@/react/portainer/environments/environment.service';
|
import { snapshotEndpoint } from '@/react/portainer/environments/environment.service';
|
||||||
import * as notifications from '@/portainer/services/notifications';
|
import * as notifications from '@/portainer/services/notifications';
|
||||||
import { getRoute } from '@/react/portainer/environments/utils';
|
import { getDashboardRoute } from '@/react/portainer/environments/utils';
|
||||||
|
|
||||||
import { ActionsMenu } from '@@/datatables/ActionsMenu';
|
import { ActionsMenu } from '@@/datatables/ActionsMenu';
|
||||||
|
|
||||||
|
@ -27,19 +27,33 @@ export function ActionsCell({
|
||||||
}: CellProps<Environment>) {
|
}: CellProps<Environment>) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const environmentRoute = getRoute(environment);
|
const environmentRoute = getDashboardRoute(environment);
|
||||||
const browseLinkProps = useSref(environmentRoute, {
|
const browseLinkProps = useSref(environmentRoute, {
|
||||||
id: environment.Id,
|
id: environment.Id,
|
||||||
endpointId: environment.Id,
|
endpointId: environment.Id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const snapshotLinkProps = useSref('edge.browse.dashboard', {
|
||||||
|
environmentId: environment.Id,
|
||||||
|
});
|
||||||
|
|
||||||
const showRefreshSnapshot = false; // remove and show MenuItem when feature is available
|
const showRefreshSnapshot = false; // remove and show MenuItem when feature is available
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionsMenu>
|
<ActionsMenu>
|
||||||
<MenuLink href={browseLinkProps.href} onClick={browseLinkProps.onClick}>
|
{environment.Edge.AsyncMode ? (
|
||||||
Browse
|
<MenuLink
|
||||||
</MenuLink>
|
className="!text-inherit hover:!no-underline"
|
||||||
|
href={snapshotLinkProps.href}
|
||||||
|
onClick={snapshotLinkProps.onClick}
|
||||||
|
>
|
||||||
|
Browse Snapshot
|
||||||
|
</MenuLink>
|
||||||
|
) : (
|
||||||
|
<MenuLink href={browseLinkProps.href} onClick={browseLinkProps.onClick}>
|
||||||
|
Browse
|
||||||
|
</MenuLink>
|
||||||
|
)}
|
||||||
{showRefreshSnapshot && (
|
{showRefreshSnapshot && (
|
||||||
<MenuItem hidden onSelect={() => handleRefreshSnapshotClick()}>
|
<MenuItem hidden onSelect={() => handleRefreshSnapshotClick()}>
|
||||||
Refresh Snapshot
|
Refresh Snapshot
|
|
@ -8,7 +8,7 @@ import { ViewLoading } from '@@/ViewLoading';
|
||||||
|
|
||||||
import { EdgeDevicesDatatableContainer } from './EdgeDevicesDatatable/EdgeDevicesDatatableContainer';
|
import { EdgeDevicesDatatableContainer } from './EdgeDevicesDatatable/EdgeDevicesDatatableContainer';
|
||||||
|
|
||||||
export function EdgeDevicesView() {
|
export function ListView() {
|
||||||
const [loadingMessage, setLoadingMessage] = useState('');
|
const [loadingMessage, setLoadingMessage] = useState('');
|
||||||
|
|
||||||
const settingsQuery = useSettings();
|
const settingsQuery = useSettings();
|
|
@ -0,0 +1 @@
|
||||||
|
export { ListView } from './ListView';
|
|
@ -1,8 +1,8 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { Select } from '@@/form-components/ReactSelect';
|
import { EdgeGroup } from '@/react/edge/edge-groups/types';
|
||||||
|
|
||||||
import { EdgeGroup } from '../edge-groups/types';
|
import { Select } from '@@/form-components/ReactSelect';
|
||||||
|
|
||||||
type SingleValue = EdgeGroup['Id'];
|
type SingleValue = EdgeGroup['Id'];
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useStatus } from '@/portainer/services/api/status.service';
|
||||||
import { useSettings } from '@/react/portainer/settings/queries';
|
import { useSettings } from '@/react/portainer/settings/queries';
|
||||||
|
|
||||||
export function useAgentDetails() {
|
export function useAgentDetails() {
|
||||||
const settingsQuery = useSettings((settings) => settings.AgentSecret);
|
const settingsQuery = useSettings();
|
||||||
|
|
||||||
const versionQuery = useStatus((status) => status.Version);
|
const versionQuery = useStatus((status) => status.Version);
|
||||||
|
|
||||||
|
@ -11,7 +11,10 @@ export function useAgentDetails() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const agentVersion = versionQuery.data;
|
const agentVersion = versionQuery.data;
|
||||||
const agentSecret = settingsQuery.data;
|
|
||||||
|
|
||||||
return { agentVersion, agentSecret };
|
return {
|
||||||
|
agentVersion,
|
||||||
|
agentSecret: settingsQuery.data.AgentSecret,
|
||||||
|
useEdgeAsyncMode: settingsQuery.data.Edge.AsyncMode,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ export function isUnassociatedEdgeEnvironment(env: Environment) {
|
||||||
return isEdgeEnvironment(env.Type) && !env.EdgeID;
|
return isEdgeEnvironment(env.Type) && !env.EdgeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRoute(environment: Environment) {
|
export function getDashboardRoute(environment: Environment) {
|
||||||
if (isEdgeEnvironment(environment.Type) && !environment.EdgeID) {
|
if (isEdgeEnvironment(environment.Type) && !environment.EdgeID) {
|
||||||
return 'portainer.endpoints.endpoint';
|
return 'portainer.endpoints.endpoint';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Formik, Form } from 'formik';
|
||||||
import { Environment } from '@/react/portainer/environments/types';
|
import { Environment } from '@/react/portainer/environments/types';
|
||||||
import { useCreateEdgeAgentEnvironmentMutation } from '@/react/portainer/environments/queries/useCreateEnvironmentMutation';
|
import { useCreateEdgeAgentEnvironmentMutation } from '@/react/portainer/environments/queries/useCreateEnvironmentMutation';
|
||||||
import { baseHref } from '@/portainer/helpers/pathHelper';
|
import { baseHref } from '@/portainer/helpers/pathHelper';
|
||||||
import { EdgeCheckinIntervalField } from '@/edge/components/EdgeCheckInIntervalField';
|
import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField';
|
||||||
import { useCreateEdgeDeviceParam } from '@/react/portainer/environments/wizard/hooks/useCreateEdgeDeviceParam';
|
import { useCreateEdgeDeviceParam } from '@/react/portainer/environments/wizard/hooks/useCreateEdgeDeviceParam';
|
||||||
|
|
||||||
import { FormSection } from '@@/form-components/FormSection';
|
import { FormSection } from '@@/form-components/FormSection';
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Form, Formik } from 'formik';
|
import { Form, Formik } from 'formik';
|
||||||
import { useReducer } from 'react';
|
import { useReducer } from 'react';
|
||||||
|
|
||||||
import { EdgeCheckinIntervalField } from '@/edge/components/EdgeCheckInIntervalField';
|
import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField';
|
||||||
import { EdgeAsyncIntervalsForm } from '@/edge/components/EdgeAsyncIntervalsForm';
|
import { EdgeAsyncIntervalsForm } from '@/react/edge/components/EdgeAsyncIntervalsForm';
|
||||||
import { notifySuccess } from '@/portainer/services/notifications';
|
import { notifySuccess } from '@/portainer/services/notifications';
|
||||||
|
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { boolean, number, object, SchemaOf } from 'yup';
|
import { boolean, number, object, SchemaOf } from 'yup';
|
||||||
|
|
||||||
import { options as asyncIntervalOptions } from '@/edge/components/EdgeAsyncIntervalsForm';
|
import { options as asyncIntervalOptions } from '@/react/edge/components/EdgeAsyncIntervalsForm';
|
||||||
|
|
||||||
import { FormValues } from './types';
|
import { FormValues } from './types';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Formik, Form } from 'formik';
|
import { Formik, Form } from 'formik';
|
||||||
|
|
||||||
import { EdgeCheckinIntervalField } from '@/edge/components/EdgeCheckInIntervalField';
|
import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField';
|
||||||
|
|
||||||
import { Switch } from '@@/form-components/SwitchField/Switch';
|
import { Switch } from '@@/form-components/SwitchField/Switch';
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
||||||
|
|
Loading…
Reference in New Issue