RPC server EnableDebug option

Passes in agent enable_debug config to nomad server and client configs.
This allows for rpc endpoints to have more granular control if they
should be enabled or not in combination with ACLs.

enable debug on client test
This commit is contained in:
Drew Bailey
2019-12-13 13:41:55 -05:00
parent 588b34c09f
commit d77b5add6c
7 changed files with 71 additions and 6 deletions

View File

@@ -31,14 +31,22 @@ func NewAgentEndpoint(c *Client) *Agent {
func (a *Agent) Profile(args *structs.AgentPprofRequest, reply *structs.AgentPprofResponse) error {
// Check ACL for agent write
if aclObj, err := a.c.ResolveToken(args.AuthToken); err != nil {
aclObj, err := a.c.ResolveToken(args.AuthToken)
if err != nil {
return err
} else if aclObj != nil && !aclObj.AllowAgentWrite() {
return structs.ErrPermissionDenied
}
// If ACLs are disabled, EnableDebug must be enabled
if aclObj == nil {
enableDebug := a.c.config.EnableDebug
if enableDebug == false {
return structs.ErrPermissionDenied
}
}
var resp []byte
var err error
var headers map[string]string
// Determine which profile to run and generate profile.

View File

@@ -215,6 +215,33 @@ func TestMonitor_Monitor_ACL(t *testing.T) {
}
}
// Test that by default with no acl, endpoint is disabled
func TestAgentProfile_DefaultDisabled(t *testing.T) {
t.Parallel()
require := require.New(t)
// start server and client
s1, cleanup := nomad.TestServer(t, nil)
defer cleanup()
testutil.WaitForLeader(t, s1.RPC)
c, cleanupC := TestClient(t, func(c *config.Config) {
c.Servers = []string{s1.GetConfig().RPCAddr.String()}
})
defer cleanupC()
req := structs.AgentPprofRequest{
ReqType: profile.CPUReq,
NodeID: c.NodeID(),
}
reply := structs.AgentPprofResponse{}
err := c.ClientRPC("Agent.Profile", &req, &reply)
require.EqualError(err, structs.ErrPermissionDenied.Error())
}
func TestAgentProfile(t *testing.T) {
t.Parallel()
require := require.New(t)
@@ -227,6 +254,7 @@ func TestAgentProfile(t *testing.T) {
c, cleanupC := TestClient(t, func(c *config.Config) {
c.Servers = []string{s1.GetConfig().RPCAddr.String()}
c.EnableDebug = true
})
defer cleanupC()

View File

@@ -71,6 +71,10 @@ type Config struct {
// avoids persistent storage.
DevMode bool
// EnableDebug is used to enable debugging RPC endpoints
// in the absence of ACLs
EnableDebug bool
// StateDir is where we store our state
StateDir string

View File

@@ -132,6 +132,8 @@ func convertServerConfig(agentConfig *Config) (*nomad.Config, error) {
conf = nomad.DefaultConfig()
}
conf.DevMode = agentConfig.DevMode
conf.EnableDebug = agentConfig.EnableDebug
conf.Build = agentConfig.Version.VersionNumber()
if agentConfig.Region != "" {
conf.Region = agentConfig.Region
@@ -433,6 +435,8 @@ func convertClientConfig(agentConfig *Config) (*clientconfig.Config, error) {
conf.Servers = agentConfig.Client.Servers
conf.LogLevel = agentConfig.LogLevel
conf.DevMode = agentConfig.DevMode
conf.EnableDebug = agentConfig.EnableDebug
if agentConfig.Region != "" {
conf.Region = agentConfig.Region
}

View File

@@ -61,15 +61,23 @@ func (a *Agent) Profile(args *structs.AgentPprofRequest, reply *structs.AgentPpr
}
// Check ACL for agent write
if aclObj, err := a.srv.ResolveToken(args.AuthToken); err != nil {
aclObj, err := a.srv.ResolveToken(args.AuthToken)
if err != nil {
return err
} else if aclObj != nil && !aclObj.AllowAgentWrite() {
return structs.ErrPermissionDenied
}
// If ACLs are disabled, EnableDebug must be enabled
if aclObj == nil {
enableDebug := a.srv.config.EnableDebug
if enableDebug == false {
return structs.ErrPermissionDenied
}
}
// Process the request on this server
var resp []byte
var err error
var headers map[string]string
// Determine which profile to run and generate profile.

View File

@@ -464,7 +464,9 @@ func TestAgentProfile_RemoteClient(t *testing.T) {
require := require.New(t)
// start server and client
s1, cleanup := TestServer(t, nil)
s1, cleanup := TestServer(t, func(c *Config) {
c.DevDisableBootstrap = true
})
defer cleanup()
s2, cleanup := TestServer(t, func(c *Config) {
@@ -478,6 +480,7 @@ func TestAgentProfile_RemoteClient(t *testing.T) {
c, cleanupC := client.TestClient(t, func(c *config.Config) {
c.Servers = []string{s2.GetConfig().RPCAddr.String()}
c.EnableDebug = true
})
defer cleanupC()
@@ -513,12 +516,14 @@ func TestAgentProfile_RemoteRegionMisMatch(t *testing.T) {
s1, cleanupS1 := TestServer(t, func(c *Config) {
c.NumSchedulers = 0
c.Region = "foo"
c.EnableDebug = true
})
defer cleanupS1()
s2, cleanup := TestServer(t, func(c *Config) {
c.NumSchedulers = 0
c.Region = "bar"
c.EnableDebug = true
})
defer cleanup()
@@ -555,6 +560,7 @@ func TestAgentProfile_RemoteRegion(t *testing.T) {
s2, cleanup := TestServer(t, func(c *Config) {
c.NumSchedulers = 0
c.Region = "bar"
c.EnableDebug = true
})
defer cleanup()
@@ -582,11 +588,14 @@ func TestAgentProfile_Server(t *testing.T) {
t.Parallel()
// start servers
s1, cleanup := TestServer(t, nil)
s1, cleanup := TestServer(t, func(c *Config) {
c.EnableDebug = true
})
defer cleanup()
s2, cleanup := TestServer(t, func(c *Config) {
c.DevDisableBootstrap = true
c.EnableDebug = true
})
defer cleanup()

View File

@@ -67,6 +67,10 @@ type Config struct {
// use of persistence or state.
DevMode bool
// EnableDebug is used to enable debugging RPC endpoints
// in the absence of ACLs
EnableDebug bool
// DevDisableBootstrap is used to disable bootstrap mode while
// in DevMode. This is largely used for testing.
DevDisableBootstrap bool