add base url support
This commit is contained in:
@@ -55,6 +55,7 @@ func (*Service) ParseFlags(version string) (*portainer.CLIFlags, error) {
|
||||
Labels: pairs(kingpin.Flag("hide-label", "Hide containers with a specific label in the UI").Short('l')),
|
||||
Logo: kingpin.Flag("logo", "URL for the logo displayed in the UI").String(),
|
||||
Templates: kingpin.Flag("templates", "URL to the templates definitions.").Short('t').String(),
|
||||
BaseURL: kingpin.Flag("base-url", "Base URL parameter such as portainer if running portainer as http://yourdomain.com/portainer/.").Short('b').Default(defaultBaseURL).String(),
|
||||
}
|
||||
|
||||
kingpin.Parse()
|
||||
|
||||
@@ -19,4 +19,5 @@ const (
|
||||
defaultSSLCertPath = "/certs/portainer.crt"
|
||||
defaultSSLKeyPath = "/certs/portainer.key"
|
||||
defaultSnapshotInterval = "5m"
|
||||
defaultBaseURL = "/"
|
||||
)
|
||||
|
||||
@@ -17,4 +17,5 @@ const (
|
||||
defaultSSLCertPath = "C:\\certs\\portainer.crt"
|
||||
defaultSSLKeyPath = "C:\\certs\\portainer.key"
|
||||
defaultSnapshotInterval = "5m"
|
||||
defaultBaseURL = "/"
|
||||
)
|
||||
|
||||
@@ -650,6 +650,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
||||
ShutdownCtx: shutdownCtx,
|
||||
ShutdownTrigger: shutdownTrigger,
|
||||
StackDeployer: stackDeployer,
|
||||
BaseURL: *flags.BaseURL,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,15 +21,17 @@ type Handler struct {
|
||||
kubernetesClientFactory *cli.ClientFactory
|
||||
authorizationService *authorization.Service
|
||||
JwtService portainer.JWTService
|
||||
BaseURL string
|
||||
}
|
||||
|
||||
// NewHandler creates a handler to process pre-proxied requests to external APIs.
|
||||
func NewHandler(bouncer *security.RequestBouncer, authorizationService *authorization.Service, dataStore portainer.DataStore, kubernetesClientFactory *cli.ClientFactory) *Handler {
|
||||
func NewHandler(bouncer *security.RequestBouncer, authorizationService *authorization.Service, dataStore portainer.DataStore, kubernetesClientFactory *cli.ClientFactory, baseURL string) *Handler {
|
||||
h := &Handler{
|
||||
Router: mux.NewRouter(),
|
||||
dataStore: dataStore,
|
||||
kubernetesClientFactory: kubernetesClientFactory,
|
||||
authorizationService: authorizationService,
|
||||
BaseURL: baseURL,
|
||||
}
|
||||
|
||||
kubeRouter := h.PathPrefix("/kubernetes").Subrouter()
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
clientV1 "k8s.io/client-go/tools/clientcmd/api/v1"
|
||||
|
||||
@@ -162,6 +163,14 @@ func buildCluster(r *http.Request, endpoint portainer.Endpoint) clientV1.NamedCl
|
||||
}
|
||||
}
|
||||
|
||||
// getProxyUrl generates portainer proxy url which acts as proxy to k8s api server
|
||||
func getProxyUrl(r *http.Request, baseURL string, endpointID int) string {
|
||||
if baseURL != "/" {
|
||||
baseURL = fmt.Sprintf("/%s/", strings.Trim(baseURL, "/"))
|
||||
}
|
||||
return fmt.Sprintf("https://%s%sapi/endpoints/%d/kubernetes", r.Host, baseURL, endpointID)
|
||||
}
|
||||
|
||||
func buildClusterName(endpointName string) string {
|
||||
return fmt.Sprintf("portainer-cluster-%s", endpointName)
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ type Server struct {
|
||||
ShutdownCtx context.Context
|
||||
ShutdownTrigger context.CancelFunc
|
||||
StackDeployer stackdeployer.StackDeployer
|
||||
BaseURL string
|
||||
}
|
||||
|
||||
// Start starts the HTTP server
|
||||
@@ -170,7 +171,7 @@ func (server *Server) Start() error {
|
||||
endpointProxyHandler.ProxyManager = server.ProxyManager
|
||||
endpointProxyHandler.ReverseTunnelService = server.ReverseTunnelService
|
||||
|
||||
var kubernetesHandler = kubehandler.NewHandler(requestBouncer, server.AuthorizationService, server.DataStore, server.KubernetesClientFactory)
|
||||
var kubernetesHandler = kubehandler.NewHandler(requestBouncer, server.AuthorizationService, server.DataStore, server.KubernetesClientFactory, server.BaseURL)
|
||||
kubernetesHandler.JwtService = server.JWTService
|
||||
|
||||
var fileHandler = file.NewHandler(filepath.Join(server.AssetsPath, "public"))
|
||||
|
||||
@@ -67,6 +67,7 @@ type (
|
||||
SSLKey *string
|
||||
Rollback *bool
|
||||
SnapshotInterval *string
|
||||
BaseURL *string
|
||||
}
|
||||
|
||||
// CustomTemplate represents a custom template
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Terminal } from 'xterm';
|
||||
import { baseHref } from '@/portainer/helpers/pathHelper';
|
||||
|
||||
angular.module('portainer.docker').controller('ContainerConsoleController', [
|
||||
'$scope',
|
||||
@@ -69,7 +70,8 @@ angular.module('portainer.docker').controller('ContainerConsoleController', [
|
||||
};
|
||||
|
||||
var url =
|
||||
window.location.href.split('#')[0] +
|
||||
window.location.origin +
|
||||
baseHref() +
|
||||
'api/websocket/attach?' +
|
||||
Object.keys(params)
|
||||
.map((k) => k + '=' + params[k])
|
||||
@@ -109,7 +111,8 @@ angular.module('portainer.docker').controller('ContainerConsoleController', [
|
||||
};
|
||||
|
||||
var url =
|
||||
window.location.href.split('#')[0] +
|
||||
window.location.origin +
|
||||
baseHref() +
|
||||
'api/websocket/exec?' +
|
||||
Object.keys(params)
|
||||
.map((k) => k + '=' + params[k])
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
<title>Portainer</title>
|
||||
<meta name="description" content="" />
|
||||
<meta name="author" content="<%= author %>" />
|
||||
<base id="base" />
|
||||
<script>
|
||||
var path = window.location.pathname.replace(/^\/+|\/+$/g, '');
|
||||
var basePath = path ? '/' + path + '/' : '/';
|
||||
document.getElementById('base').href = basePath;
|
||||
</script>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Terminal } from 'xterm';
|
||||
import * as fit from 'xterm/lib/addons/fit/fit';
|
||||
import { baseHref } from '@/portainer/helpers/pathHelper';
|
||||
|
||||
export default class KubectlShellController {
|
||||
/* @ngInject */
|
||||
@@ -91,7 +92,7 @@ export default class KubectlShellController {
|
||||
};
|
||||
|
||||
const wsProtocol = this.$window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
const path = '/api/websocket/kubernetes-shell';
|
||||
const path = baseHref() + 'api/websocket/kubernetes-shell';
|
||||
const queryParams = Object.entries(params)
|
||||
.map(([k, v]) => `${k}=${v}`)
|
||||
.join('&');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import angular from 'angular';
|
||||
import { Terminal } from 'xterm';
|
||||
import { baseHref } from '@/portainer/helpers/pathHelper';
|
||||
|
||||
class KubernetesApplicationConsoleController {
|
||||
/* @ngInject */
|
||||
@@ -59,7 +60,8 @@ class KubernetesApplicationConsoleController {
|
||||
};
|
||||
|
||||
let url =
|
||||
window.location.href.split('#')[0] +
|
||||
window.location.origin +
|
||||
baseHref() +
|
||||
'api/websocket/pod?' +
|
||||
Object.keys(params)
|
||||
.map((k) => k + '=' + params[k])
|
||||
|
||||
10
app/portainer/helpers/pathHelper.js
Normal file
10
app/portainer/helpers/pathHelper.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* calculates baseHref
|
||||
*
|
||||
* return [string]
|
||||
*
|
||||
*/
|
||||
export function baseHref() {
|
||||
const base = document.getElementById('base');
|
||||
return base ? base.getAttribute('href') : '/';
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { baseHref } from '@/portainer/helpers/pathHelper';
|
||||
|
||||
angular.module('portainer.app').factory('WebhookHelper', [
|
||||
'$location',
|
||||
'API_ENDPOINT_WEBHOOKS',
|
||||
@@ -11,11 +13,11 @@ angular.module('portainer.app').factory('WebhookHelper', [
|
||||
const displayPort = (protocol === 'http' && port === 80) || (protocol === 'https' && port === 443) ? '' : ':' + port;
|
||||
|
||||
helper.returnWebhookUrl = function (token) {
|
||||
return `${protocol}://${$location.host()}${displayPort}/${API_ENDPOINT_WEBHOOKS}/${token}`;
|
||||
return `${protocol}://${$location.host()}${displayPort}${baseHref()}${API_ENDPOINT_WEBHOOKS}/${token}`;
|
||||
};
|
||||
|
||||
helper.returnStackWebhookUrl = function (token) {
|
||||
return `${protocol}://${$location.host()}${displayPort}/${API_ENDPOINT_STACKS}/webhooks/${token}`;
|
||||
return `${protocol}://${$location.host()}${displayPort}${baseHref()}${API_ENDPOINT_STACKS}/webhooks/${token}`;
|
||||
};
|
||||
|
||||
return helper;
|
||||
|
||||
Reference in New Issue
Block a user