chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { Formik } from 'formik';
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import { OsSelector } from './OsSelector';
|
||||
import { CommandTab } from './scripts';
|
||||
import { ScriptTabs } from './ScriptTabs';
|
||||
import { EdgeScriptSettingsFieldset } from './EdgeScriptSettingsFieldset';
|
||||
import { validationSchema } from './EdgeScriptForm.validation';
|
||||
import { ScriptFormValues, OS, Platform, EdgeInfo } from './types';
|
||||
|
||||
const edgePropertiesFormInitialValues: ScriptFormValues = {
|
||||
allowSelfSignedCertificates: true,
|
||||
envVars: '',
|
||||
os: 'linux' as OS,
|
||||
platform: 'k8s' as Platform,
|
||||
authEnabled: true,
|
||||
tlsEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
group: 0,
|
||||
tagsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
};
|
||||
|
||||
interface Props {
|
||||
edgeInfo: EdgeInfo;
|
||||
commands: CommandTab[] | Partial<Record<OS, CommandTab[]>>;
|
||||
asyncMode?: boolean;
|
||||
showMetaFields?: boolean;
|
||||
}
|
||||
|
||||
export function EdgeScriptForm({
|
||||
edgeInfo,
|
||||
commands,
|
||||
asyncMode,
|
||||
showMetaFields,
|
||||
children,
|
||||
}: PropsWithChildren<Props>) {
|
||||
const showOsSelector = !(commands instanceof Array);
|
||||
|
||||
return (
|
||||
<div className="form-horizontal">
|
||||
<Formik
|
||||
initialValues={edgePropertiesFormInitialValues}
|
||||
validationSchema={() => validationSchema()}
|
||||
onSubmit={() => {}}
|
||||
validateOnMount
|
||||
>
|
||||
{({ values, setFieldValue }) => (
|
||||
<>
|
||||
{children}
|
||||
|
||||
<EdgeScriptSettingsFieldset
|
||||
hideIdGetter={edgeInfo.id !== undefined}
|
||||
showMetaFields={showMetaFields}
|
||||
/>
|
||||
<div className="mt-8">
|
||||
{showOsSelector && (
|
||||
<OsSelector
|
||||
value={values.os}
|
||||
onChange={(value) => setFieldValue('os', value)}
|
||||
/>
|
||||
)}
|
||||
<ScriptTabs
|
||||
edgeId={edgeInfo.id}
|
||||
edgeKey={edgeInfo.key}
|
||||
values={values}
|
||||
commands={showOsSelector ? commands[values.os] || [] : commands}
|
||||
platform={values.platform}
|
||||
onPlatformChange={(platform) =>
|
||||
setFieldValue('platform', platform)
|
||||
}
|
||||
asyncMode={asyncMode}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Formik>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { object, boolean, string } from 'yup';
|
||||
|
||||
export function validationSchema() {
|
||||
return object().shape({
|
||||
allowSelfSignedCertificates: boolean(),
|
||||
envVars: string(),
|
||||
edgeIdGenerator: string()
|
||||
.required('Edge ID Generator is required')
|
||||
.test(
|
||||
'valid edge id generator',
|
||||
'edge id generator cannot be empty',
|
||||
(value) => !!(value && value.length)
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import { useFormikContext, Field } from 'formik';
|
||||
|
||||
import { GroupField } from '@/react/portainer/environments/common/MetadataFieldset/GroupsField';
|
||||
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
import { Input } from '@@/form-components/Input';
|
||||
import { SwitchField } from '@@/form-components/SwitchField';
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { TagSelector } from '@@/TagSelector';
|
||||
|
||||
import { EdgeGroupsSelector } from '../../edge-stacks/components/EdgeGroupsSelector';
|
||||
|
||||
import { ScriptFormValues } from './types';
|
||||
|
||||
interface Props {
|
||||
hideIdGetter?: boolean;
|
||||
showMetaFields?: boolean;
|
||||
}
|
||||
|
||||
export function EdgeScriptSettingsFieldset({
|
||||
hideIdGetter,
|
||||
showMetaFields,
|
||||
}: Props) {
|
||||
const { values, setFieldValue, errors } =
|
||||
useFormikContext<ScriptFormValues>();
|
||||
|
||||
return (
|
||||
<>
|
||||
{showMetaFields && (
|
||||
<>
|
||||
<GroupField name="group" />
|
||||
|
||||
<EdgeGroupsSelector
|
||||
value={values.edgeGroupsIds}
|
||||
onChange={(value) => setFieldValue('edgeGroupsIds', value)}
|
||||
isGroupVisible={(group) => !group.Dynamic}
|
||||
horizontal
|
||||
/>
|
||||
|
||||
<TagSelector
|
||||
value={values.tagsIds}
|
||||
onChange={(value) => setFieldValue('tagsIds', value)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{!hideIdGetter && (
|
||||
<>
|
||||
<FormControl
|
||||
label="Edge ID Generator"
|
||||
tooltip="Enter a single-line bash command that generates a unique Edge ID. For example, you can use 'uuidgen' or 'uuid'. The result will be assigned to the 'PORTAINER_EDGE_ID' environment variable."
|
||||
inputId="edge-id-generator-input"
|
||||
required
|
||||
errors={errors.edgeIdGenerator}
|
||||
>
|
||||
<Input
|
||||
type="text"
|
||||
value={values.edgeIdGenerator}
|
||||
name="edgeIdGenerator"
|
||||
placeholder="e.g. uuidgen"
|
||||
id="edge-id-generator-input"
|
||||
onChange={(e) => setFieldValue(e.target.name, e.target.value)}
|
||||
data-cy="edge-id-generator-input"
|
||||
/>
|
||||
</FormControl>
|
||||
<div className="form-group">
|
||||
<div className="col-sm-12">
|
||||
<TextTip color="blue">
|
||||
<code>PORTAINER_EDGE_ID</code> environment variable is required
|
||||
to successfully connect the edge agent to Portainer
|
||||
</TextTip>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<FormControl
|
||||
label="Environment variables"
|
||||
tooltip="Comma separated list of environment variables that will be sourced from the host where the agent is deployed."
|
||||
inputId="env-variables-input"
|
||||
>
|
||||
<Field
|
||||
name="envVars"
|
||||
as={Input}
|
||||
placeholder="e.g. foo=bar"
|
||||
id="env-variables-input"
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<TextTip color="orange" className="icon-orange mb-2">
|
||||
For security purposes, only environment variables prefixed with
|
||||
'PORTAINER_' will be accessible.
|
||||
</TextTip>
|
||||
|
||||
<div className="form-group">
|
||||
<div className="col-sm-12">
|
||||
<SwitchField
|
||||
checked={values.allowSelfSignedCertificates}
|
||||
data-cy="allow-self-signed-certs-switch"
|
||||
onChange={(value) =>
|
||||
setFieldValue('allowSelfSignedCertificates', value)
|
||||
}
|
||||
label="Allow self-signed certs"
|
||||
labelClass="col-sm-3 col-lg-2"
|
||||
tooltip="When allowing self-signed certificates the edge agent will ignore the domain validation when connecting to Portainer via HTTPS"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { LayoutGrid } from 'lucide-react';
|
||||
|
||||
import Linux from '@/assets/ico/linux.svg?c';
|
||||
|
||||
import { ButtonSelector } from '@@/form-components/ButtonSelector/ButtonSelector';
|
||||
import { Icon } from '@@/Icon';
|
||||
|
||||
import { OS } from './types';
|
||||
|
||||
interface Props {
|
||||
value: OS;
|
||||
onChange(value: OS): void;
|
||||
}
|
||||
|
||||
export function OsSelector({ onChange, value }: Props) {
|
||||
return (
|
||||
<div className="form-group">
|
||||
<div className="col-sm-12">
|
||||
<ButtonSelector
|
||||
size="small"
|
||||
value={value}
|
||||
onChange={(os: OS) => onChange(os)}
|
||||
options={[
|
||||
{
|
||||
value: 'linux',
|
||||
label: (
|
||||
<>
|
||||
<Icon icon={Linux} className="mr-1" />
|
||||
Linux & Windows WSL
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: 'win',
|
||||
label: (
|
||||
<>
|
||||
<Icon icon={LayoutGrid} className="mr-1" />
|
||||
Windows WCS
|
||||
</>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { useAgentDetails } from '@/react/portainer/environments/queries/useAgentDetails';
|
||||
|
||||
import { Code } from '@@/Code';
|
||||
import { CopyButton } from '@@/buttons/CopyButton';
|
||||
import { NavTabs } from '@@/NavTabs';
|
||||
import { NavContainer } from '@@/NavTabs/NavContainer';
|
||||
|
||||
import { ScriptFormValues, Platform } from './types';
|
||||
import { CommandTab } from './scripts';
|
||||
|
||||
interface Props {
|
||||
values: ScriptFormValues;
|
||||
edgeKey: string;
|
||||
edgeId?: string;
|
||||
commands: CommandTab[];
|
||||
platform?: Platform;
|
||||
onPlatformChange?(platform: Platform): void;
|
||||
asyncMode?: boolean;
|
||||
}
|
||||
|
||||
export function ScriptTabs({
|
||||
values,
|
||||
edgeKey,
|
||||
edgeId,
|
||||
commands,
|
||||
platform,
|
||||
asyncMode = false,
|
||||
onPlatformChange = () => {},
|
||||
}: Props) {
|
||||
const agentDetails = useAgentDetails();
|
||||
|
||||
useEffect(() => {
|
||||
if (commands.length > 0 && commands.every((p) => p.id !== platform)) {
|
||||
onPlatformChange(commands[0].id);
|
||||
}
|
||||
}, [platform, onPlatformChange, commands]);
|
||||
|
||||
if (!agentDetails) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { agentSecret, agentVersion } = agentDetails;
|
||||
|
||||
const options = commands.map((c) => {
|
||||
const cmd = c.command(
|
||||
agentVersion,
|
||||
edgeKey,
|
||||
values,
|
||||
asyncMode,
|
||||
edgeId,
|
||||
agentSecret
|
||||
);
|
||||
|
||||
return {
|
||||
id: c.id,
|
||||
label: c.label,
|
||||
children: (
|
||||
<>
|
||||
<Code>{cmd}</Code>
|
||||
<div className="mt-2">
|
||||
<CopyButton copyText={cmd} data-cy="copy-edge-script-button">
|
||||
Copy
|
||||
</CopyButton>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<NavContainer>
|
||||
<NavTabs
|
||||
selectedId={platform}
|
||||
options={options}
|
||||
onSelect={(id: Platform) => onPlatformChange(id)}
|
||||
/>
|
||||
</NavContainer>
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
export { EdgeScriptForm } from './EdgeScriptForm';
|
||||
@@ -0,0 +1,318 @@
|
||||
import {
|
||||
buildLinuxPodmanCommand,
|
||||
buildLinuxStandaloneCommand,
|
||||
buildLinuxSwarmCommand,
|
||||
buildLinuxKubernetesCommand,
|
||||
buildWindowsStandaloneCommand,
|
||||
buildWindowsSwarmCommand,
|
||||
} from './scripts';
|
||||
import { ScriptFormValues } from './types';
|
||||
|
||||
it('buildLinuxPodmanCommand should include PODMAN=1', () => {
|
||||
const command = buildLinuxPodmanCommand(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
{
|
||||
allowSelfSignedCertificates: false,
|
||||
authEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
envVars: '',
|
||||
group: 0,
|
||||
os: 'linux',
|
||||
platform: 'podman',
|
||||
tagsIds: [],
|
||||
tlsEnabled: false,
|
||||
},
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toContain('PODMAN=1');
|
||||
});
|
||||
|
||||
describe.each([
|
||||
{
|
||||
name: 'buildLinuxStandaloneCommand',
|
||||
builder: buildLinuxStandaloneCommand,
|
||||
defaultProperties: {
|
||||
allowSelfSignedCertificates: false,
|
||||
authEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
envVars: '',
|
||||
group: 0,
|
||||
os: 'linux' as const,
|
||||
platform: 'standalone' as const,
|
||||
tagsIds: [],
|
||||
tlsEnabled: false,
|
||||
},
|
||||
edgeIdGeneratorValue: 'uuidgen',
|
||||
},
|
||||
{
|
||||
name: 'buildLinuxPodmanCommand',
|
||||
builder: buildLinuxPodmanCommand,
|
||||
defaultProperties: {
|
||||
allowSelfSignedCertificates: false,
|
||||
authEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
envVars: '',
|
||||
group: 0,
|
||||
os: 'linux' as const,
|
||||
platform: 'podman' as const,
|
||||
tagsIds: [],
|
||||
tlsEnabled: false,
|
||||
},
|
||||
edgeIdGeneratorValue: 'uuidgen',
|
||||
},
|
||||
{
|
||||
name: 'buildLinuxSwarmCommand',
|
||||
builder: buildLinuxSwarmCommand,
|
||||
defaultProperties: {
|
||||
allowSelfSignedCertificates: false,
|
||||
authEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
envVars: '',
|
||||
group: 0,
|
||||
os: 'linux' as const,
|
||||
platform: 'swarm' as const,
|
||||
tagsIds: [],
|
||||
tlsEnabled: false,
|
||||
},
|
||||
edgeIdGeneratorValue: 'uuidgen',
|
||||
},
|
||||
{
|
||||
name: 'buildLinuxKubernetesCommand',
|
||||
builder: buildLinuxKubernetesCommand,
|
||||
defaultProperties: {
|
||||
allowSelfSignedCertificates: false,
|
||||
authEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
envVars: '',
|
||||
group: 0,
|
||||
os: 'linux' as const,
|
||||
platform: 'k8s' as const,
|
||||
tagsIds: [],
|
||||
tlsEnabled: false,
|
||||
},
|
||||
edgeIdGeneratorValue: 'uuidgen',
|
||||
},
|
||||
{
|
||||
name: 'buildWindowsStandaloneCommand',
|
||||
builder: buildWindowsStandaloneCommand,
|
||||
defaultProperties: {
|
||||
allowSelfSignedCertificates: false,
|
||||
authEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
envVars: '',
|
||||
group: 0,
|
||||
os: 'win' as const,
|
||||
platform: 'standalone' as const,
|
||||
tagsIds: [],
|
||||
tlsEnabled: false,
|
||||
},
|
||||
edgeIdGeneratorValue: 'Get-MachineGUID',
|
||||
},
|
||||
{
|
||||
name: 'buildWindowsSwarmCommand',
|
||||
builder: buildWindowsSwarmCommand,
|
||||
defaultProperties: {
|
||||
allowSelfSignedCertificates: false,
|
||||
authEnabled: false,
|
||||
edgeGroupsIds: [],
|
||||
edgeIdGenerator: '',
|
||||
envVars: '',
|
||||
group: 0,
|
||||
os: 'win' as const,
|
||||
platform: 'swarm' as const,
|
||||
tagsIds: [],
|
||||
tlsEnabled: false,
|
||||
},
|
||||
edgeIdGeneratorValue: 'Get-MachineGUID',
|
||||
},
|
||||
])('$name', ({ builder, defaultProperties, edgeIdGeneratorValue }) => {
|
||||
it('should generate basic command with minimal configuration', () => {
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
defaultProperties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with async mode enabled', () => {
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
defaultProperties,
|
||||
true,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with self-signed certificates allowed', () => {
|
||||
const properties: ScriptFormValues = {
|
||||
...defaultProperties,
|
||||
allowSelfSignedCertificates: true,
|
||||
};
|
||||
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
properties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with edge ID generator', () => {
|
||||
const properties: ScriptFormValues = {
|
||||
...defaultProperties,
|
||||
edgeIdGenerator: edgeIdGeneratorValue,
|
||||
};
|
||||
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
properties,
|
||||
false,
|
||||
undefined,
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with custom environment variables', () => {
|
||||
const properties: ScriptFormValues = {
|
||||
...defaultProperties,
|
||||
envVars: 'MY_VAR=value1,ANOTHER_VAR=value2',
|
||||
};
|
||||
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
properties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with edge groups', () => {
|
||||
const properties: ScriptFormValues = {
|
||||
...defaultProperties,
|
||||
edgeGroupsIds: [1, 2, 3],
|
||||
};
|
||||
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
properties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with portainer group', () => {
|
||||
const properties: ScriptFormValues = {
|
||||
...defaultProperties,
|
||||
group: 5,
|
||||
};
|
||||
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
properties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with tags', () => {
|
||||
const properties: ScriptFormValues = {
|
||||
...defaultProperties,
|
||||
tagsIds: [10, 20, 30],
|
||||
};
|
||||
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
properties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with all meta variables', () => {
|
||||
const properties: ScriptFormValues = {
|
||||
...defaultProperties,
|
||||
edgeGroupsIds: [1, 2],
|
||||
group: 5,
|
||||
tagsIds: [10, 20],
|
||||
};
|
||||
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
properties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
'test-secret'
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command without agent secret', () => {
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
defaultProperties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
undefined
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate command with empty agent secret', () => {
|
||||
const command = builder(
|
||||
'2.19.0',
|
||||
'test-edge-key',
|
||||
defaultProperties,
|
||||
false,
|
||||
'test-edge-id',
|
||||
''
|
||||
);
|
||||
|
||||
expect(command).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,332 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
import { getAgentShortVersion } from '@/portainer/views/endpoints/helpers';
|
||||
|
||||
import { ScriptFormValues, Platform } from './types';
|
||||
|
||||
type CommandGenerator = (
|
||||
agentVersion: string,
|
||||
edgeKey: string,
|
||||
properties: ScriptFormValues,
|
||||
useAsyncMode: boolean,
|
||||
edgeId?: string,
|
||||
agentSecret?: string
|
||||
) => string;
|
||||
|
||||
export type CommandTab = {
|
||||
id: Platform;
|
||||
label: string;
|
||||
command: CommandGenerator;
|
||||
};
|
||||
|
||||
export const commandsTabs: Record<string, CommandTab> = {
|
||||
k8sLinux: {
|
||||
id: 'k8s',
|
||||
label: 'Kubernetes',
|
||||
command: buildLinuxKubernetesCommand,
|
||||
},
|
||||
swarmLinux: {
|
||||
id: 'swarm',
|
||||
label: 'Docker Swarm',
|
||||
command: buildLinuxSwarmCommand,
|
||||
},
|
||||
standaloneLinux: {
|
||||
id: 'standalone',
|
||||
label: 'Docker Standalone',
|
||||
command: buildLinuxStandaloneCommand,
|
||||
},
|
||||
podmanLinux: {
|
||||
id: 'podman',
|
||||
label: 'Podman',
|
||||
command: buildLinuxPodmanCommand,
|
||||
},
|
||||
swarmWindows: {
|
||||
id: 'swarm',
|
||||
label: 'Docker Swarm',
|
||||
command: buildWindowsSwarmCommand,
|
||||
},
|
||||
standaloneWindow: {
|
||||
id: 'standalone',
|
||||
label: 'Docker Standalone',
|
||||
command: buildWindowsStandaloneCommand,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export function buildLinuxStandaloneCommand(
|
||||
agentVersion: string,
|
||||
edgeKey: string,
|
||||
properties: ScriptFormValues,
|
||||
useAsyncMode: boolean,
|
||||
edgeId?: string,
|
||||
agentSecret?: string
|
||||
) {
|
||||
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
||||
|
||||
const env = buildDockerEnvVars(envVars, [
|
||||
...buildDefaultDockerEnvVars(
|
||||
edgeKey,
|
||||
allowSelfSignedCertificates,
|
||||
!edgeIdGenerator ? edgeId : undefined,
|
||||
agentSecret,
|
||||
useAsyncMode
|
||||
),
|
||||
...metaEnvVars(properties),
|
||||
]);
|
||||
|
||||
return `${
|
||||
edgeIdGenerator ? `PORTAINER_EDGE_ID=$(${edgeIdGenerator}) \n\n` : ''
|
||||
}\
|
||||
docker run -d \\
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \\
|
||||
-v /var/lib/docker/volumes:/var/lib/docker/volumes \\
|
||||
-v /:/host \\
|
||||
-v portainer_agent_data:/data \\
|
||||
--restart always \\
|
||||
${env} \\
|
||||
--name portainer_edge_agent \\
|
||||
portainer/agent:${agentVersion}
|
||||
`;
|
||||
}
|
||||
|
||||
export function buildLinuxPodmanCommand(
|
||||
agentVersion: string,
|
||||
edgeKey: string,
|
||||
properties: ScriptFormValues,
|
||||
useAsyncMode: boolean,
|
||||
edgeId?: string,
|
||||
agentSecret?: string
|
||||
) {
|
||||
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
||||
|
||||
const env = buildDockerEnvVars(envVars, [
|
||||
...buildDefaultDockerEnvVars(
|
||||
edgeKey,
|
||||
allowSelfSignedCertificates,
|
||||
!edgeIdGenerator ? edgeId : undefined,
|
||||
agentSecret,
|
||||
useAsyncMode
|
||||
),
|
||||
'PODMAN=1',
|
||||
...metaEnvVars(properties),
|
||||
]);
|
||||
|
||||
return `${
|
||||
edgeIdGenerator ? `PORTAINER_EDGE_ID=$(${edgeIdGenerator}) \n\n` : ''
|
||||
}\
|
||||
sudo podman volume create portainer_agent_data
|
||||
|
||||
sudo podman run -d \\
|
||||
-v /run/podman/podman.sock:/var/run/docker.sock \\
|
||||
-v /var/lib/containers/storage/volumes:/var/lib/docker/volumes \\
|
||||
-v /:/host \\
|
||||
-v portainer_agent_data:/data \\
|
||||
--restart always \\
|
||||
--privileged \\
|
||||
${env} \\
|
||||
--name portainer_edge_agent \\
|
||||
docker.io/portainer/agent:${agentVersion}
|
||||
`;
|
||||
}
|
||||
|
||||
export function buildWindowsStandaloneCommand(
|
||||
agentVersion: string,
|
||||
edgeKey: string,
|
||||
properties: ScriptFormValues,
|
||||
useAsyncMode: boolean,
|
||||
edgeId?: string,
|
||||
agentSecret?: string
|
||||
) {
|
||||
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
||||
|
||||
const env = buildDockerEnvVars(
|
||||
envVars,
|
||||
[
|
||||
...buildDefaultDockerEnvVars(
|
||||
edgeKey,
|
||||
allowSelfSignedCertificates,
|
||||
edgeIdGenerator ? '$Env:PORTAINER_EDGE_ID' : edgeId,
|
||||
agentSecret,
|
||||
useAsyncMode
|
||||
),
|
||||
...metaEnvVars(properties),
|
||||
],
|
||||
'`'
|
||||
);
|
||||
|
||||
return `${
|
||||
edgeIdGenerator
|
||||
? `$Env:PORTAINER_EDGE_ID = "@(${edgeIdGenerator})" \n\n`
|
||||
: ''
|
||||
}\
|
||||
docker run -d \`
|
||||
--mount type=npipe,src=\\\\.\\pipe\\docker_engine,dst=\\\\.\\pipe\\docker_engine \`
|
||||
--mount type=bind,src=C:\\ProgramData\\docker\\volumes,dst=C:\\ProgramData\\docker\\volumes \`
|
||||
--mount type=volume,src=portainer_agent_data,dst=C:\\data \`
|
||||
--restart always \`
|
||||
${env} \`
|
||||
--name portainer_edge_agent \`
|
||||
portainer/agent:${agentVersion}
|
||||
`;
|
||||
}
|
||||
|
||||
export function buildLinuxSwarmCommand(
|
||||
agentVersion: string,
|
||||
edgeKey: string,
|
||||
properties: ScriptFormValues,
|
||||
useAsyncMode: boolean,
|
||||
edgeId?: string,
|
||||
agentSecret?: string
|
||||
) {
|
||||
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
||||
|
||||
const env = buildDockerEnvVars(envVars, [
|
||||
...buildDefaultDockerEnvVars(
|
||||
edgeKey,
|
||||
allowSelfSignedCertificates,
|
||||
!edgeIdGenerator ? edgeId : undefined,
|
||||
agentSecret,
|
||||
useAsyncMode
|
||||
),
|
||||
'AGENT_CLUSTER_ADDR=tasks.portainer_edge_agent',
|
||||
...metaEnvVars(properties),
|
||||
]);
|
||||
|
||||
return `${
|
||||
edgeIdGenerator ? `PORTAINER_EDGE_ID=$(${edgeIdGenerator}) \n\n` : ''
|
||||
}\
|
||||
docker network create \\
|
||||
--driver overlay \\
|
||||
portainer_agent_network;
|
||||
|
||||
docker service create \\
|
||||
--name portainer_edge_agent \\
|
||||
--network portainer_agent_network \\
|
||||
${env} \\
|
||||
--mode global \\
|
||||
--constraint 'node.platform.os == linux' \\
|
||||
--mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock \\
|
||||
--mount type=bind,src=//var/lib/docker/volumes,dst=/var/lib/docker/volumes \\
|
||||
--mount type=bind,src=//,dst=/host \\
|
||||
--mount type=volume,src=portainer_agent_data,dst=/data \\
|
||||
portainer/agent:${agentVersion}
|
||||
`;
|
||||
}
|
||||
|
||||
export function buildWindowsSwarmCommand(
|
||||
agentVersion: string,
|
||||
edgeKey: string,
|
||||
properties: ScriptFormValues,
|
||||
useAsyncMode: boolean,
|
||||
edgeId?: string,
|
||||
agentSecret?: string
|
||||
) {
|
||||
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
||||
|
||||
const env = buildDockerEnvVars(
|
||||
envVars,
|
||||
[
|
||||
...buildDefaultDockerEnvVars(
|
||||
edgeKey,
|
||||
allowSelfSignedCertificates,
|
||||
edgeIdGenerator ? '$Env:PORTAINER_EDGE_ID' : edgeId,
|
||||
agentSecret,
|
||||
useAsyncMode
|
||||
),
|
||||
'AGENT_CLUSTER_ADDR=tasks.portainer_edge_agent',
|
||||
...metaEnvVars(properties),
|
||||
],
|
||||
'`'
|
||||
);
|
||||
|
||||
return `${
|
||||
edgeIdGenerator
|
||||
? `$Env:PORTAINER_EDGE_ID = "@(${edgeIdGenerator})" \n\n`
|
||||
: ''
|
||||
}\
|
||||
docker network create \`
|
||||
--driver overlay \`
|
||||
portainer_agent_network;
|
||||
|
||||
docker service create \`
|
||||
--name portainer_edge_agent \`
|
||||
--network portainer_agent_network \`
|
||||
${env} \`
|
||||
--mode global \`
|
||||
--constraint 'node.platform.os == windows' \`
|
||||
--mount type=npipe,src=\\\\.\\pipe\\docker_engine,dst=\\\\.\\pipe\\docker_engine \`
|
||||
--mount type=bind,src=C:\\ProgramData\\docker\\volumes,dst=C:\\ProgramData\\docker\\volumes \`
|
||||
--mount type=volume,src=portainer_agent_data,dst=C:\\data \`
|
||||
portainer/agent:${agentVersion}
|
||||
`;
|
||||
}
|
||||
|
||||
export function buildLinuxKubernetesCommand(
|
||||
agentVersion: string,
|
||||
edgeKey: string,
|
||||
properties: ScriptFormValues,
|
||||
useAsyncMode: boolean,
|
||||
edgeId?: string,
|
||||
agentSecret?: string
|
||||
) {
|
||||
const { allowSelfSignedCertificates, edgeIdGenerator, envVars } = properties;
|
||||
|
||||
const agentShortVersion = getAgentShortVersion(agentVersion);
|
||||
const allEnvVars = buildEnvVars(
|
||||
envVars,
|
||||
_.compact([useAsyncMode && 'EDGE_ASYNC=1', ...metaEnvVars(properties)])
|
||||
);
|
||||
|
||||
const idEnvVar = edgeIdGenerator
|
||||
? `PORTAINER_EDGE_ID=$(${edgeIdGenerator}) \n\n`
|
||||
: '';
|
||||
const edgeIdVar = !edgeIdGenerator && edgeId ? edgeId : '$PORTAINER_EDGE_ID';
|
||||
const selfSigned = allowSelfSignedCertificates ? '1' : '0';
|
||||
|
||||
return `${idEnvVar}curl https://downloads.portainer.io/ee${agentShortVersion}/portainer-edge-agent-setup.sh | bash -s -- "${edgeIdVar}" "${edgeKey}" "${selfSigned}" "${agentSecret}" "${allEnvVars}"`;
|
||||
}
|
||||
|
||||
function buildDockerEnvVars(
|
||||
envVars: string,
|
||||
moreVars: string[],
|
||||
lineContinuationToken = '\\'
|
||||
) {
|
||||
const vars = moreVars.concat(envVars.split(',').filter((s) => s.length > 0));
|
||||
|
||||
return vars.map((s) => `-e ${s}`).join(` ${lineContinuationToken}\n `);
|
||||
}
|
||||
|
||||
function buildDefaultDockerEnvVars(
|
||||
edgeKey: string,
|
||||
allowSelfSignedCerts: boolean,
|
||||
edgeId = '$PORTAINER_EDGE_ID',
|
||||
agentSecret = '',
|
||||
useAsyncMode = false
|
||||
) {
|
||||
return _.compact([
|
||||
'EDGE=1',
|
||||
`EDGE_ID=${edgeId}`,
|
||||
`EDGE_KEY=${edgeKey}`,
|
||||
`EDGE_INSECURE_POLL=${allowSelfSignedCerts ? 1 : 0}`,
|
||||
agentSecret ? `AGENT_SECRET=${agentSecret}` : ``,
|
||||
useAsyncMode ? 'EDGE_ASYNC=1' : '',
|
||||
]);
|
||||
}
|
||||
|
||||
const ENV_VAR_SEPARATOR = ',';
|
||||
const VAR_LIST_SEPARATOR = ':';
|
||||
function buildEnvVars(envVars: string, moreVars: string[]) {
|
||||
return _.compact([envVars.trim(), ...moreVars]).join(ENV_VAR_SEPARATOR);
|
||||
}
|
||||
|
||||
function metaEnvVars({
|
||||
edgeGroupsIds,
|
||||
group,
|
||||
tagsIds,
|
||||
}: Pick<ScriptFormValues, 'edgeGroupsIds' | 'tagsIds' | 'group'>) {
|
||||
return _.compact([
|
||||
edgeGroupsIds.length &&
|
||||
`EDGE_GROUPS=${edgeGroupsIds.join(VAR_LIST_SEPARATOR)}`,
|
||||
group && `PORTAINER_GROUP=${group}`,
|
||||
tagsIds.length && `PORTAINER_TAGS=${tagsIds.join(VAR_LIST_SEPARATOR)}`,
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { TagId } from '@/portainer/tags/types';
|
||||
import { EnvironmentGroupId } from '@/react/portainer/environments/types';
|
||||
|
||||
import { EdgeGroup } from '../../edge-groups/types';
|
||||
|
||||
export type Platform = 'standalone' | 'swarm' | 'podman' | 'k8s' | 'kubesolo';
|
||||
export type OS = 'win' | 'linux';
|
||||
|
||||
export interface ScriptFormValues {
|
||||
authEnabled: boolean;
|
||||
tlsEnabled: boolean;
|
||||
|
||||
allowSelfSignedCertificates: boolean;
|
||||
envVars: string;
|
||||
|
||||
os: OS;
|
||||
platform: Platform;
|
||||
|
||||
edgeIdGenerator: string;
|
||||
|
||||
group: EnvironmentGroupId;
|
||||
edgeGroupsIds: Array<EdgeGroup['Id']>;
|
||||
tagsIds: Array<TagId>;
|
||||
}
|
||||
|
||||
export interface EdgeInfo {
|
||||
id?: string;
|
||||
key: string;
|
||||
}
|
||||
Reference in New Issue
Block a user