feat(agent): add auto agent platform detection (#4132)

* feat(endpoint): check endpoint type on creation

* feat(edge): check edge endpoint type

* feat(endpoint): send endpoint creation type

* feat(endpoint): pass tls config

* feat(endpoint): show connect errors

* fix(endpoint): set correct endpoint type

* feat(endpoint): support endpoint creation

* style(endpoint): remove todo comment

* feat(endpoint): set protocol for endpoint url

* feat(endpoint): change scheme of url

* fix(endpoint): toggle code block

* feat(edge): report missing agent platform header

* fix(api/endpoints): fix an issue with agent on kubernetes endpoint

* feat(core/endpoints): minor UI update

Co-authored-by: Anthony Lapenna <lapenna.anthony@gmail.com>
pull/4147/head
Chaim Lev-Ari 2020-08-04 03:44:17 +03:00 committed by GitHub
parent 490b7ad26f
commit bd7d7dcef5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 226 additions and 76 deletions

View File

@ -2,17 +2,20 @@ package endpoints
import (
"errors"
"fmt"
"net"
"net/http"
"net/url"
"runtime"
"strconv"
"strings"
"time"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/crypto"
"github.com/portainer/portainer/api/http/client"
"github.com/portainer/portainer/api/internal/edge"
)
@ -20,7 +23,7 @@ import (
type endpointCreatePayload struct {
Name string
URL string
EndpointType int
EndpointCreationType endpointCreationEnum
PublicURL string
GroupID int
TLS bool
@ -36,6 +39,17 @@ type endpointCreatePayload struct {
EdgeCheckinInterval int
}
type endpointCreationEnum int
const (
_ endpointCreationEnum = iota
localDockerEnvironment
agentEnvironment
azureEnvironment
edgeAgentEnvironment
localKubernetesEnvironment
)
func (payload *endpointCreatePayload) Validate(r *http.Request) error {
name, err := request.RetrieveMultiPartFormValue(r, "Name", false)
if err != nil {
@ -43,11 +57,11 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
}
payload.Name = name
endpointType, err := request.RetrieveNumericMultiPartFormValue(r, "EndpointType", false)
if err != nil || endpointType == 0 {
return errors.New("Invalid endpoint type value. Value must be one of: 1 (Docker environment), 2 (Agent environment), 3 (Azure environment) or 4 (Edge Agent environment)")
endpointCreationType, err := request.RetrieveNumericMultiPartFormValue(r, "EndpointCreationType", false)
if err != nil || endpointCreationType == 0 {
return errors.New("Invalid endpoint type value. Value must be one of: 1 (Docker environment), 2 (Agent environment), 3 (Azure environment), 4 (Edge Agent environment) or 5 (Local Kubernetes environment)")
}
payload.EndpointType = endpointType
payload.EndpointCreationType = endpointCreationEnum(endpointCreationType)
groupID, _ := request.RetrieveNumericMultiPartFormValue(r, "GroupID", true)
if groupID == 0 {
@ -97,8 +111,8 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
}
}
switch portainer.EndpointType(payload.EndpointType) {
case portainer.AzureEnvironment:
switch payload.EndpointCreationType {
case azureEnvironment:
azureApplicationID, err := request.RetrieveMultiPartFormValue(r, "AzureApplicationID", false)
if err != nil {
return errors.New("Invalid Azure application ID")
@ -182,22 +196,34 @@ func (handler *Handler) endpointCreate(w http.ResponseWriter, r *http.Request) *
}
func (handler *Handler) createEndpoint(payload *endpointCreatePayload) (*portainer.Endpoint, *httperror.HandlerError) {
switch portainer.EndpointType(payload.EndpointType) {
case portainer.AzureEnvironment:
switch payload.EndpointCreationType {
case azureEnvironment:
return handler.createAzureEndpoint(payload)
case portainer.EdgeAgentOnDockerEnvironment:
return handler.createEdgeAgentEndpoint(payload, portainer.EdgeAgentOnDockerEnvironment)
case edgeAgentEnvironment:
return handler.createEdgeAgentEndpoint(payload)
case portainer.KubernetesLocalEnvironment:
case localKubernetesEnvironment:
return handler.createKubernetesEndpoint(payload)
}
case portainer.EdgeAgentOnKubernetesEnvironment:
return handler.createEdgeAgentEndpoint(payload, portainer.EdgeAgentOnKubernetesEnvironment)
endpointType := portainer.DockerEnvironment
if payload.EndpointCreationType == agentEnvironment {
agentPlatform, err := handler.pingAndCheckPlatform(payload)
if err != nil {
return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to get endpoint type", err}
}
if agentPlatform == portainer.AgentPlatformDocker {
endpointType = portainer.AgentOnDockerEnvironment
} else if agentPlatform == portainer.AgentPlatformKubernetes {
endpointType = portainer.AgentOnKubernetesEnvironment
payload.URL = strings.TrimPrefix(payload.URL, "tcp://")
}
}
if payload.TLS {
return handler.createTLSSecuredEndpoint(payload, portainer.EndpointType(payload.EndpointType))
return handler.createTLSSecuredEndpoint(payload, endpointType)
}
return handler.createUnsecuredEndpoint(payload)
}
@ -241,7 +267,7 @@ func (handler *Handler) createAzureEndpoint(payload *endpointCreatePayload) (*po
return endpoint, nil
}
func (handler *Handler) createEdgeAgentEndpoint(payload *endpointCreatePayload, endpointType portainer.EndpointType) (*portainer.Endpoint, *httperror.HandlerError) {
func (handler *Handler) createEdgeAgentEndpoint(payload *endpointCreatePayload) (*portainer.Endpoint, *httperror.HandlerError) {
endpointID := handler.DataStore.Endpoint().GetNextIdentifier()
portainerURL, err := url.Parse(payload.URL)
@ -264,7 +290,7 @@ func (handler *Handler) createEdgeAgentEndpoint(payload *endpointCreatePayload,
ID: portainer.EndpointID(endpointID),
Name: payload.Name,
URL: portainerHost,
Type: endpointType,
Type: portainer.EdgeAgentOnDockerEnvironment,
GroupID: portainer.EndpointGroupID(payload.GroupID),
TLSConfig: portainer.TLSConfiguration{
TLS: false,
@ -472,3 +498,58 @@ func (handler *Handler) storeTLSFiles(endpoint *portainer.Endpoint, payload *end
return nil
}
func (handler *Handler) pingAndCheckPlatform(payload *endpointCreatePayload) (portainer.AgentPlatform, error) {
httpCli := &http.Client{
Timeout: 3 * time.Second,
}
if payload.TLS {
tlsConfig, err := crypto.CreateTLSConfigurationFromBytes(payload.TLSCACertFile, payload.TLSCertFile, payload.TLSKeyFile, payload.TLSSkipVerify, payload.TLSSkipClientVerify)
if err != nil {
return 0, err
}
httpCli.Transport = &http.Transport{
TLSClientConfig: tlsConfig,
}
}
url, err := url.Parse(fmt.Sprintf("%s/ping", payload.URL))
if err != nil {
return 0, err
}
url.Scheme = "https"
req, err := http.NewRequest(http.MethodGet, url.String(), nil)
if err != nil {
return 0, err
}
resp, err := httpCli.Do(req)
if err != nil {
return 0, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
return 0, fmt.Errorf("Failed request with status %d", resp.StatusCode)
}
agentPlatformHeader := resp.Header.Get(portainer.HTTPResponseAgentPlatform)
if agentPlatformHeader == "" {
return 0, errors.New("Agent Platform Header is missing")
}
agentPlatformNumber, err := strconv.Atoi(agentPlatformHeader)
if err != nil {
return 0, err
}
if agentPlatformNumber == 0 {
return 0, errors.New("Agent platform is invalid")
}
return portainer.AgentPlatform(agentPlatformNumber), nil
}

View File

@ -2,13 +2,15 @@ package endpoints
import (
"encoding/base64"
"errors"
"net/http"
"strconv"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type stackStatusResponse struct {
@ -41,7 +43,7 @@ func (handler *Handler) endpointStatusInspect(w http.ResponseWriter, r *http.Req
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == errors.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -54,10 +56,27 @@ func (handler *Handler) endpointStatusInspect(w http.ResponseWriter, r *http.Req
if endpoint.EdgeID == "" {
edgeIdentifier := r.Header.Get(portainer.PortainerAgentEdgeIDHeader)
endpoint.EdgeID = edgeIdentifier
err := handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint)
agentPlatformHeader := r.Header.Get(portainer.HTTPResponseAgentPlatform)
if agentPlatformHeader == "" {
return &httperror.HandlerError{http.StatusInternalServerError, "Agent Platform Header is missing", errors.New("Agent Platform Header is missing")}
}
agentPlatformNumber, err := strconv.Atoi(agentPlatformHeader)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to parse agent platform header", err}
}
agentPlatform := portainer.AgentPlatform(agentPlatformNumber)
if agentPlatform == portainer.AgentPlatformDocker {
endpoint.Type = portainer.EdgeAgentOnDockerEnvironment
} else if agentPlatform == portainer.AgentPlatformKubernetes {
endpoint.Type = portainer.EdgeAgentOnKubernetesEnvironment
}
err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to Unable to persist endpoint changes inside the database", err}
}

View File

@ -11,6 +11,9 @@ type (
RoleID RoleID `json:"RoleId"`
}
// AgentPlatform represents a platform type for an Agent
AgentPlatform int
// APIOperationAuthorizationRequest represent an request for the authorization to execute an API operation
APIOperationAuthorizationRequest struct {
Path string
@ -1141,6 +1144,8 @@ const (
PortainerAgentHeader = "Portainer-Agent"
// PortainerAgentEdgeIDHeader represent the name of the header containing the Edge ID associated to an agent/agent cluster
PortainerAgentEdgeIDHeader = "X-PortainerAgent-EdgeID"
// HTTPResponseAgentPlatform represents the name of the header containing the Agent platform
HTTPResponseAgentPlatform = "Portainer-Agent-Platform"
// PortainerAgentTargetHeader represent the name of the header containing the target node name
PortainerAgentTargetHeader = "X-PortainerAgent-Target"
// PortainerAgentSignatureHeader represent the name of the header containing the digital signature
@ -1174,6 +1179,14 @@ const (
AuthenticationOAuth
)
const (
_ AgentPlatform = iota
// AgentPlatformDocker represent the Docker platform (Standalone/Swarm)
AgentPlatformDocker
// AgentPlatformKubernetes represent the Kubernetes platform
AgentPlatformKubernetes
)
const (
_ EdgeJobLogsStatus = iota
// EdgeJobLogsStatusIdle represents an idle log collection job

View File

@ -18,6 +18,17 @@ export const PortainerEndpointTypes = Object.freeze({
EdgeAgentOnKubernetesEnvironment: 7,
});
/**
* JS reference of endpoint_create.go#EndpointCreationType iota
*/
export const PortainerEndpointCreationTypes = Object.freeze({
LocalDockerEnvironment: 1,
AgentEnvironment: 2,
AzureEnvironment: 3,
EdgeAgentEnvironment: 4,
LocalKubernetesEnvironment: 5,
});
export const PortainerEndpointConnectionTypes = Object.freeze({
DOCKER_LOCAL: 1,
KUBERNETES_LOCAL: 2,

View File

@ -1,4 +1,4 @@
import { PortainerEndpointTypes } from 'Portainer/models/endpoint/models';
import { PortainerEndpointCreationTypes } from 'Portainer/models/endpoint/models';
angular.module('portainer.app').factory('EndpointService', [
'$q',
@ -59,7 +59,7 @@ angular.module('portainer.app').factory('EndpointService', [
service.createLocalEndpoint = function () {
var deferred = $q.defer();
FileUploadService.createEndpoint('local', PortainerEndpointTypes.DockerEnvironment, '', '', 1, [], false)
FileUploadService.createEndpoint('local', PortainerEndpointCreationTypes.LocalDockerEnvironment, '', '', 1, [], false)
.then(function success(response) {
deferred.resolve(response.data);
})
@ -72,7 +72,7 @@ angular.module('portainer.app').factory('EndpointService', [
service.createRemoteEndpoint = function (
name,
type,
creationType,
URL,
PublicURL,
groupID,
@ -88,17 +88,13 @@ angular.module('portainer.app').factory('EndpointService', [
var deferred = $q.defer();
var endpointURL = URL;
if (
type !== PortainerEndpointTypes.EdgeAgentOnDockerEnvironment &&
type !== PortainerEndpointTypes.AgentOnKubernetesEnvironment &&
type !== PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment
) {
if (creationType !== PortainerEndpointCreationTypes.EdgeAgentEnvironment) {
endpointURL = 'tcp://' + URL;
}
FileUploadService.createEndpoint(
name,
type,
creationType,
endpointURL,
PublicURL,
groupID,
@ -124,7 +120,7 @@ angular.module('portainer.app').factory('EndpointService', [
service.createLocalKubernetesEndpoint = function () {
var deferred = $q.defer();
FileUploadService.createEndpoint('local', 5, '', '', 1, [], true, true, true)
FileUploadService.createEndpoint('local', PortainerEndpointCreationTypes.LocalKubernetesEnvironment, '', '', 1, [], true, true, true)
.then(function success(response) {
deferred.resolve(response.data);
})

View File

@ -1,3 +1,4 @@
import { PortainerEndpointCreationTypes } from 'Portainer/models/endpoint/models';
import { genericHandler, jsonObjectsToArrayHandler } from '../../docker/rest/response/handlers';
angular.module('portainer.app').factory('FileUploadService', [
@ -112,12 +113,26 @@ angular.module('portainer.app').factory('FileUploadService', [
});
};
service.createEndpoint = function (name, type, URL, PublicURL, groupID, tagIds, TLS, TLSSkipVerify, TLSSkipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile, checkinInterval) {
service.createEndpoint = function (
name,
creationType,
URL,
PublicURL,
groupID,
tagIds,
TLS,
TLSSkipVerify,
TLSSkipClientVerify,
TLSCAFile,
TLSCertFile,
TLSKeyFile,
checkinInterval
) {
return Upload.upload({
url: 'api/endpoints',
data: {
Name: name,
EndpointType: type,
EndpointCreationType: creationType,
URL: URL,
PublicURL: PublicURL,
GroupID: groupID,
@ -139,7 +154,7 @@ angular.module('portainer.app').factory('FileUploadService', [
url: 'api/endpoints',
data: {
Name: name,
EndpointType: 3,
EndpointCreationType: PortainerEndpointCreationTypes.Azure,
GroupID: groupId,
TagIds: Upload.json(tagIds),
AzureApplicationID: applicationId,

View File

@ -1,4 +1,4 @@
import { PortainerEndpointTypes } from 'Portainer/models/endpoint/models';
import { PortainerEndpointCreationTypes, PortainerEndpointTypes } from 'Portainer/models/endpoint/models';
import { EndpointSecurityFormData } from '../../../components/endpointSecurity/porEndpointSecurityModel';
angular
@ -56,7 +56,7 @@ angular
};
$scope.copyAgentCommand = function () {
if ($scope.state.deploymentTab === 0) {
if ($scope.state.deploymentTab === 1) {
clipboard.copyText('curl -L https://downloads.portainer.io/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent');
} else {
clipboard.copyText('curl -L https://downloads.portainer.io/portainer-agent-k8s.yaml -o portainer-agent-k8s.yaml; kubectl apply -f portainer-agent-k8s.yaml');
@ -102,19 +102,31 @@ angular
var TLSCertFile = TLSSkipClientVerify ? null : securityData.TLSCert;
var TLSKeyFile = TLSSkipClientVerify ? null : securityData.TLSKey;
addEndpoint(name, PortainerEndpointTypes.DockerEnvironment, URL, publicURL, groupId, tagIds, TLS, TLSSkipVerify, TLSSkipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile);
addEndpoint(
name,
PortainerEndpointCreationTypes.LocalDockerEnvironment,
URL,
publicURL,
groupId,
tagIds,
TLS,
TLSSkipVerify,
TLSSkipClientVerify,
TLSCAFile,
TLSCertFile,
TLSKeyFile
);
};
$scope.addAgentEndpoint = function () {
var name = $scope.formValues.Name;
var URL = $filter('stripprotocol')($scope.formValues.URL);
// var URL = $filter('stripprotocol')($scope.formValues.URL);
var URL = $scope.formValues.URL;
var publicURL = $scope.formValues.PublicURL === '' ? URL.split(':')[0] : $scope.formValues.PublicURL;
var groupId = $scope.formValues.GroupId;
var tagIds = $scope.formValues.TagIds;
addEndpoint(name, PortainerEndpointTypes.AgentOnDockerEnvironment, URL, publicURL, groupId, tagIds, true, true, true, null, null, null);
// TODO: k8s merge - temporarily updated to AgentOnKubernetesEnvironment, breaking Docker agent support
// addEndpoint(name, PortainerEndpointTypes.AgentOnKubernetesEnvironment, URL, publicURL, groupId, tags, true, true, true, null, null, null);
addEndpoint(name, PortainerEndpointCreationTypes.AgentEnvironment, URL, publicURL, groupId, tagIds, true, true, true, null, null, null);
};
$scope.addEdgeAgentEndpoint = function () {
@ -123,9 +135,7 @@ angular
var tagIds = $scope.formValues.TagIds;
var URL = $scope.formValues.URL;
addEndpoint(name, PortainerEndpointTypes.EdgeAgentOnDockerEnvironment, URL, '', groupId, tagIds, false, false, false, null, null, null, $scope.formValues.CheckinInterval);
// TODO: k8s merge - temporarily updated to EdgeAgentOnKubernetesEnvironment, breaking Docker Edge agent support
// addEndpoint(name, PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment, URL, "", groupId, tags, false, false, false, null, null, null);
addEndpoint(name, PortainerEndpointCreationTypes.EdgeAgentEnvironment, URL, '', groupId, tagIds, false, false, false, null, null, null, $scope.formValues.CheckinInterval);
};
$scope.addAzureEndpoint = function () {
@ -154,11 +164,11 @@ angular
});
}
function addEndpoint(name, type, URL, PublicURL, groupId, tagIds, TLS, TLSSkipVerify, TLSSkipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile, CheckinInterval) {
function addEndpoint(name, creationType, URL, PublicURL, groupId, tagIds, TLS, TLSSkipVerify, TLSSkipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile, CheckinInterval) {
$scope.state.actionInProgress = true;
EndpointService.createRemoteEndpoint(
name,
type,
creationType,
URL,
PublicURL,
groupId,
@ -171,14 +181,19 @@ angular
TLSKeyFile,
CheckinInterval
)
.then(function success(data) {
.then(function success(endpoint) {
Notifications.success('Endpoint created', name);
if (type === PortainerEndpointTypes.EdgeAgentOnDockerEnvironment || type === PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment) {
$state.go('portainer.endpoints.endpoint', { id: data.Id });
} else if (type === PortainerEndpointTypes.AgentOnKubernetesEnvironment) {
$state.go('portainer.endpoints.endpoint.kubernetesConfig', { id: data.Id });
} else {
$state.go('portainer.endpoints', {}, { reload: true });
switch (endpoint.Type) {
case PortainerEndpointTypes.EdgeAgentOnDockerEnvironment:
case PortainerEndpointTypes.EdgeAgentOnKubernetesEnvironment:
$state.go('portainer.endpoints.endpoint', { id: endpoint.Id });
break;
case PortainerEndpointTypes.AgentOnKubernetesEnvironment:
$state.go('portainer.endpoints.endpoint.kubernetesConfig', { id: endpoint.Id });
break;
default:
$state.go('portainer.endpoints', {}, { reload: true });
break;
}
})
.catch(function error(err) {

View File

@ -73,19 +73,19 @@
</div>
<div class="form-group">
<span class="col-sm-12 text-muted small">
Ensure that you have deployed the Portainer agent in your cluster first. You can use execute the following command on any manager node to deploy it.
Ensure that you have deployed the Portainer agent in your cluster first. Refer to the platform related command below to deploy it.
<div style="margin-top: 10px;">
<uib-tabset active="state.deploymentTab">
<uib-tab index="0" heading="Kubernetes">
<code style="display: block; white-space: pre-wrap;">
curl -L https://downloads.portainer.io/portainer-agent-k8s.yaml -o portainer-agent-k8s.yaml; kubectl apply -f portainer-agent-k8s.yaml
</code>
<code style="display: block; white-space: pre-wrap; padding: 16px 90px;"
>curl -L https://downloads.portainer.io/portainer-agent-k8s.yaml -o portainer-agent-k8s.yaml; kubectl apply -f portainer-agent-k8s.yaml</code
>
</uib-tab>
<uib-tab index="0" heading="Docker">
<code>
curl -L https://downloads.portainer.io/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent
</code>
<uib-tab index="1" heading="Docker Swarm">
<code style="display: block; white-space: pre-wrap; padding: 16px 90px;"
>curl -L https://downloads.portainer.io/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent</code
>
</uib-tab>
</uib-tabset>
<div style="margin-top: 10px;">

View File

@ -28,23 +28,23 @@
<span class="small text-muted">
<p>
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px;"></i>
Deploy the Edge agent on your remote Docker/Kubernetes environment using the following command(s)
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>
<div style="margin-top: 10px;">
<uib-tabset active="state.deploymentTab">
<uib-tab index="0" heading="Standalone">
<code style="display: block; white-space: pre-wrap; padding: 16px 90px;">{{ dockerCommands.standalone }}</code>
<uib-tab index="0" heading="Kubernetes">
<code style="display: block; white-space: pre-wrap; padding: 16px 90px;"
>curl https://downloads.portainer.io/portainer-edge-agent-setup.sh | sudo bash -s -- {{ randomEdgeID }} {{ endpoint.EdgeKey }}</code
>
</uib-tab>
<uib-tab index="1" heading="Swarm">
<uib-tab index="1" heading="Docker Swarm">
<code style="display: block; white-space: pre-wrap; padding: 16px 90px;">{{ dockerCommands.swarm }}</code>
</uib-tab>
<uib-tab index="0" heading="Kubernetes">
<code style="display: block; white-space: pre-wrap;">
curl https://downloads.portainer.io/portainer-edge-agent-setup.sh | sudo bash -s -- {{ randomEdgeID }} {{ endpoint.EdgeKey }}
</code>
<uib-tab index="2" heading="Docker Standalone">
<code style="display: block; white-space: pre-wrap; padding: 16px 90px;">{{ dockerCommands.standalone }}</code>
</uib-tab>
</uib-tabset>
<div style="margin-top: 10px;">

View File

@ -55,7 +55,7 @@ angular
};
$scope.copyEdgeAgentDeploymentCommand = function () {
if ($scope.state.deploymentTab === 0) {
if ($scope.state.deploymentTab === 2) {
clipboard.copyText(
'docker run -d -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker/volumes:/var/lib/docker/volumes -v /:/host --restart always -e EDGE=1 -e EDGE_ID=' +
$scope.randomEdgeID +

View File

@ -1,7 +1,7 @@
import _ from 'lodash-es';
import angular from 'angular';
import { PortainerEndpointInitFormValueEndpointSections, PortainerEndpointInitFormValues } from 'Portainer/models/endpoint/formValues';
import { PortainerEndpointConnectionTypes, PortainerEndpointTypes } from 'Portainer/models/endpoint/models';
import { PortainerEndpointConnectionTypes, PortainerEndpointCreationTypes, PortainerEndpointTypes } from 'Portainer/models/endpoint/models';
require('./includes/localDocker.html');
require('./includes/localKubernetes.html');
@ -61,7 +61,7 @@ class InitEndpointController {
case PortainerEndpointConnectionTypes.AGENT:
return this.createAgentEndpoint();
default:
this.Notifications.error('Failure', 'Unable to determine wich action to do');
this.Notifications.error('Failure', 'Unable to determine which action to do');
}
}
@ -112,10 +112,10 @@ class InitEndpointController {
const name = this.formValues.Name;
const URL = this.formValues.URL;
const PublicURL = URL.split(':')[0];
// TODO: k8s merge - change type ID for agent on kube (6) or agent on swarm (2)
const endpoint = await this.EndpointService.createRemoteEndpoint(
name,
PortainerEndpointTypes.AgentOnKubernetesEnvironment,
PortainerEndpointCreationTypes.AgentEnvironment,
URL,
PublicURL,
1,
@ -127,8 +127,8 @@ class InitEndpointController {
null,
null
);
// TODO: k8s merge - go on home whith agent on swarm (2)
this.$state.go('portainer.endpoints.endpoint.kubernetesConfig', { id: endpoint.Id });
const routeName = endpoint.Type === PortainerEndpointTypes.AgentOnKubernetesEnvironment ? 'portainer.endpoints.endpoint.kubernetesConfig' : 'portainer.home';
this.$state.go(routeName, { id: endpoint.Id });
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to connect to the Docker environment');
} finally {