Skip to content

Commit 47d68be

Browse files
committed
add proxy endpoint
1 parent 6428cd4 commit 47d68be

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

pkg/cmd/server/origin/master.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
kubeapiserver "k8s.io/kubernetes/pkg/master"
1717
kcorestorage "k8s.io/kubernetes/pkg/registry/core/rest"
1818

19+
"io/ioutil"
20+
1921
assetapiserver "github.com/openshift/origin/pkg/assets/apiserver"
2022
configapi "github.com/openshift/origin/pkg/cmd/server/api"
2123
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
@@ -153,6 +155,19 @@ func (c *MasterConfig) newAssetServerHandler(genericConfig *apiserver.Config) (h
153155
return http.NotFoundHandler(), nil
154156
}
155157

158+
if WebConsoleProxy() {
159+
fmt.Printf("#### installing the webconsole proxy")
160+
caBundle, err := ioutil.ReadFile(c.Options.ControllerConfig.ServiceServingCert.Signer.CertFile)
161+
if err != nil {
162+
return nil, err
163+
}
164+
proxyHandler, err := NewWebConsoleProxyHandler(aggregatorapiserver.NewClusterIPServiceResolver(c.ClientGoKubeInformers.Core().V1().Services().Lister()), caBundle)
165+
if err != nil {
166+
return nil, err
167+
}
168+
return proxyHandler, nil
169+
}
170+
156171
config, err := NewAssetServerConfigFromMasterConfig(c.Options)
157172
if err != nil {
158173
return nil, err

pkg/cmd/server/origin/master_config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
kubernetes "github.com/openshift/origin/pkg/cmd/server/kubernetes/master"
3131
originadmission "github.com/openshift/origin/pkg/cmd/server/origin/admission"
3232
originrest "github.com/openshift/origin/pkg/cmd/server/origin/rest"
33+
"github.com/openshift/origin/pkg/cmd/util"
3334
imageadmission "github.com/openshift/origin/pkg/image/admission"
3435
imageapi "github.com/openshift/origin/pkg/image/apis/image"
3536
imageinformer "github.com/openshift/origin/pkg/image/generated/informers/internalversion"
@@ -39,6 +40,8 @@ import (
3940
quotainformer "github.com/openshift/origin/pkg/quota/generated/informers/internalversion"
4041
userinformer "github.com/openshift/origin/pkg/user/generated/informers/internalversion"
4142

43+
"strings"
44+
4245
securityinformer "github.com/openshift/origin/pkg/security/generated/informers/internalversion"
4346
"github.com/openshift/origin/pkg/service"
4447
"github.com/openshift/origin/pkg/util/restoptions"
@@ -259,3 +262,10 @@ func (c *MasterConfig) WebConsoleEnabled() bool {
259262
func (c *MasterConfig) WebConsoleStandalone() bool {
260263
return c.Options.AssetConfig.ServingInfo.BindAddress != c.Options.ServingInfo.BindAddress
261264
}
265+
266+
func WebConsoleProxy() bool {
267+
if false {
268+
return strings.EqualFold(util.Env("OS_WEB_CONSOLE_PROXY", "false"), "true")
269+
}
270+
return true
271+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package origin
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
9+
"k8s.io/apimachinery/pkg/runtime"
10+
utilnet "k8s.io/apimachinery/pkg/util/net"
11+
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
12+
genericrest "k8s.io/apiserver/pkg/registry/generic/rest"
13+
restclient "k8s.io/client-go/rest"
14+
)
15+
16+
// A ServiceResolver knows how to get a URL given a service.
17+
type ServiceResolver interface {
18+
ResolveEndpoint(namespace, name string) (*url.URL, error)
19+
}
20+
21+
// proxyHandler provides a http.Handler which will proxy traffic to locations
22+
// specified by items implementing Redirector.
23+
type webConsoleProxyHandler struct {
24+
// Endpoints based routing to map from cluster IP to routable IP
25+
serviceResolver ServiceResolver
26+
27+
// proxyRoundTripper is the re-useable portion of the transport. It does not vary with any request.
28+
proxyRoundTripper http.RoundTripper
29+
30+
restConfig *restclient.Config
31+
}
32+
33+
const (
34+
serviceName = "webconsole"
35+
serviceNamespace = "openshift-web-console"
36+
)
37+
38+
func NewWebConsoleProxyHandler(serviceResolver ServiceResolver, caBundle []byte) (*webConsoleProxyHandler, error) {
39+
restConfig := &restclient.Config{
40+
TLSClientConfig: restclient.TLSClientConfig{
41+
ServerName: serviceName + "." + serviceNamespace + ".svc",
42+
CAData: caBundle,
43+
},
44+
}
45+
proxyRoundTripper, err := restclient.TransportFor(restConfig)
46+
if err != nil {
47+
return nil, err
48+
}
49+
50+
return &webConsoleProxyHandler{
51+
serviceResolver: serviceResolver,
52+
proxyRoundTripper: proxyRoundTripper,
53+
restConfig: restConfig,
54+
}, nil
55+
}
56+
57+
func (r *webConsoleProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
58+
// write a new location based on the existing request pointed at the target service
59+
location := &url.URL{}
60+
location.Scheme = "https"
61+
rloc, err := r.serviceResolver.ResolveEndpoint(serviceNamespace, serviceName)
62+
if err != nil {
63+
http.Error(w, fmt.Sprintf("missing route (%s)", err.Error()), http.StatusInternalServerError)
64+
return
65+
}
66+
location.Host = rloc.Host
67+
location.Path = req.URL.Path
68+
location.RawQuery = req.URL.Query().Encode()
69+
70+
// WithContext creates a shallow clone of the request with the new context.
71+
newReq := req.WithContext(context.Background())
72+
newReq.Header = utilnet.CloneHeader(req.Header)
73+
newReq.URL = location
74+
75+
handler := genericrest.NewUpgradeAwareProxyHandler(location, r.proxyRoundTripper, true, false, &responder{w: w})
76+
handler.ServeHTTP(w, newReq)
77+
}
78+
79+
// responder implements rest.Responder for assisting a connector in writing objects or errors.
80+
type responder struct {
81+
w http.ResponseWriter
82+
}
83+
84+
// TODO this should properly handle content type negotiation
85+
// if the caller asked for protobuf and you write JSON bad things happen.
86+
func (r *responder) Object(statusCode int, obj runtime.Object) {
87+
responsewriters.WriteRawJSON(statusCode, obj, r.w)
88+
}
89+
90+
func (r *responder) Error(err error) {
91+
http.Error(r.w, err.Error(), http.StatusInternalServerError)
92+
}

0 commit comments

Comments
 (0)