Skip to content

Commit

Permalink
Put pprof endpoint behind auth (#3793)
Browse files Browse the repository at this point in the history
  • Loading branch information
robertdavidsmith committed Jul 16, 2024
1 parent a013dc4 commit dc817c5
Show file tree
Hide file tree
Showing 45 changed files with 447 additions and 258 deletions.
9 changes: 3 additions & 6 deletions cmd/armada/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/armadaproject/armada/internal/common/health"
"github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/profiling"
"github.com/armadaproject/armada/internal/common/serve"
"github.com/armadaproject/armada/pkg/api"
)

Expand Down Expand Up @@ -64,11 +63,9 @@ func main() {
})

// Expose profiling endpoints if enabled.
if config.PprofPort != nil {
pprofServer := profiling.SetupPprofHttpServer(*config.PprofPort)
g.Go(func() error {
return serve.ListenAndServe(ctx, pprofServer)
})
err := profiling.SetupPprof(config.Profiling, ctx, g)
if err != nil {
log.Fatalf("Pprof setup failed, exiting, %v", err)
}

// TODO This starts a separate HTTP server. Is that intended? Should we have a single mux for everything?
Expand Down
13 changes: 3 additions & 10 deletions cmd/binoculars/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
gateway "github.com/armadaproject/armada/internal/common/grpc"
"github.com/armadaproject/armada/internal/common/health"
"github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/profiling"
"github.com/armadaproject/armada/internal/common/serve"
api "github.com/armadaproject/armada/pkg/api/binoculars"
)

