mirror of https://github.com/k3s-io/k3s
Allocate mux in master.New()
Callsites no longer allocate a mux. Master now exposes method to install handlers which use the master's auth code. Not used but forks (openshift) are expected to use these methods. These methods will later be a point for additional plug-in functionality. Integration tests now use the master-provided handler which has auth, rather than using the mux, which didn't. Fix TestWhoAmI now that /_whoami sits behind auth.pull/6/head
parent
ecdf65f4b1
commit
9713b58caa
|
@ -197,7 +197,6 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
n := net.IPNet(portalNet)
|
n := net.IPNet(portalNet)
|
||||||
mux := http.NewServeMux()
|
|
||||||
config := &master.Config{
|
config := &master.Config{
|
||||||
Client: client,
|
Client: client,
|
||||||
Cloud: cloud,
|
Cloud: cloud,
|
||||||
|
@ -215,7 +214,6 @@ func main() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PortalNet: &n,
|
PortalNet: &n,
|
||||||
Mux: mux,
|
|
||||||
EnableLogsSupport: *enableLogsSupport,
|
EnableLogsSupport: *enableLogsSupport,
|
||||||
EnableUISupport: true,
|
EnableUISupport: true,
|
||||||
APIPrefix: *apiPrefix,
|
APIPrefix: *apiPrefix,
|
||||||
|
|
|
@ -137,14 +137,12 @@ func startComponents(manifestURL string) (apiServerURL string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Nonnumeric port? %v", err)
|
glog.Fatalf("Nonnumeric port? %v", err)
|
||||||
}
|
}
|
||||||
mux := http.NewServeMux()
|
|
||||||
// Create a master and install handlers into mux.
|
// Create a master and install handlers into mux.
|
||||||
master.New(&master.Config{
|
m := master.New(&master.Config{
|
||||||
Client: cl,
|
Client: cl,
|
||||||
EtcdHelper: helper,
|
EtcdHelper: helper,
|
||||||
Minions: machineList,
|
Minions: machineList,
|
||||||
KubeletClient: fakeKubeletClient{},
|
KubeletClient: fakeKubeletClient{},
|
||||||
Mux: mux,
|
|
||||||
EnableLogsSupport: false,
|
EnableLogsSupport: false,
|
||||||
APIPrefix: "/api",
|
APIPrefix: "/api",
|
||||||
|
|
||||||
|
@ -152,7 +150,7 @@ func startComponents(manifestURL string) (apiServerURL string) {
|
||||||
ReadOnlyPort: portNumber,
|
ReadOnlyPort: portNumber,
|
||||||
PublicAddress: host,
|
PublicAddress: host,
|
||||||
})
|
})
|
||||||
handler.delegate = mux
|
handler.delegate = m.Handler
|
||||||
|
|
||||||
// Scheduler
|
// Scheduler
|
||||||
schedulerConfigFactory := &factory.ConfigFactory{cl}
|
schedulerConfigFactory := &factory.ConfigFactory{cl}
|
||||||
|
|
|
@ -180,7 +180,28 @@ func setDefaults(c *Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new instance of Master connected to the given etcd server.
|
// New returns a new instance of Master from the given config.
|
||||||
|
// Certain config fields will be set to a default value if unset,
|
||||||
|
// including:
|
||||||
|
// PortalNet
|
||||||
|
// MasterCount
|
||||||
|
// ReadOnlyPort
|
||||||
|
// ReadWritePort
|
||||||
|
// PublicAddress
|
||||||
|
// Certain config fields must be specified, including:
|
||||||
|
// KubeletClient
|
||||||
|
// Public fields:
|
||||||
|
// Handler -- The returned master has a field TopHandler which is an
|
||||||
|
// http.Handler which handles all the endpoints provided by the master,
|
||||||
|
// including the API, the UI, and miscelaneous debugging endpoints. All
|
||||||
|
// these are subject to authorization and authentication.
|
||||||
|
// Public methods:
|
||||||
|
// HandleWithAuth -- Allows caller to add an http.Handler for an endpoint
|
||||||
|
// that uses the same authentication and authorization (if any is configured)
|
||||||
|
// as the master's built-in endpoints.
|
||||||
|
// If the caller wants to add additional endpoints not using the master's
|
||||||
|
// auth, then the caller should create a handler for those endpoints, which delegates the
|
||||||
|
// any unhandled paths to "Handler".
|
||||||
func New(c *Config) *Master {
|
func New(c *Config) *Master {
|
||||||
setDefaults(c)
|
setDefaults(c)
|
||||||
minionRegistry := makeMinionRegistry(c)
|
minionRegistry := makeMinionRegistry(c)
|
||||||
|
@ -198,7 +219,7 @@ func New(c *Config) *Master {
|
||||||
minionRegistry: minionRegistry,
|
minionRegistry: minionRegistry,
|
||||||
client: c.Client,
|
client: c.Client,
|
||||||
portalNet: c.PortalNet,
|
portalNet: c.PortalNet,
|
||||||
mux: c.Mux,
|
mux: http.NewServeMux(),
|
||||||
enableLogsSupport: c.EnableLogsSupport,
|
enableLogsSupport: c.EnableLogsSupport,
|
||||||
enableUISupport: c.EnableUISupport,
|
enableUISupport: c.EnableUISupport,
|
||||||
apiPrefix: c.APIPrefix,
|
apiPrefix: c.APIPrefix,
|
||||||
|
@ -213,6 +234,24 @@ func New(c *Config) *Master {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleWithAuth adds an http.Handler for pattern to an http.ServeMux
|
||||||
|
// Applies the same authentication and authorization (if any is configured)
|
||||||
|
// to the request is used for the master's built-in endpoints.
|
||||||
|
func (m *Master) HandleWithAuth(pattern string, handler http.Handler) {
|
||||||
|
// TODO: Add a way for plugged-in endpoints to translate their
|
||||||
|
// URLs into attributes that an Authorizer can understand, and have
|
||||||
|
// sensible policy defaults for plugged-in endpoints. This will be different
|
||||||
|
// for generic endpoints versus REST object endpoints.
|
||||||
|
m.mux.Handle(pattern, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleFuncWithAuth adds an http.Handler for pattern to an http.ServeMux
|
||||||
|
// Applies the same authentication and authorization (if any is configured)
|
||||||
|
// to the request is used for the master's built-in endpoints.
|
||||||
|
func (m *Master) HandleFuncWithAuth(pattern string, handler func(http.ResponseWriter, *http.Request)) {
|
||||||
|
m.mux.HandleFunc(pattern, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func makeMinionRegistry(c *Config) minion.Registry {
|
func makeMinionRegistry(c *Config) minion.Registry {
|
||||||
var minionRegistry minion.Registry = etcd.NewRegistry(c.EtcdHelper, nil)
|
var minionRegistry minion.Registry = etcd.NewRegistry(c.EtcdHelper, nil)
|
||||||
if c.HealthCheckMinions {
|
if c.HealthCheckMinions {
|
||||||
|
|
|
@ -63,18 +63,16 @@ xyz987,bob,2
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
mux := http.NewServeMux()
|
|
||||||
|
|
||||||
master.New(&master.Config{
|
m := master.New(&master.Config{
|
||||||
EtcdHelper: helper,
|
EtcdHelper: helper,
|
||||||
Mux: mux,
|
|
||||||
EnableLogsSupport: false,
|
EnableLogsSupport: false,
|
||||||
EnableUISupport: false,
|
EnableUISupport: false,
|
||||||
APIPrefix: "/api",
|
APIPrefix: "/api",
|
||||||
TokenAuthFile: f.Name(),
|
TokenAuthFile: f.Name(),
|
||||||
})
|
})
|
||||||
|
|
||||||
s := httptest.NewServer(mux)
|
s := httptest.NewServer(m.Handler)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
// TODO: also test TLS, using e.g NewUnsafeTLSTransport() and NewClientCertTLSTransport() (see pkg/client/helper.go)
|
// TODO: also test TLS, using e.g NewUnsafeTLSTransport() and NewClientCertTLSTransport() (see pkg/client/helper.go)
|
||||||
|
@ -84,10 +82,11 @@ xyz987,bob,2
|
||||||
name string
|
name string
|
||||||
token string
|
token string
|
||||||
expected string
|
expected string
|
||||||
|
succeeds bool
|
||||||
}{
|
}{
|
||||||
{"Valid token", "abc123", "AUTHENTICATED AS alice"},
|
{"Valid token", "abc123", "AUTHENTICATED AS alice", true},
|
||||||
{"Unknown token", "456jkl", "NOT AUTHENTICATED"},
|
{"Unknown token", "456jkl", "", false},
|
||||||
{"Empty token", "", "NOT AUTHENTICATED"},
|
{"No token", "", "", false},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
req, err := http.NewRequest("GET", s.URL+"/_whoami", nil)
|
req, err := http.NewRequest("GET", s.URL+"/_whoami", nil)
|
||||||
|
@ -101,14 +100,21 @@ xyz987,bob,2
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
if tc.succeeds {
|
||||||
if err != nil {
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
t.Fatalf("unexpected error: %v", err)
|
if err != nil {
|
||||||
}
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := string(body)
|
||||||
|
if tc.expected != actual {
|
||||||
|
t.Errorf("case: %s expected: %v got: %v", tc.name, tc.expected, actual)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if resp.StatusCode != http.StatusUnauthorized {
|
||||||
|
t.Errorf("case: %s expected Unauthorized, got: %v", tc.name, resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
actual := string(body)
|
|
||||||
if tc.expected != actual {
|
|
||||||
t.Errorf("case: %s expected: %v got: %v", tc.name, tc.expected, actual)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ limitations under the License.
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -40,17 +39,14 @@ func TestClient(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
mux := http.NewServeMux()
|
m := master.New(&master.Config{
|
||||||
|
|
||||||
master.New(&master.Config{
|
|
||||||
EtcdHelper: helper,
|
EtcdHelper: helper,
|
||||||
Mux: mux,
|
|
||||||
EnableLogsSupport: false,
|
EnableLogsSupport: false,
|
||||||
EnableUISupport: false,
|
EnableUISupport: false,
|
||||||
APIPrefix: "/api",
|
APIPrefix: "/api",
|
||||||
})
|
})
|
||||||
|
|
||||||
s := httptest.NewServer(mux)
|
s := httptest.NewServer(m.Handler)
|
||||||
|
|
||||||
testCases := []string{
|
testCases := []string{
|
||||||
"v1beta1",
|
"v1beta1",
|
||||||
|
|
Loading…
Reference in New Issue