fix(endpoints): show edge script when unassociated [EE-2842] (#6730)

pull/6750/head
Chaim Lev-Ari 2022-04-11 11:26:13 +03:00 committed by GitHub
parent 287107e8da
commit 13faa75a2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 121 additions and 120 deletions

View File

@ -16,7 +16,7 @@ angular.module('portainer.app').factory('Endpoints', [
}, },
get: { method: 'GET', params: { id: '@id' } }, get: { method: 'GET', params: { id: '@id' } },
update: { method: 'PUT', params: { id: '@id' } }, update: { method: 'PUT', params: { id: '@id' } },
deassociate: { method: 'DELETE', params: { id: '@id', action: 'association' } }, disassociate: { method: 'DELETE', params: { id: '@id', action: 'association' } },
updateAccess: { method: 'PUT', params: { id: '@id', action: 'access' } }, updateAccess: { method: 'PUT', params: { id: '@id', action: 'access' } },
remove: { method: 'DELETE', params: { id: '@id' } }, remove: { method: 'DELETE', params: { id: '@id' } },
snapshots: { method: 'POST', params: { action: 'snapshot' } }, snapshots: { method: 'POST', params: { action: 'snapshot' } },

View File

@ -40,8 +40,8 @@ angular.module('portainer.app').factory('EndpointService', [
return Endpoints.updateAccess({ id: id }, { UserAccessPolicies: userAccessPolicies, TeamAccessPolicies: teamAccessPolicies }).$promise; return Endpoints.updateAccess({ id: id }, { UserAccessPolicies: userAccessPolicies, TeamAccessPolicies: teamAccessPolicies }).$promise;
}; };
service.deassociateEndpoint = function (endpointID) { service.disassociateEndpoint = function (endpointID) {
return Endpoints.deassociate({ id: endpointID }).$promise; return Endpoints.disassociate({ id: endpointID }).$promise;
}; };
service.updateEndpoint = function (id, payload) { service.updateEndpoint = function (id, payload) {

View File

@ -115,17 +115,17 @@ export function confirmDetachment(message: string, callback: ConfirmCallback) {
}); });
} }
export function confirmDeassociate(callback: ConfirmCallback) { export function confirmDisassociate(callback: ConfirmCallback) {
const message = const message =
'<p>De-associating this Edge environment will mark it as non associated and will clear the registered Edge ID.</p>' + '<p>Disassociating this Edge environment will mark it as non associated and will clear the registered Edge ID.</p>' +
'<p>Any agent started with the Edge key associated to this environment will be able to re-associate with this environment.</p>' + '<p>Any agent started with the Edge key associated to this environment will be able to re-associate with this environment.</p>' +
'<p>You can re-use the Edge ID and Edge key that you used to deploy the existing Edge agent to associate a new Edge device to this environment.</p>'; '<p>You can re-use the Edge ID and Edge key that you used to deploy the existing Edge agent to associate a new Edge device to this environment.</p>';
confirm({ confirm({
title: 'About de-associating', title: 'About disassociating',
message: sanitize(message), message: sanitize(message),
buttons: { buttons: {
confirm: { confirm: {
label: 'De-associate', label: 'Disassociate',
className: 'btn-primary', className: 'btn-primary',
}, },
}, },

View File

@ -4,7 +4,7 @@ import bootbox from 'bootbox';
import { import {
cancelRegistryRepositoryAction, cancelRegistryRepositoryAction,
confirmAsync, confirmAsync,
confirmDeassociate, confirmDisassociate,
confirmDeletion, confirmDeletion,
confirmDetachment, confirmDetachment,
confirmDeletionAsync, confirmDeletionAsync,
@ -46,7 +46,7 @@ export function ModalServiceAngular() {
cancelRegistryRepositoryAction, cancelRegistryRepositoryAction,
confirmDeletion, confirmDeletion,
confirmDetachment, confirmDetachment,
confirmDeassociate, confirmDisassociate,
confirmUpdate, confirmUpdate,
confirmRedeploy, confirmRedeploy,
confirmDeletionAsync, confirmDeletionAsync,

View File

@ -10,113 +10,112 @@
</rd-header> </rd-header>
<div class="row"> <div class="row">
<information-panel ng-if="state.edgeEndpoint && endpoint.EdgeID && endpoint.LastCheckInDate" title-text="Edge information"> <div ng-if="state.edgeEndpoint">
<span class="small text-muted"> <information-panel ng-if="state.edgeAssociated" title-text="Edge information">
<p> <span class="small text-muted">
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i> <p>
This Edge environment is associated to an Edge environment {{ state.kubernetesEndpoint ? '(Kubernetes)' : '(Docker)' }}. <i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
</p> This Edge environment is associated to an Edge environment {{ state.kubernetesEndpoint ? '(Kubernetes)' : '(Docker)' }}.
<p> </p>
Edge key: <code>{{ endpoint.EdgeKey }}</code> <p>
</p> Edge key: <code>{{ endpoint.EdgeKey }}</code>
<p> </p>
Edge identifier: <code>{{ endpoint.EdgeID }}</code> <p>
</p> Edge identifier: <code>{{ endpoint.EdgeID }}</code>
<p> </p>
<button <p>
type="button" <button
class="btn btn-primary btn-sm" type="button"
ng-disabled="state.actionInProgress" class="btn btn-primary btn-sm"
ng-click="onDeassociateEndpoint()" ng-disabled="state.actionInProgress"
button-spinner="state.actionInProgress" ng-click="onDisassociateEndpoint()"
analytics-on button-spinner="state.actionInProgress"
analytics-event="edge-endpoint-deassociate" analytics-on
analytics-category="edge" analytics-event="edge-endpoint-disassociate"
> analytics-category="edge"
<span ng-hide="state.actionInProgress">De-associate</span> >
</button> <span ng-hide="state.actionInProgress">Disassociate</span>
</p> </button>
</span> </p>
</information-panel> </span>
<information-panel ng-if="state.edgeEndpoint && !endpoint.LastCheckInDate" title-text="Deploy an agent"> </information-panel>
<span class="small text-muted"> <information-panel ng-if="!state.edgeAssociated" title-text="Deploy an agent">
<p> <span class="small text-muted">
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i> <p>
Refer to the platform related command below to deploy the Edge agent in your remote cluster. <i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
</p> Refer to the platform related command below to deploy the Edge agent in your remote cluster.
<p> </p>
The agent will communicate with Portainer via <u>{{ edgeKeyDetails.instanceURL }}</u> and <u>tcp://{{ edgeKeyDetails.tunnelServerAddr }}</u> <p>
</p> The agent will communicate with Portainer via <u>{{ edgeKeyDetails.instanceURL }}</u> and <u>tcp://{{ edgeKeyDetails.tunnelServerAddr }}</u>
<div class="input-group input-group-sm" style="margin-top: 10px; margin-bottom: 10px"> </p>
<div class="btn-group btn-group-sm"> <div class="input-group input-group-sm" style="margin-top: 10px; margin-bottom: 10px">
<label class="btn btn-primary" ng-model="state.platformType" uib-btn-radio="'linux'"><i class="fab fa-linux" style="margin-right: 2px"></i> Linux</label> <div class="btn-group btn-group-sm">
<label class="btn btn-primary" ng-model="state.platformType" uib-btn-radio="'windows'"><i class="fab fa-windows" style="margin-right: 2px"></i> Windows</label> <label class="btn btn-primary" ng-model="state.platformType" uib-btn-radio="'linux'"><i class="fab fa-linux" style="margin-right: 2px"></i> Linux</label>
<label class="btn btn-primary" ng-model="state.platformType" uib-btn-radio="'windows'"><i class="fab fa-windows" style="margin-right: 2px"></i> Windows</label>
</div>
</div> </div>
</div> <div class="form-group">
<por-switch-field
<div class="form-group"> label="'Allow self-signed certs'"
<por-switch-field checked="state.allowSelfSignedCerts"
label="'Allow self-signed certs'" tooltip="'When allowing self-signed certificates the edge agent will ignore the domain validation when connecting to Portainer via HTTPS'"
checked="state.allowSelfSignedCerts" on-change="(onToggleAllowSelfSignedCerts)"
tooltip="'When allowing self-signed certificates the edge agent will ignore the domain validation when connecting to Portainer via HTTPS'" ></por-switch-field>
on-change="(onToggleAllowSelfSignedCerts)" </div>
></por-switch-field> <div class="form-group clearfix" ng-if="!isKubernetesDeploymentTabSelected()">
</div> <label for="env_vars" class="col-sm-3 col-lg-2 control-label text-left" style="padding-left: 0; padding-top: 5px">
Environment variables
<div class="form-group clearfix" ng-if="!isKubernetesDeploymentTabSelected()"> <portainer-tooltip
<label for="env_vars" class="col-sm-3 col-lg-2 control-label text-left" style="padding-left: 0; padding-top: 5px"> position="bottom"
Environment variables message="Comma separated list of environment variables that will be sourced from the host where the agent is deployed."
<portainer-tooltip ></portainer-tooltip>
position="bottom" </label>
message="Comma separated list of environment variables that will be sourced from the host where the agent is deployed." <div class="col-sm-9 col-lg-10">
></portainer-tooltip> <input type="text" class="form-control" id="env_vars" ng-model="formValues.EnvVarSource" placeholder="foo=bar,myvar" />
</label> </div>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="env_vars" ng-model="formValues.EnvVarSource" placeholder="foo=bar,myvar" />
</div> </div>
</div>
<div style="margin-top: 10px">
<uib-tabset active="state.deploymentTab">
<uib-tab index="'kubernetes'" heading="Kubernetes" ng-if="state.platformType === 'linux'">
<code style="display: block; white-space: pre-wrap; padding: 16px 45px">{{
dockerCommands[state.deploymentTab][state.platformType](agentShortVersion, endpoint.EdgeID, endpoint.EdgeKey, state.allowSelfSignedCerts)
}}</code>
</uib-tab>
<uib-tab index="'swarm'" heading="Docker Swarm">
<code style="display: block; white-space: pre-wrap; padding: 16px 45px">{{
dockerCommands[state.deploymentTab][state.platformType](agentVersion, endpoint.EdgeID, endpoint.EdgeKey, state.allowSelfSignedCerts)
}}</code>
</uib-tab>
<uib-tab index="'standalone'" heading="Docker Standalone">
<code style="display: block; white-space: pre-wrap; padding: 16px 45px">{{
dockerCommands[state.deploymentTab][state.platformType](agentVersion, endpoint.EdgeID, endpoint.EdgeKey, state.allowSelfSignedCerts)
}}</code>
</uib-tab>
</uib-tabset>
<div style="margin-top: 10px"> <div style="margin-top: 10px">
<span class="btn btn-primary btn-sm" ng-click="copyEdgeAgentDeploymentCommand()"><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy command</span> <uib-tabset active="state.deploymentTab">
<span id="copyNotificationDeploymentCommand" style="margin-left: 7px; display: none; color: #23ae89"> <i class="fa fa-check" aria-hidden="true"></i> copied </span> <uib-tab index="'kubernetes'" heading="Kubernetes" ng-if="state.platformType === 'linux'">
<code style="display: block; white-space: pre-wrap; padding: 16px 45px">{{
dockerCommands[state.deploymentTab][state.platformType](agentShortVersion, endpoint.EdgeID, endpoint.EdgeKey, state.allowSelfSignedCerts)
}}</code>
</uib-tab>
<uib-tab index="'swarm'" heading="Docker Swarm">
<code style="display: block; white-space: pre-wrap; padding: 16px 45px">{{
dockerCommands[state.deploymentTab][state.platformType](agentVersion, endpoint.EdgeID, endpoint.EdgeKey, state.allowSelfSignedCerts)
}}</code>
</uib-tab>
<uib-tab index="'standalone'" heading="Docker Standalone">
<code style="display: block; white-space: pre-wrap; padding: 16px 45px">{{
dockerCommands[state.deploymentTab][state.platformType](agentVersion, endpoint.EdgeID, endpoint.EdgeKey, state.allowSelfSignedCerts)
}}</code>
</uib-tab>
</uib-tabset>
<div style="margin-top: 10px">
<span class="btn btn-primary btn-sm" ng-click="copyEdgeAgentDeploymentCommand()"><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy command</span>
<span id="copyNotificationDeploymentCommand" style="margin-left: 7px; display: none; color: #23ae89"> <i class="fa fa-check" aria-hidden="true"></i> copied </span>
</div>
</div> </div>
</div> <div class="col-sm-12 form-section-title" style="margin-top: 25px"> Join token </div>
<div class="col-sm-12 form-section-title" style="margin-top: 25px"> Join token </div> <p>
<p> <i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i> For those prestaging the edge agent, use the following join token to associate the Edge agent with this environment.
For those prestaging the edge agent, use the following join token to associate the Edge agent with this environment. </p>
</p> <p> You can read more about pre-staging in the userguide available <a href="https://downloads.portainer.io/edge_agent_guide.pdf">here.</a> </p>
<p> You can read more about pre-staging in the userguide available <a href="https://downloads.portainer.io/edge_agent_guide.pdf">here.</a> </p> <div style="margin-top: 10px; overflow-wrap: break-word">
<div style="margin-top: 10px; overflow-wrap: break-word"> <code>
<code> {{ endpoint.EdgeKey }}
{{ endpoint.EdgeKey }} </code>
</code> <div style="margin-top: 10px">
<div style="margin-top: 10px"> <span class="btn btn-primary btn-sm" ng-click="copyEdgeAgentKey()"><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy token</span>
<span class="btn btn-primary btn-sm" ng-click="copyEdgeAgentKey()"><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy token</span> <span id="copyNotificationEdgeKey" style="margin-left: 7px; display: none; color: #23ae89"> <i class="fa fa-check" aria-hidden="true"></i> copied </span>
<span id="copyNotificationEdgeKey" style="margin-left: 7px; display: none; color: #23ae89"> <i class="fa fa-check" aria-hidden="true"></i> copied </span> </div>
</div> </div>
</div> </span>
</span> </information-panel>
</information-panel> </div>
<information-panel ng-if="state.kubernetesEndpoint && (!state.edgeEndpoint || (state.edgeEndpoint && endpoint.EdgeID))" title-text="Kubernetes features configuration"> <information-panel ng-if="state.kubernetesEndpoint && (!state.edgeEndpoint || state.edgeAssociated)" title-text="Kubernetes features configuration">
<span class="small text-muted"> <span class="small text-muted">
<i class="fa fa-tools blue-icon" aria-hidden="true" style="margin-right: 2px"></i> <i class="fa fa-tools blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
You should configure the features available in this Kubernetes environment in the You should configure the features available in this Kubernetes environment in the

View File

@ -47,6 +47,7 @@ function EndpointController(
kubernetesEndpoint: false, kubernetesEndpoint: false,
agentEndpoint: false, agentEndpoint: false,
edgeEndpoint: false, edgeEndpoint: false,
edgeAssociated: false,
allowCreate: Authentication.isAdmin(), allowCreate: Authentication.isAdmin(),
availableEdgeAgentCheckinOptions: [ availableEdgeAgentCheckinOptions: [
{ key: 'Use default interval', value: 0 }, { key: 'Use default interval', value: 0 },
@ -139,24 +140,24 @@ function EndpointController(
} }
} }
$scope.onDeassociateEndpoint = async function () { $scope.onDisassociateEndpoint = async function () {
ModalService.confirmDeassociate((confirmed) => { ModalService.confirmDisassociate((confirmed) => {
if (confirmed) { if (confirmed) {
deassociateEndpoint(); disassociateEndpoint();
} }
}); });
}; };
async function deassociateEndpoint() { async function disassociateEndpoint() {
var endpoint = $scope.endpoint; var endpoint = $scope.endpoint;
try { try {
$scope.state.actionInProgress = true; $scope.state.actionInProgress = true;
await EndpointService.deassociateEndpoint(endpoint.Id); await EndpointService.disassociateEndpoint(endpoint.Id);
Notifications.success('Environment de-associated', $scope.endpoint.Name); Notifications.success('Environment disassociated', $scope.endpoint.Name);
$state.reload(); $state.reload();
} catch (err) { } catch (err) {
Notifications.error('Failure', err, 'Unable to de-associate environment'); Notifications.error('Failure', err, 'Unable to disassociate environment');
} finally { } finally {
$scope.state.actionInProgress = false; $scope.state.actionInProgress = false;
} }
@ -280,6 +281,8 @@ function EndpointController(
if (endpoint.Type === PortainerEndpointTypes.EdgeAgentOnDockerEnvironment || endpoint.Type === PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment) { if (endpoint.Type === PortainerEndpointTypes.EdgeAgentOnDockerEnvironment || endpoint.Type === PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment) {
$scope.edgeKeyDetails = decodeEdgeKey(endpoint.EdgeKey); $scope.edgeKeyDetails = decodeEdgeKey(endpoint.EdgeKey);
$scope.state.edgeAssociated = !!endpoint.EdgeID;
endpoint.EdgeID = endpoint.EdgeID || uuidv4(); endpoint.EdgeID = endpoint.EdgeID || uuidv4();
$scope.state.availableEdgeAgentCheckinOptions[0].key += ` (${settings.EdgeAgentCheckinInterval} seconds)`; $scope.state.availableEdgeAgentCheckinOptions[0].key += ` (${settings.EdgeAgentCheckinInterval} seconds)`;
@ -291,8 +294,7 @@ function EndpointController(
configureState(); configureState();
const disconnectedEdge = $scope.state.edgeEndpoint && !endpoint.EdgeID; if (EndpointHelper.isDockerEndpoint(endpoint) && $scope.state.edgeAssociated) {
if (EndpointHelper.isDockerEndpoint(endpoint) && !disconnectedEdge) {
$scope.state.showAMTInfo = settings && settings.openAMTConfiguration && settings.openAMTConfiguration.enabled; $scope.state.showAMTInfo = settings && settings.openAMTConfiguration && settings.openAMTConfiguration.enabled;
} }
} catch (err) { } catch (err) {