diff --git a/app/edge/EdgeDevices/EdgeDevicesView/EdgeDevicesDatatable/EdgeDevicesDatatableActions.tsx b/app/edge/EdgeDevices/EdgeDevicesView/EdgeDevicesDatatable/EdgeDevicesDatatableActions.tsx index a05db1151..9e052651b 100644 --- a/app/edge/EdgeDevices/EdgeDevicesView/EdgeDevicesDatatable/EdgeDevicesDatatableActions.tsx +++ b/app/edge/EdgeDevices/EdgeDevicesView/EdgeDevicesDatatable/EdgeDevicesDatatableActions.tsx @@ -21,6 +21,11 @@ interface Props { showWaitingRoomLink: boolean; } +enum DeployType { + FDO = 'FDO', + MANUAL = 'MANUAL', +} + export function EdgeDevicesDatatableActions({ selectedItems, isOpenAMTEnabled, @@ -105,38 +110,37 @@ export function EdgeDevicesDatatableActions({ } async function onAddNewDeviceClick() { - if (!isFDOEnabled) { - router.stateService.go('portainer.endpoints.newEdgeDevice'); - return; - } - - const result = await promptAsync({ - title: 'How would you like to add an Edge Device?', - inputType: 'radio', - inputOptions: [ - { - text: 'Provision bare-metal using Intel FDO', - value: 'FDO', - }, - { - text: 'Deploy agent manually', - value: 'MANUAL', - }, - ], - buttons: { - confirm: { - label: 'Confirm', - className: 'btn-primary', - }, - }, - }); + const result = isFDOEnabled + ? await promptAsync({ + title: 'How would you like to add an Edge Device?', + inputType: 'radio', + inputOptions: [ + { + text: 'Provision bare-metal using Intel FDO', + value: DeployType.FDO, + }, + { + text: 'Deploy agent manually', + value: DeployType.MANUAL, + }, + ], + buttons: { + confirm: { + label: 'Confirm', + className: 'btn-primary', + }, + }, + }) + : DeployType.MANUAL; switch (result) { - case 'FDO': + case DeployType.FDO: router.stateService.go('portainer.endpoints.importDevice'); break; - case 'MANUAL': - router.stateService.go('portainer.endpoints.newEdgeDevice'); + case DeployType.MANUAL: + router.stateService.go('portainer.wizard.endpoints', { + edgeDevice: true, + }); break; default: break; diff --git a/app/portainer/__module.js b/app/portainer/__module.js index dccf8cf8a..3664b7241 100644 --- a/app/portainer/__module.js +++ b/app/portainer/__module.js @@ -188,20 +188,6 @@ angular }, }; - var edgeDeviceCreation = { - name: 'portainer.endpoints.newEdgeDevice', - url: '/newEdgeDevice', - params: { - isEdgeDevice: true, - }, - views: { - 'content@': { - templateUrl: './views/endpoints/create/createendpoint.html', - controller: 'CreateEndpointController', - }, - }, - }; - var deviceImport = { name: 'portainer.endpoints.importDevice', url: '/device', @@ -471,7 +457,6 @@ angular $stateRegistryProvider.register(endpoint); $stateRegistryProvider.register(endpointAccess); $stateRegistryProvider.register(endpointKVM); - $stateRegistryProvider.register(edgeDeviceCreation); $stateRegistryProvider.register(deviceImport); $stateRegistryProvider.register(addFDOProfile); $stateRegistryProvider.register(editFDOProfile); diff --git a/app/portainer/react/views/wizard.ts b/app/portainer/react/views/wizard.ts index ec195b291..81235da7f 100644 --- a/app/portainer/react/views/wizard.ts +++ b/app/portainer/react/views/wizard.ts @@ -29,6 +29,19 @@ function config($stateRegistryProvider: StateRegistry) { }, }); + $stateRegistryProvider.register({ + name: 'portainer.wizard.endpoints', + url: '/endpoints?edgeDevice', + views: { + 'content@': { + component: 'wizardEnvironmentTypeSelectView', + }, + }, + params: { + localEndpointId: 0, + }, + }); + $stateRegistryProvider.register({ name: 'portainer.wizard.endpoints.create', url: '/create?envType', @@ -41,17 +54,4 @@ function config($stateRegistryProvider: StateRegistry) { envType: '', }, }); - - $stateRegistryProvider.register({ - name: 'portainer.wizard.endpoints', - url: '/endpoints', - views: { - 'content@': { - component: 'wizardEnvironmentTypeSelectView', - }, - }, - params: { - localEndpointId: 0, - }, - }); } diff --git a/app/portainer/views/endpoints/create/createEndpointController.js b/app/portainer/views/endpoints/create/createEndpointController.js deleted file mode 100644 index 840a4ea12..000000000 --- a/app/portainer/views/endpoints/create/createEndpointController.js +++ /dev/null @@ -1,357 +0,0 @@ -import { PortainerEndpointCreationTypes, PortainerEndpointTypes } from 'Portainer/models/endpoint/models'; -import { getAgentShortVersion } from 'Portainer/views/endpoints/helpers'; -import { baseHref } from '@/portainer/helpers/pathHelper'; -import { EndpointSecurityFormData } from '../../../components/endpointSecurity/porEndpointSecurityModel'; - -angular - .module('portainer.app') - .controller( - 'CreateEndpointController', - function CreateEndpointController( - $async, - $analytics, - $q, - $scope, - $state, - $filter, - clipboard, - EndpointService, - GroupService, - SettingsService, - Notifications, - Authentication, - StateManager - ) { - $scope.onChangeCheckInInterval = onChangeCheckInInterval; - $scope.setFieldValue = setFieldValue; - - $scope.state = { - EnvironmentType: $state.params.isEdgeDevice ? 'edge_agent' : 'agent', - PlatformType: 'linux', - actionInProgress: false, - deploymentTab: 0, - allowCreateTag: Authentication.isAdmin(), - isEdgeDevice: $state.params.isEdgeDevice, - }; - - const agentVersion = StateManager.getState().application.version; - const agentShortVersion = getAgentShortVersion(agentVersion); - $scope.agentSecret = ''; - - $scope.deployCommands = { - kubeLoadBalancer: `curl -L https://downloads.portainer.io/ce${agentShortVersion}/portainer-agent-k8s-lb.yaml -o portainer-agent-k8s.yaml; kubectl apply -f portainer-agent-k8s.yaml`, - kubeNodePort: `curl -L https://downloads.portainer.io/ce${agentShortVersion}/portainer-agent-k8s-nodeport.yaml -o portainer-agent-k8s.yaml; kubectl apply -f portainer-agent-k8s.yaml`, - agentLinux: agentLinuxSwarmCommand, - agentWindows: agentWindowsSwarmCommand, - }; - - $scope.formValues = { - Name: '', - URL: '', - PublicURL: '', - GroupId: 1, - SecurityFormData: new EndpointSecurityFormData(), - AzureApplicationId: '', - AzureTenantId: '', - AzureAuthenticationKey: '', - TagIds: [], - CheckinInterval: 0, - }; - - $scope.copyAgentCommand = function () { - let command = ''; - if ($scope.state.deploymentTab === 2 && $scope.state.PlatformType === 'linux') { - command = $scope.deployCommands.agentLinux($scope.agentSecret); - } else if ($scope.state.deploymentTab === 2 && $scope.state.PlatformType === 'windows') { - command = $scope.deployCommands.agentWindows($scope.agentSecret); - } else if ($scope.state.deploymentTab === 1) { - command = $scope.deployCommands.kubeNodePort; - } else { - command = $scope.deployCommands.kubeLoadBalancer; - } - clipboard.copyText(command.trim()); - $('#copyNotification').show().fadeOut(2500); - }; - - $scope.setDefaultPortainerInstanceURL = function () { - let url; - - if (window.location.origin.startsWith('http')) { - const path = baseHref() !== '/' ? path : ''; - url = `${window.location.origin}${path}`; - } else { - url = baseHref().replace(/\/$/, ''); - } - - $scope.formValues.URL = url; - }; - - $scope.resetEndpointURL = function () { - $scope.formValues.URL = ''; - }; - - $scope.onChangeTags = function onChangeTags(value) { - return $scope.$evalAsync(() => { - $scope.formValues.TagIds = value; - }); - }; - - function onChangeCheckInInterval(value) { - setFieldValue('EdgeCheckinInterval', value); - } - - function setFieldValue(name, value) { - return $scope.$evalAsync(() => { - $scope.formValues = { - ...$scope.formValues, - [name]: value, - }; - }); - } - - $scope.addDockerEndpoint = function () { - var name = $scope.formValues.Name; - var URL = $filter('stripprotocol')($scope.formValues.URL); - var publicURL = $scope.formValues.PublicURL; - var groupId = $scope.formValues.GroupId; - var tagIds = $scope.formValues.TagIds; - - if ($scope.formValues.ConnectSocket) { - URL = $scope.formValues.SocketPath; - $scope.state.actionInProgress = true; - EndpointService.createLocalEndpoint(name, URL, publicURL, groupId, tagIds) - .then(function success() { - Notifications.success('Environment created', name); - $state.go('portainer.endpoints', {}, { reload: true }); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to create environment'); - }) - .finally(function final() { - $scope.state.actionInProgress = false; - }); - } else { - if (publicURL === '') { - publicURL = URL.split(':')[0]; - } - - var securityData = $scope.formValues.SecurityFormData; - var TLS = securityData.TLS; - var TLSMode = securityData.TLSMode; - var TLSSkipVerify = TLS && (TLSMode === 'tls_client_noca' || TLSMode === 'tls_only'); - var TLSSkipClientVerify = TLS && (TLSMode === 'tls_ca' || TLSMode === 'tls_only'); - var TLSCAFile = TLSSkipVerify ? null : securityData.TLSCACert; - var TLSCertFile = TLSSkipClientVerify ? null : securityData.TLSCert; - var TLSKeyFile = TLSSkipClientVerify ? null : securityData.TLSKey; - - addEndpoint( - name, - PortainerEndpointCreationTypes.LocalDockerEnvironment, - URL, - publicURL, - groupId, - tagIds, - TLS, - TLSSkipVerify, - TLSSkipClientVerify, - TLSCAFile, - TLSCertFile, - TLSKeyFile - ); - } - }; - - $scope.addKubernetesEndpoint = function () { - var name = $scope.formValues.Name; - var tagIds = $scope.formValues.TagIds; - $scope.state.actionInProgress = true; - EndpointService.createLocalKubernetesEndpoint(name, tagIds) - .then(function success(result) { - Notifications.success('Environment created', name); - $state.go('kubernetes.cluster.setup', { endpoinId: result.Id }); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to create environment'); - }) - .finally(function final() { - $scope.state.actionInProgress = false; - }); - }; - - $scope.addAgentEndpoint = addAgentEndpoint; - async function addAgentEndpoint() { - return $async(async () => { - const name = $scope.formValues.Name; - const URL = $scope.formValues.URL; - const publicURL = $scope.formValues.PublicURL === '' ? URL.split(':')[0] : $scope.formValues.PublicURL; - const groupId = $scope.formValues.GroupId; - const tagIds = $scope.formValues.TagIds; - - const endpoint = await addEndpoint(name, PortainerEndpointCreationTypes.AgentEnvironment, URL, publicURL, groupId, tagIds, true, true, true, null, null, null); - $analytics.eventTrack('portainer-endpoint-creation', { category: 'portainer', metadata: { type: 'agent', platform: platformLabel(endpoint.Type) } }); - }); - - function platformLabel(type) { - switch (type) { - case PortainerEndpointTypes.DockerEnvironment: - case PortainerEndpointTypes.AgentOnDockerEnvironment: - case PortainerEndpointTypes.EdgeAgentOnDockerEnvironment: - return 'docker'; - case PortainerEndpointTypes.KubernetesLocalEnvironment: - case PortainerEndpointTypes.AgentOnKubernetesEnvironment: - case PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment: - return 'kubernetes'; - } - } - } - - $scope.addEdgeAgentEndpoint = function () { - var name = $scope.formValues.Name; - var groupId = $scope.formValues.GroupId; - var tagIds = $scope.formValues.TagIds; - var URL = $scope.formValues.URL; - - addEndpoint(name, PortainerEndpointCreationTypes.EdgeAgentEnvironment, URL, '', groupId, tagIds, false, false, false, null, null, null, $scope.formValues.CheckinInterval); - }; - - $scope.addAzureEndpoint = function () { - var name = $scope.formValues.Name; - var applicationId = $scope.formValues.AzureApplicationId; - var tenantId = $scope.formValues.AzureTenantId; - var authenticationKey = $scope.formValues.AzureAuthenticationKey; - var groupId = $scope.formValues.GroupId; - var tagIds = $scope.formValues.TagIds; - - createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tagIds); - }; - - function createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tagIds) { - $scope.state.actionInProgress = true; - EndpointService.createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tagIds) - .then(function success() { - Notifications.success('Environment created', name); - $state.go('portainer.endpoints', {}, { reload: true }); - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to create environment'); - }) - .finally(function final() { - $scope.state.actionInProgress = false; - }); - } - - async function addEndpoint( - name, - creationType, - URL, - PublicURL, - groupId, - tagIds, - TLS, - TLSSkipVerify, - TLSSkipClientVerify, - TLSCAFile, - TLSCertFile, - TLSKeyFile, - CheckinInterval - ) { - return $async(async () => { - $scope.state.actionInProgress = true; - try { - const endpoint = await EndpointService.createRemoteEndpoint( - name, - creationType, - URL, - PublicURL, - groupId, - tagIds, - TLS, - TLSSkipVerify, - TLSSkipClientVerify, - TLSCAFile, - TLSCertFile, - TLSKeyFile, - CheckinInterval, - $scope.state.isEdgeDevice - ); - - Notifications.success('Environment created', name); - switch (endpoint.Type) { - case PortainerEndpointTypes.EdgeAgentOnDockerEnvironment: - case PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment: - $state.go('portainer.endpoints.endpoint', { id: endpoint.Id }); - break; - case PortainerEndpointTypes.AgentOnKubernetesEnvironment: - $state.go('kubernetes.cluster.setup', { endpoinId: endpoint.Id }); - break; - default: - $state.go('portainer.endpoints', {}, { reload: true }); - break; - } - - return endpoint; - } catch (err) { - Notifications.error('Failure', err, 'Unable to create environment'); - } finally { - $scope.state.actionInProgress = false; - } - }); - } - - function initView() { - $q.all({ - groups: GroupService.groups(), - settings: SettingsService.settings(), - }) - .then(function success(data) { - $scope.groups = data.groups; - - const settings = data.settings; - - $scope.agentSecret = settings.AgentSecret; - }) - .catch(function error(err) { - Notifications.error('Failure', err, 'Unable to load groups'); - }); - } - - function agentLinuxSwarmCommand(agentSecret) { - let secret = agentSecret == '' ? '' : `\\\n -e AGENT_SECRET=${agentSecret} `; - return ` -docker network create \\ - --driver overlay \\ - portainer_agent_network - -docker service create \\ - --name portainer_agent \\ - --network portainer_agent_network \\ - -p 9001:9001/tcp ${secret}\\ - --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 \\ - portainer/agent:${agentVersion} - `; - } - - function agentWindowsSwarmCommand(agentSecret) { - let secret = agentSecret == '' ? '' : `\\\n -e AGENT_SECRET=${agentSecret} `; - return ` -docker network create \\ - --driver overlay \\ - portainer_agent_network && \\ -docker service create \\ - --name portainer_agent \\ - --network portainer_agent_network \\ - -p 9001:9001/tcp ${secret}\\ - --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 \\ - portainer/agent:${agentVersion} - `; - } - - initView(); - } - ); diff --git a/app/portainer/views/endpoints/create/createendpoint.html b/app/portainer/views/endpoints/create/createendpoint.html deleted file mode 100644 index 008d9b368..000000000 --- a/app/portainer/views/endpoints/create/createendpoint.html +++ /dev/null @@ -1,521 +0,0 @@ - - -
-
- - -
-
Environment type
-
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
-
Important notice
-
-

- You can connect Portainer to a Docker environment via socket or via TCP. You can find more information about how to expose the Docker API over TCP - in the Docker documentation. -

- -

- When using the socket, ensure that you have started the Portainer container with the following Docker flag - -v "/var/run/docker.sock:/var/run/docker.sock" - (on Linux) or - -v \.\pipe\docker_engine:\.\pipe\docker_engine - (on Windows). -

-
-
-
-
Information
-
- - Ensure that you have deployed the Portainer agent in your cluster first. Refer to the platform related command below to deploy it. -
-
- - -
-
-
- - -

- - Note that the environment variable AGENT_SECRET will need to be set to {{ agentSecret }}. Please update the manifest that will be downloaded from the following script. -

- {{ deployCommands.kubeLoadBalancer }} -
- - -

- - Note that the environment variable AGENT_SECRET will need to be set to {{ agentSecret }}. Please update the manifest that will be downloaded from the following script. -

- {{ deployCommands.kubeNodePort }} -
- - - {{ - deployCommands.agentLinux(agentSecret) - }} - {{ - deployCommands.agentWindows(agentSecret) - }} - -
-
- Copy command - - - -
-
-
-
-
-
-
Information
-
- -

- Allows you to create an environment that can be registered with an Edge agent. The Edge agent will initiate the communications with the Portainer instance. All - the required information on how to connect an Edge agent to this environment will be available after environment creation. -

-

You can read more about the Edge agent in the userguide available here.

-
-
-
-
-
Important notice
-
-

This will allow you to manage the Kubernetes environment where Portainer is running.

- -

- - In order to manage a remote Kubernetes environment, please use the Agent or Edge agent options. -

-
-
-
-
Information
-
-
- -

This feature is experimental.

-

Connect to Microsoft Azure to manage Azure Container Instances (ACI).

-

- - Have a look at - the Azure documentation - to retrieve the credentials required below. -

-
-
-
-
-
Environment details
- -
- -
- -
-
-
-
-
-

This field is required.

-
-
-
- - -
-
- - -
-
- -
-
- - -
- -
-
- -
- -
-
-
-
-
-

This field is required.

-
-
-
-
-
- - -
-
- -
- - -
-
-
-
-
-

This field is required.

-
-
-
-
- - -
-
- -
- -
-
-
-
-
-

This field is required.

-
-
-
- - -
-
Check-in Intervals
- -
-
- -
-
- -
- -
-
-
- - -
- -
- -
- -
-
-
-
-
-

This field is required.

-
-
-
- - -
- -
- -
-
-
-
-
-

This field is required.

-
-
-
- - -
- -
- -
-
-
-
-
-

This field is required.

-
-
-
- -
- - - - -
Metadata
- -
- -
- -
-
- - - - -
Actions
- -
-
- - - - - -
-
- -
-
-
-
-
diff --git a/app/react/portainer/environments/wizard/EnvironmentTypeSelectView/EndpointTypeView.tsx b/app/react/portainer/environments/wizard/EnvironmentTypeSelectView/EndpointTypeView.tsx index bc1e30f3e..8ee8726ae 100644 --- a/app/react/portainer/environments/wizard/EnvironmentTypeSelectView/EndpointTypeView.tsx +++ b/app/react/portainer/environments/wizard/EnvironmentTypeSelectView/EndpointTypeView.tsx @@ -8,6 +8,8 @@ import { Button } from '@@/buttons'; import { PageHeader } from '@@/PageHeader'; import { Widget, WidgetBody, WidgetTitle } from '@@/Widget'; +import { useCreateEdgeDeviceParam } from '../hooks/useCreateEdgeDeviceParam'; + import { EnvironmentSelector, EnvironmentSelectorValue, @@ -15,6 +17,8 @@ import { import { environmentTypes } from './environment-types'; export function EnvironmentTypeSelectView() { + const createEdgeDevice = useCreateEdgeDeviceParam(); + const [types, setTypes] = useState([]); const { trackEvent } = useAnalytics(); const router = useRouter(); @@ -31,7 +35,11 @@ export function EnvironmentTypeSelectView() { - +