Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pod attach/exec proto #1939

Merged
merged 2 commits into from
Jun 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
"ng-jsoneditor": "angular-tools/ng-jsoneditor#~1.0.0",
"angularUtils-pagination": "angular-utils-pagination#~0.11.1",
"easyfont-roboto-mono": "easyfont/roboto-mono#fa7971ea56f68bfdb2771f9cb560c99aca0164c1",
"angular-clipboard": "^1.5.0"
"angular-clipboard": "^1.5.0",
"hterm": "~1.0.0",
"sockjs-client": "^1.1.4"
},
"overrides": {
"material-design-icons": {
Expand Down
3 changes: 3 additions & 0 deletions build/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ function compileES6(translation) {
path.join(conf.paths.externs, 'dataselect.js'),
path.join(conf.paths.externs, 'dirPagination.js'),
path.join(conf.paths.externs, 'searchapi.js'),
path.join(conf.paths.externs, 'shell.js'),
path.join(conf.paths.externs, 'hterm.js'),
path.join(conf.paths.externs, 'sockjs.js'),
];

let closureCompilerConfig = {
Expand Down
13 changes: 7 additions & 6 deletions build/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ import browserSync from 'browser-sync';
import browserSyncSpa from 'browser-sync-spa';
import child from 'child_process';
import gulp from 'gulp';
import proxyMiddleware from 'http-proxy-middleware';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should run gulp format.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import path from 'path';
import proxyMiddleware from 'proxy-middleware';
import url from 'url';
import conf from './conf';

/**
Expand Down Expand Up @@ -77,17 +76,19 @@ function browserSyncInit(baseDir, includeBowerComponents) {
}));

let apiRoute = '/api';
let proxyMiddlewareOptions =
url.parse(`http://localhost:${conf.backend.devServerPort}${apiRoute}`);
proxyMiddlewareOptions.route = apiRoute;
let proxyMiddlewareOptions = {
target: `http://localhost:${conf.backend.devServerPort}`,
// proxy websockets
ws: true,
};

let config = {
browser: [], // Needed so that the browser does not auto-launch.
directory: false, // Disable directory listings.
// TODO(bryk): Add proxy to the backend here.
server: {
baseDir: baseDir,
middleware: proxyMiddleware(proxyMiddlewareOptions),
middleware: proxyMiddleware(apiRoute, proxyMiddlewareOptions),
},
port: conf.frontend.serverPort,
startPath: '/',
Expand Down
1 change: 1 addition & 0 deletions src/app/backend/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func main() {
http.Handle("/api/", apiHandler)
// TODO(maciaszczykm): Move to /appConfig.json as it was discussed in #640.
http.Handle("/api/appConfig.json", handler.AppHandler(handler.ConfigHandler))
http.Handle("/api/sockjs/", handler.CreateAttachHandler("/api/sockjs"))
http.Handle("/metrics", prometheus.Handler())

// Listen for http and https
Expand Down
40 changes: 40 additions & 0 deletions src/app/backend/handler/apihandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import (
"golang.org/x/net/xsrftoken"
errorsK8s "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
)

const (
Expand All @@ -76,6 +77,12 @@ type APIHandler struct {
manager client.ClientManager
}

// TerminalResponse is sent by handleExecShell. The Id is a random session id that binds the original REST request and the SockJS connection.
// Any client in possession of this Id can hijack the terminal session.
type TerminalResponse struct {
Id string `json:"id"`
}

// CreateHTTPAPIHandler creates a new HTTP handler that handles all requests to the API of the backend.
func CreateHTTPAPIHandler(heapsterClient heapster.HeapsterClient, manager client.ClientManager) (
http.Handler, error) {
Expand Down Expand Up @@ -238,6 +245,10 @@ func CreateHTTPAPIHandler(heapsterClient heapster.HeapsterClient, manager client
apiV1Ws.GET("/pod/{namespace}/{pod}/event").
To(apiHandler.handleGetPodEvents).
Writes(common.EventList{}))
apiV1Ws.Route(
apiV1Ws.GET("/pod/{namespace}/{pod}/shell/{container}").
To(apiHandler.handleExecShell).
Writes(TerminalResponse{}))

apiV1Ws.Route(
apiV1Ws.GET("/deployment").
Expand Down Expand Up @@ -1148,6 +1159,35 @@ func (apiHandler *APIHandler) handleGetPodEvents(request *restful.Request, respo
response.WriteHeaderAndEntity(http.StatusOK, result)
}

// Handles execute shell API call
func (apiHandler *APIHandler) handleExecShell(request *restful.Request, response *restful.Response) {
sessionId, err := genTerminalSessionId()
if err != nil {
handleInternalError(response, err)
return
}

k8sClient, err := apiHandler.manager.Client(request)
if err != nil {
handleInternalError(response, err)
return
}

cfg, err := apiHandler.manager.Config(request)
if err != nil {
handleInternalError(response, err)
return
}

terminalSessions[sessionId] = TerminalSession{
id: sessionId,
bound: make(chan error),
sizeChan: make(chan remotecommand.TerminalSize),
}
go WaitForTerminal(k8sClient, cfg, request, sessionId)
response.WriteHeaderAndEntity(http.StatusOK, TerminalResponse{Id: sessionId})
}

func (apiHandler *APIHandler) handleGetDeployments(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.manager.Client(request)
if err != nil {
Expand Down
Loading