Expand All @@ -47,14 +45,9 @@ func main() {
log.Info("Starting...")

// Expose profiling endpoints if enabled.
if config.PprofPort != nil {
pprofServer := profiling.SetupPprofHttpServer(*config.PprofPort)
go func() {
ctx := armadacontext.Background()
if err := serve.ListenAndServe(ctx, pprofServer); err != nil {
logging.WithStacktrace(ctx, err).Error("pprof server failure")
}
}()
err := profiling.SetupPprof(config.Profiling, armadacontext.Background(), nil)
if err != nil {
log.Fatalf("Pprof setup failed, exiting, %v", err)
}

stopSignal := make(chan os.Signal, 1)
Expand Down
17 changes: 5 additions & 12 deletions cmd/executor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ import (
"syscall"

"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"github.com/spf13/viper"

"github.com/armadaproject/armada/internal/common"
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/health"
"github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/profiling"
"github.com/armadaproject/armada/internal/common/serve"
"github.com/armadaproject/armada/internal/executor"
"github.com/armadaproject/armada/internal/executor/configuration"
)
Expand All @@ -41,14 +39,9 @@ func main() {
common.LoadConfig(&config, "./config/executor", userSpecifiedConfigs)

// Expose profiling endpoints if enabled.
if config.PprofPort != nil {
pprofServer := profiling.SetupPprofHttpServer(*config.PprofPort)
go func() {
ctx := armadacontext.Background()
if err := serve.ListenAndServe(ctx, pprofServer); err != nil {
logging.WithStacktrace(ctx, err).Error("pprof server failure")
}
}()
err := profiling.SetupPprof(config.Profiling, armadacontext.Background(), nil)
if err != nil {
log.Fatalf("Pprof setup failed, exiting, %v", err)
}

mux := http.NewServeMux()
Expand All @@ -68,7 +61,7 @@ func main() {
)
defer shutdownMetricServer()

shutdown, wg := executor.StartUp(armadacontext.Background(), logrus.NewEntry(logrus.StandardLogger()), config)
shutdown, wg := executor.StartUp(armadacontext.Background(), log.NewEntry(log.StandardLogger()), config)
go func() {
<-shutdownChannel
shutdown()
Expand Down
14 changes: 4 additions & 10 deletions cmd/fakeexecutor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import (
"os/signal"
"syscall"

log "github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"github.com/spf13/viper"

"github.com/armadaproject/armada/internal/common"
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/profiling"
"github.com/armadaproject/armada/internal/common/serve"
"github.com/armadaproject/armada/internal/executor/configuration"
"github.com/armadaproject/armada/internal/executor/fake"
"github.com/armadaproject/armada/internal/executor/fake/context"
Expand All @@ -38,14 +37,9 @@ func main() {
v := common.LoadConfig(&config, "./config/executor", userSpecifiedConfigs)

// Expose profiling endpoints if enabled.
if config.PprofPort != nil {
pprofServer := profiling.SetupPprofHttpServer(*config.PprofPort)
go func() {
ctx := armadacontext.Background()
if err := serve.ListenAndServe(ctx, pprofServer); err != nil {
logging.WithStacktrace(ctx, err).Error("pprof server failure")
}
}()
err := profiling.SetupPprof(config.Profiling, armadacontext.Background(), nil)
if err != nil {
log.Fatalf("Pprof setup failed, exiting, %v", err)
}

var nodes []*context.NodeSpec
Expand Down
13 changes: 3 additions & 10 deletions cmd/lookoutv2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import (
"github.com/armadaproject/armada/internal/common"
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/database"
"github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/profiling"
"github.com/armadaproject/armada/internal/common/serve"
"github.com/armadaproject/armada/internal/lookoutv2"
"github.com/armadaproject/armada/internal/lookoutv2/configuration"
"github.com/armadaproject/armada/internal/lookoutv2/gen/restapi"
Expand Down Expand Up @@ -127,14 +125,9 @@ func main() {
common.LoadConfig(&config, "./config/lookoutv2", userSpecifiedConfigs)

// Expose profiling endpoints if enabled.
if config.PprofPort != nil {
pprofServer := profiling.SetupPprofHttpServer(*config.PprofPort)
go func() {
ctx := armadacontext.Background()
if err := serve.ListenAndServe(ctx, pprofServer); err != nil {
logging.WithStacktrace(ctx, err).Error("pprof server failure")
}
}()
err := profiling.SetupPprof(config.Profiling, armadacontext.Background(), nil)
if err != nil {
log.Fatalf("Pprof setup failed, exiting, %v", err)
}

log.SetLevel(log.DebugLevel)
Expand Down
4 changes: 2 additions & 2 deletions deployment/armada/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ spec:
- containerPort: {{ .Values.applicationConfig.httpPort }}
protocol: TCP
name: rest
{{- if .Values.applicationConfig.pprofPort }}
- containerPort: {{ .Values.applicationConfig.pprofPort }}
{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
- containerPort: {{ .Values.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
4 changes: 2 additions & 2 deletions deployment/binoculars/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ spec:
- containerPort: {{ .Values.applicationConfig.httpPort }}
protocol: TCP
name: web
{{- if .Values.applicationConfig.pprofPort }}
- containerPort: {{ .Values.applicationConfig.pprofPort }}
{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
- containerPort: {{ .Values.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
4 changes: 2 additions & 2 deletions deployment/event-ingester/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ spec:
resources:
{{- toYaml .Values.resources | nindent 12 }}
ports:
{{- if .Values.applicationConfig.pprofPort }}
- containerPort: {{ .Values.applicationConfig.pprofPort }}
{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
- containerPort: {{ .Values.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
4 changes: 2 additions & 2 deletions deployment/executor/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ spec:
- containerPort: 9001
protocol: TCP
name: metrics
{{- if .Values.applicationConfig.pprofPort }}
- containerPort: {{ .Values.applicationConfig.pprofPort }}
{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
- containerPort: {{ .Values.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
4 changes: 2 additions & 2 deletions deployment/lookout-ingester-v2/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ spec:
resources:
{{- toYaml .Values.resources | nindent 12 }}
ports:
{{- if .Values.applicationConfig.pprofPort }}
- containerPort: {{ .Values.applicationConfig.pprofPort }}
{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
- containerPort: {{ .Values.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
4 changes: 2 additions & 2 deletions deployment/lookout-v2/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ spec:
- containerPort: {{ .Values.applicationConfig.apiPort }}
protocol: TCP
name: web
{{- if .Values.applicationConfig.pprofPort }}
- containerPort: {{ .Values.applicationConfig.pprofPort }}
{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
- containerPort: {{ .Values.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ spec:
resources:
{{- toYaml .Values.ingester.resources | nindent 12 }}
ports:
{{- if .Values.ingester.applicationConfig.pprofPort }}
- containerPort: {{ .Values.ingester.applicationConfig.pprofPort }}
{{- if and .Values.ingester.applicationConfig.profiling .Values.ingester.applicationConfig.profiling.port }}
- containerPort: {{ .Values.ingester.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
4 changes: 2 additions & 2 deletions deployment/scheduler/templates/scheduler-statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ spec:
- containerPort: {{ .Values.scheduler.applicationConfig.metrics.port }}
protocol: TCP
name: metrics
{{- if .Values.scheduler.applicationConfig.pprofPort }}
- containerPort: {{ .Values.scheduler.applicationConfig.pprofPort }}
{{- if and .Values.scheduler.applicationConfig.profiling .Values.scheduler.applicationConfig.profiling.port }}
- containerPort: {{ .Values.scheduler.applicationConfig.profiling.port }}
protocol: TCP
name: pprof
{{- end }}
Expand Down
14 changes: 14 additions & 0 deletions docs/developer/pprof.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Use of pprof

- Go provides a profiling tool called pprof. It's documented at https://pkg.go.dev/net/http/pprof.
- If you wish to use this with Armada, enable the profiling socket with the following config (this should be under `applicationConfig` if using the helm charts). This config will listen on the specified port with no auth.
```
profiling:
port: 6060
auth:
anonymousAuth: true
permissionGroupMapping:
pprof: ["everyone"]
```
- It's possible to put pprof behind auth if you want, see [api.md#authentication](./api.md#authentication) and [oidc.md](./oidc.md).
- The helm charts do not currently expose the profiling port via a service and ingress. You can use `kubectl port-forward` to access them.
4 changes: 2 additions & 2 deletions internal/armada/configuration/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

authconfig "github.com/armadaproject/armada/internal/common/auth/configuration"
grpcconfig "github.com/armadaproject/armada/internal/common/grpc/configuration"
profilingconfig "github.com/armadaproject/armada/internal/common/profiling/configuration"
armadaresource "github.com/armadaproject/armada/internal/common/resource"
"github.com/armadaproject/armada/pkg/client"
)
Expand All @@ -19,8 +20,7 @@ type ArmadaConfig struct {
GrpcPort uint16
HttpPort uint16
MetricsPort uint16
// If non-nil, net/http/pprof endpoints are exposed on localhost on this port.
PprofPort *uint16
Profiling *profilingconfig.ProfilingConfig

CorsAllowedOrigins []string
GrpcGatewayPath string
Expand Down
6 changes: 3 additions & 3 deletions internal/armada/event/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ func TestEventServer_GetJobSetEvents_Permissions(t *testing.T) {
err := s.queueRepository.(armadaqueue.QueueRepository).CreateQueue(ctx, q)
assert.NoError(t, err)

principal := auth.NewStaticPrincipal("alice", []string{})
principal := auth.NewStaticPrincipal("alice", "test", []string{})
ctx := auth.WithPrincipal(armadacontext.Background(), principal)
stream := &eventStreamMock{ctx: ctx}

Expand All @@ -351,7 +351,7 @@ func TestEventServer_GetJobSetEvents_Permissions(t *testing.T) {
err := s.queueRepository.(armadaqueue.QueueRepository).CreateQueue(ctx, q)
assert.NoError(t, err)

principal := auth.NewStaticPrincipal("alice", []string{"watch-all-events-group"})
principal := auth.NewStaticPrincipal("alice", "test", []string{"watch-all-events-group"})
ctx := auth.WithPrincipal(armadacontext.Background(), principal)
stream := &eventStreamMock{ctx: ctx}

Expand All @@ -373,7 +373,7 @@ func TestEventServer_GetJobSetEvents_Permissions(t *testing.T) {
err := s.queueRepository.(armadaqueue.QueueRepository).CreateQueue(ctx, q)
assert.NoError(t, err)

principal := auth.NewStaticPrincipal("alice", []string{"watch-events-group", "watch-queue-group"})
principal := auth.NewStaticPrincipal("alice", "test", []string{"watch-events-group", "watch-queue-group"})
ctx := auth.WithPrincipal(armadacontext.Background(), principal)
stream := &eventStreamMock{ctx: ctx}

Expand Down
2 changes: 1 addition & 1 deletion internal/armada/submit/testfixtures/test_fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var (
DefaultOwner = "testUser"
DefaultJobset = "testJobset"
DefaultQueue = queue.Queue{Name: "testQueue"}
DefaultPrincipal = auth.NewStaticPrincipal(DefaultOwner, []string{"groupA"})
DefaultPrincipal = auth.NewStaticPrincipal(DefaultOwner, "test", []string{"groupA"})
DefaultContainerPort = v1.ContainerPort{
Name: "testContainerPort",
ContainerPort: 8080,
Expand Down
4 changes: 2 additions & 2 deletions internal/binoculars/configuration/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package configuration
import (
"github.com/armadaproject/armada/internal/common/auth/configuration"
grpcconfig "github.com/armadaproject/armada/internal/common/grpc/configuration"
profilingconfig "github.com/armadaproject/armada/internal/common/profiling/configuration"
)

type BinocularsConfig struct {
Expand All @@ -12,8 +13,7 @@ type BinocularsConfig struct {
GrpcPort uint16
HttpPort uint16
MetricsPort uint16
// If non-nil, net/http/pprof endpoints are exposed on localhost on this port.
PprofPort *uint16
Profiling *profilingconfig.ProfilingConfig

CorsAllowedOrigins []string

Expand Down
2 changes: 1 addition & 1 deletion internal/binoculars/service/cordon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var (
)

func TestCordonNode(t *testing.T) {
principal := auth.NewStaticPrincipal("principle", []string{})
principal := auth.NewStaticPrincipal("principle", "test", []string{})
tests := map[string]struct {
additionalLabels map[string]string
expectedLabels map[string]string
Expand Down
9 changes: 5 additions & 4 deletions internal/common/auth/anonymous.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package auth

import "context"

const AnonymousAuthServiceName = "Anonymous"

type AnonymousAuthService struct{}

func (authService *AnonymousAuthService) Name() string {
return "Anonymous"
}
// Default principal used if no principal can be found in a context.
var anonymousPrincipal = NewStaticPrincipal("anonymous", AnonymousAuthServiceName, []string{})

func (AnonymousAuthService) Authenticate(ctx context.Context) (Principal, error) {
func (AnonymousAuthService) Authenticate(ctx context.Context, authHeader string) (Principal, error) {
return anonymousPrincipal, nil
}
4 changes: 2 additions & 2 deletions internal/common/auth/authorization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ func TestAuthorizer_AuthorizeQueueAction(t *testing.T) {
PriorityFactor: 1,
}

authorizedPrincipal := NewStaticPrincipal("alice", []string{"submit-job-group"})
unauthorizedPrincipcal := NewStaticPrincipal("alice", []string{})
authorizedPrincipal := NewStaticPrincipal("alice", "test", []string{"submit-job-group"})
unauthorizedPrincipcal := NewStaticPrincipal("alice", "test", []string{})

tests := map[string]struct {
ctx *armadacontext.Context
Expand Down
Loading

0 comments on commit dc817c5

Please sign in to comment.