diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index a0e84aff2..d9cbb2786 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -278,6 +278,12 @@ func updateSettingsFromFlags(dataStore dataservices.DataStore, flags *portainer. settings.BlackListedLabels = *flags.Labels } + if agentKey, ok := os.LookupEnv("AGENT_SECRET"); ok { + settings.AgentSecret = agentKey + } else { + settings.AgentSecret = "" + } + err = dataStore.Settings().UpdateSettings(settings) if err != nil { return err diff --git a/api/portainer.go b/api/portainer.go index e2a64f814..a78ffc321 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -813,6 +813,8 @@ type ( DisableTrustOnFirstConnect bool `json:"DisableTrustOnFirstConnect" example:"false"` // EnforceEdgeID makes Portainer store the Edge ID instead of accepting anyone EnforceEdgeID bool `json:"EnforceEdgeID" example:"false"` + // Container environment parameter AGENT_SECRET + AgentSecret string `json:"AgentSecret"` // Deprecated fields DisplayDonationHeader bool diff --git a/app/portainer/models/settings.js b/app/portainer/models/settings.js index f6c69ba4b..baf579ec1 100644 --- a/app/portainer/models/settings.js +++ b/app/portainer/models/settings.js @@ -17,6 +17,7 @@ export function SettingsViewModel(data) { this.HelmRepositoryURL = data.HelmRepositoryURL; this.DisableTrustOnFirstConnect = data.DisableTrustOnFirstConnect; this.EnforceEdgeID = data.EnforceEdgeID; + this.AgentSecret = data.AgentSecret; } export function PublicSettingsViewModel(settings) { diff --git a/app/portainer/views/endpoints/create/createEndpointController.js b/app/portainer/views/endpoints/create/createEndpointController.js index 1189b19e1..7da101aad 100644 --- a/app/portainer/views/endpoints/create/createEndpointController.js +++ b/app/portainer/views/endpoints/create/createEndpointController.js @@ -52,14 +52,14 @@ angular const agentVersion = StateManager.getState().application.version; const agentShortVersion = getAgentShortVersion(agentVersion); + $scope.agentSecret = ''; - const deployCommands = { + $scope.deployCommands = { kubeLoadBalancer: `curl -L https://downloads.portainer.io/portainer-agent-ce${agentShortVersion}-k8s-lb.yaml -o portainer-agent-k8s.yaml; kubectl apply -f portainer-agent-k8s.yaml`, kubeNodePort: `curl -L https://downloads.portainer.io/portainer-agent-ce${agentShortVersion}-k8s-nodeport.yaml -o portainer-agent-k8s.yaml; kubectl apply -f portainer-agent-k8s.yaml`, - agentLinux: `curl -L https://downloads.portainer.io/agent-stack-ce${agentShortVersion}.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent`, - agentWindows: `curl -L https://downloads.portainer.io/agent-stack-ce${agentShortVersion}-windows.yml -o agent-stack-windows.yml && docker stack deploy --compose-file=agent-stack-windows.yml portainer-agent`, + agentLinux: agentLinuxSwarmCommand, + agentWindows: agentWindowsSwarmCommand, }; - $scope.deployCommands = deployCommands; $scope.formValues = { Name: '', @@ -75,15 +75,17 @@ angular }; $scope.copyAgentCommand = function () { + let command = ''; if ($scope.state.deploymentTab === 2 && $scope.state.PlatformType === 'linux') { - clipboard.copyText(deployCommands.agentLinux); + command = $scope.deployCommands.agentLinux($scope.agentSecret); } else if ($scope.state.deploymentTab === 2 && $scope.state.PlatformType === 'windows') { - clipboard.copyText(deployCommands.agentWindows); + command = $scope.deployCommands.agentWindows($scope.agentSecret); } else if ($scope.state.deploymentTab === 1) { - clipboard.copyText(deployCommands.kubeNodePort); + command = $scope.deployCommands.kubeNodePort; } else { - clipboard.copyText(deployCommands.kubeLoadBalancer); + command = $scope.deployCommands.kubeLoadBalancer; } + clipboard.copyText(command.trim()); $('#copyNotification').show().fadeOut(2500); }; @@ -311,12 +313,50 @@ angular const settings = data.settings; $scope.state.availableEdgeAgentCheckinOptions[0].key += ` (${settings.EdgeAgentCheckinInterval} seconds)`; + $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 index 146da5647..5bf120a05 100644 --- a/app/portainer/views/endpoints/create/createendpoint.html +++ b/app/portainer/views/endpoints/create/createendpoint.html @@ -95,16 +95,30 @@
- {{ 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.kubeLoadBalancer }}
- {{ deployCommands.kubeNodePort }} +

+ + 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 }} - {{ deployCommands.agentWindows }} + {{ + deployCommands.agentLinux(agentSecret) + }} + {{ + deployCommands.agentWindows(agentSecret) + }}
diff --git a/app/portainer/views/endpoints/edit/endpointController.js b/app/portainer/views/endpoints/edit/endpointController.js index a60b31828..133c8a9b7 100644 --- a/app/portainer/views/endpoints/edit/endpointController.js +++ b/app/portainer/views/endpoints/edit/endpointController.js @@ -12,7 +12,6 @@ angular.module('portainer.app').controller('EndpointController', EndpointControl /* @ngInject */ function EndpointController( $async, - $q, $scope, $state, $transition$, @@ -73,6 +72,7 @@ function EndpointController( $scope.agentVersion = StateManager.getState().application.version; $scope.agentShortVersion = getAgentShortVersion($scope.agentVersion); + $scope.agentSecret = ''; $scope.dockerCommands = { [DEPLOYMENT_TABS.STANDALONE]: { @@ -291,6 +291,7 @@ function EndpointController( $scope.endpoint = endpoint; $scope.groups = groups; $scope.availableTags = tags; + $scope.agentSecret = settings.AgentSecret; configureState(); @@ -326,17 +327,20 @@ function EndpointController( } function buildEnvironmentSubCommand() { - if ($scope.formValues.EnvVarSource === '') { - return []; + let env = []; + if ($scope.formValues.EnvVarSource != '') { + env = $scope.formValues.EnvVarSource.split(',') + .map(function (s) { + if (s !== '') { + return `-e ${s} \\`; + } + }) + .filter((s) => s !== undefined); } - - return $scope.formValues.EnvVarSource.split(',') - .map(function (s) { - if (s !== '') { - return `-e ${s} \\`; - } - }) - .filter((s) => s !== undefined); + if ($scope.agentSecret != '') { + env.push(`-e AGENT_SECRET=${$scope.agentSecret} \\`); + } + return env; } function buildLinuxStandaloneCommand(agentVersion, edgeId, edgeKey, allowSelfSignedCerts) { @@ -438,7 +442,9 @@ function EndpointController( } function buildKubernetesCommand(agentVersion, edgeId, edgeKey, allowSelfSignedCerts) { - return `curl https://downloads.portainer.io/portainer-ce${agentVersion}-edge-agent-setup.sh | bash -s -- ${edgeId} ${edgeKey} ${allowSelfSignedCerts ? '1' : '0'}`; + return `curl https://downloads.portainer.io/portainer-ce${agentVersion}-edge-agent-setup.sh | bash -s -- ${edgeId} ${edgeKey} ${allowSelfSignedCerts ? '1' : '0'} ${ + $scope.agentSecret + }`; } initView();