mirror of https://github.com/linkerd/linkerd2.git
Fix panic when routes is called in single-namespace mode (#2123)
Fixes #2119 When Linkerd is installed in single-namespace mode, the public-api container panics when it attempts to access watch service profiles. In single-namespace mode, we no longer watch service profiles and return an informative error when the TopRoutes API is called. Signed-off-by: Alex Leong <alex@buoyant.io>
This commit is contained in:
parent
b227c85a5b
commit
32efab41b5
|
@ -30,6 +30,7 @@ type (
|
||||||
k8sAPI *k8s.API
|
k8sAPI *k8s.API
|
||||||
controllerNamespace string
|
controllerNamespace string
|
||||||
ignoredNamespaces []string
|
ignoredNamespaces []string
|
||||||
|
singleNamespace bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ func newGrpcServer(
|
||||||
k8sAPI *k8s.API,
|
k8sAPI *k8s.API,
|
||||||
controllerNamespace string,
|
controllerNamespace string,
|
||||||
ignoredNamespaces []string,
|
ignoredNamespaces []string,
|
||||||
|
singleNamespace bool,
|
||||||
) *grpcServer {
|
) *grpcServer {
|
||||||
return &grpcServer{
|
return &grpcServer{
|
||||||
prometheusAPI: promAPI,
|
prometheusAPI: promAPI,
|
||||||
|
@ -59,6 +61,7 @@ func newGrpcServer(
|
||||||
k8sAPI: k8sAPI,
|
k8sAPI: k8sAPI,
|
||||||
controllerNamespace: controllerNamespace,
|
controllerNamespace: controllerNamespace,
|
||||||
ignoredNamespaces: ignoredNamespaces,
|
ignoredNamespaces: ignoredNamespaces,
|
||||||
|
singleNamespace: singleNamespace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -243,6 +243,7 @@ spec:
|
||||||
k8sAPI,
|
k8sAPI,
|
||||||
"linkerd",
|
"linkerd",
|
||||||
[]string{},
|
[]string{},
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
k8sAPI.Sync()
|
k8sAPI.Sync()
|
||||||
|
@ -343,6 +344,7 @@ metadata:
|
||||||
k8sAPI,
|
k8sAPI,
|
||||||
"linkerd",
|
"linkerd",
|
||||||
[]string{},
|
[]string{},
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
k8sAPI.Sync()
|
k8sAPI.Sync()
|
||||||
|
|
|
@ -247,6 +247,7 @@ func NewServer(
|
||||||
k8sAPI *k8s.API,
|
k8sAPI *k8s.API,
|
||||||
controllerNamespace string,
|
controllerNamespace string,
|
||||||
ignoredNamespaces []string,
|
ignoredNamespaces []string,
|
||||||
|
singleNamespace bool,
|
||||||
) *http.Server {
|
) *http.Server {
|
||||||
baseHandler := &handler{
|
baseHandler := &handler{
|
||||||
grpcServer: newGrpcServer(
|
grpcServer: newGrpcServer(
|
||||||
|
@ -255,6 +256,7 @@ func NewServer(
|
||||||
k8sAPI,
|
k8sAPI,
|
||||||
controllerNamespace,
|
controllerNamespace,
|
||||||
ignoredNamespaces,
|
ignoredNamespaces,
|
||||||
|
singleNamespace,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -776,6 +776,7 @@ status:
|
||||||
k8sAPI,
|
k8sAPI,
|
||||||
"linkerd",
|
"linkerd",
|
||||||
[]string{},
|
[]string{},
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
_, err := fakeGrpcServer.StatSummary(context.TODO(), &exp.req)
|
_, err := fakeGrpcServer.StatSummary(context.TODO(), &exp.req)
|
||||||
|
@ -800,6 +801,7 @@ status:
|
||||||
k8sAPI,
|
k8sAPI,
|
||||||
"linkerd",
|
"linkerd",
|
||||||
[]string{},
|
[]string{},
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
invalidRequests := []statSumExpected{
|
invalidRequests := []statSumExpected{
|
||||||
|
|
|
@ -281,6 +281,7 @@ func newMockGrpcServer(exp expectedStatRPC) (*mockProm, *grpcServer, error) {
|
||||||
k8sAPI,
|
k8sAPI,
|
||||||
"linkerd",
|
"linkerd",
|
||||||
[]string{},
|
[]string{},
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
k8sAPI.Sync()
|
k8sAPI.Sync()
|
||||||
|
|
|
@ -42,6 +42,10 @@ type resourceTable struct {
|
||||||
func (s *grpcServer) TopRoutes(ctx context.Context, req *pb.TopRoutesRequest) (*pb.TopRoutesResponse, error) {
|
func (s *grpcServer) TopRoutes(ctx context.Context, req *pb.TopRoutesRequest) (*pb.TopRoutesResponse, error) {
|
||||||
log.Debugf("TopRoutes request: %+v", req)
|
log.Debugf("TopRoutes request: %+v", req)
|
||||||
|
|
||||||
|
if s.singleNamespace {
|
||||||
|
return topRoutesError(req, "Routes are not available in single-namespace mode"), nil
|
||||||
|
}
|
||||||
|
|
||||||
errRsp := validateRequest(req)
|
errRsp := validateRequest(req)
|
||||||
if errRsp != nil {
|
if errRsp != nil {
|
||||||
return errRsp, nil
|
return errRsp, nil
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/linkerd/linkerd2/controller/api/proxy"
|
"github.com/linkerd/linkerd2/controller/api/proxy"
|
||||||
|
spclient "github.com/linkerd/linkerd2/controller/gen/client/clientset/versioned"
|
||||||
"github.com/linkerd/linkerd2/controller/k8s"
|
"github.com/linkerd/linkerd2/controller/k8s"
|
||||||
"github.com/linkerd/linkerd2/pkg/admin"
|
"github.com/linkerd/linkerd2/pkg/admin"
|
||||||
"github.com/linkerd/linkerd2/pkg/flags"
|
"github.com/linkerd/linkerd2/pkg/flags"
|
||||||
|
@ -32,33 +33,27 @@ func main() {
|
||||||
log.Fatal(err.Error())
|
log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
var k8sAPI *k8s.API
|
var spClient *spclient.Clientset
|
||||||
|
restrictToNamespace := ""
|
||||||
|
resources := []k8s.APIResource{k8s.Endpoint, k8s.Pod, k8s.RS, k8s.Svc}
|
||||||
|
|
||||||
if *singleNamespace {
|
if *singleNamespace {
|
||||||
k8sAPI = k8s.NewAPI(
|
restrictToNamespace = *controllerNamespace
|
||||||
k8sClient,
|
|
||||||
nil,
|
|
||||||
*controllerNamespace,
|
|
||||||
k8s.Endpoint,
|
|
||||||
k8s.Pod,
|
|
||||||
k8s.RS,
|
|
||||||
k8s.Svc,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
spClient, err := k8s.NewSpClientSet(*kubeConfigPath)
|
spClient, err = k8s.NewSpClientSet(*kubeConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err.Error())
|
log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
k8sAPI = k8s.NewAPI(
|
|
||||||
|
resources = append(resources, k8s.SP)
|
||||||
|
}
|
||||||
|
|
||||||
|
k8sAPI := k8s.NewAPI(
|
||||||
k8sClient,
|
k8sClient,
|
||||||
spClient,
|
spClient,
|
||||||
"",
|
restrictToNamespace,
|
||||||
k8s.Endpoint,
|
resources...,
|
||||||
k8s.Pod,
|
|
||||||
k8s.RS,
|
|
||||||
k8s.Svc,
|
|
||||||
k8s.SP,
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/linkerd/linkerd2/controller/api/public"
|
"github.com/linkerd/linkerd2/controller/api/public"
|
||||||
|
spclient "github.com/linkerd/linkerd2/controller/gen/client/clientset/versioned"
|
||||||
"github.com/linkerd/linkerd2/controller/k8s"
|
"github.com/linkerd/linkerd2/controller/k8s"
|
||||||
"github.com/linkerd/linkerd2/controller/tap"
|
"github.com/linkerd/linkerd2/controller/tap"
|
||||||
"github.com/linkerd/linkerd2/pkg/admin"
|
"github.com/linkerd/linkerd2/pkg/admin"
|
||||||
|
@ -41,24 +42,27 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err.Error())
|
log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
spClient, err := k8s.NewSpClientSet(*kubeConfigPath)
|
|
||||||
|
var spClient *spclient.Clientset
|
||||||
|
restrictToNamespace := ""
|
||||||
|
resources := []k8s.APIResource{k8s.Deploy, k8s.Pod, k8s.RC, k8s.RS, k8s.Svc}
|
||||||
|
|
||||||
|
if *singleNamespace {
|
||||||
|
restrictToNamespace = *controllerNamespace
|
||||||
|
} else {
|
||||||
|
spClient, err = k8s.NewSpClientSet(*kubeConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err.Error())
|
log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
restrictToNamespace := ""
|
|
||||||
if *singleNamespace {
|
resources = append(resources, k8s.SP)
|
||||||
restrictToNamespace = *controllerNamespace
|
|
||||||
}
|
}
|
||||||
|
|
||||||
k8sAPI := k8s.NewAPI(
|
k8sAPI := k8s.NewAPI(
|
||||||
k8sClient,
|
k8sClient,
|
||||||
spClient,
|
spClient,
|
||||||
restrictToNamespace,
|
restrictToNamespace,
|
||||||
k8s.Deploy,
|
resources...,
|
||||||
k8s.Pod,
|
|
||||||
k8s.RC,
|
|
||||||
k8s.RS,
|
|
||||||
k8s.SP,
|
|
||||||
k8s.Svc,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
prometheusClient, err := promApi.NewClient(promApi.Config{Address: *prometheusURL})
|
prometheusClient, err := promApi.NewClient(promApi.Config{Address: *prometheusURL})
|
||||||
|
@ -73,6 +77,7 @@ func main() {
|
||||||
k8sAPI,
|
k8sAPI,
|
||||||
*controllerNamespace,
|
*controllerNamespace,
|
||||||
strings.Split(*ignoredNamespaces, ","),
|
strings.Split(*ignoredNamespaces, ","),
|
||||||
|
*singleNamespace,
|
||||||
)
|
)
|
||||||
|
|
||||||
k8sAPI.Sync() // blocks until caches are synced
|
k8sAPI.Sync() // blocks until caches are synced
|
||||||
|
|
Loading…
Reference in New Issue