Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consul: include admin partition in JWT login requests #22226

Merged
merged 1 commit into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/22226.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
consul: Fixed a bug where Consul admin partition was not used to login via Consul JWT auth method
```
2 changes: 1 addition & 1 deletion client/allocrunner/alloc_runner_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (ar *allocRunner) initRunnerHooks(config *clientconfig.Config) error {
allocdir: ar.allocDir,
widmgr: ar.widmgr,
consulConfigs: ar.clientConfig.GetConsulConfigs(hookLogger),
consulClientConstructor: consul.NewConsulClient,
consulClientConstructor: consul.NewConsulClientFactory(config.Node),
hookResources: ar.hookResources,
envBuilder: newEnvBuilder,
logger: hookLogger,
Expand Down
4 changes: 2 additions & 2 deletions client/allocrunner/consul_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type consulHook struct {
allocdir allocdir.Interface
widmgr widmgr.IdentityManager
consulConfigs map[string]*structsc.ConsulConfig
consulClientConstructor func(*structsc.ConsulConfig, log.Logger) (consul.Client, error)
consulClientConstructor consul.ConsulClientFunc
hookResources *cstructs.AllocHookResources
envBuilder *taskenv.Builder

Expand All @@ -39,7 +39,7 @@ type consulHookConfig struct {
consulConfigs map[string]*structsc.ConsulConfig
// consulClientConstructor injects the function that will return a consul
// client (eases testing)
consulClientConstructor func(*structsc.ConsulConfig, log.Logger) (consul.Client, error)
consulClientConstructor consul.ConsulClientFunc

// hookResources is used for storing and retrieving Consul tokens
hookResources *cstructs.AllocHookResources
Expand Down
68 changes: 42 additions & 26 deletions client/consul/consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,43 +63,56 @@ type consulClient struct {
// client is the API client to interact with consul
client *consulapi.Client

// partition is the Consul partition for the local agent
partition string

// config is the configuration to connect to consul
config *config.ConsulConfig

logger hclog.Logger
}

// NewConsulClient creates a new Consul client
func NewConsulClient(config *config.ConsulConfig, logger hclog.Logger) (Client, error) {
if config == nil {
return nil, fmt.Errorf("nil consul config")
}
// ConsulClientFunc creates a new Consul client for the specific Consul config
type ConsulClientFunc func(config *config.ConsulConfig, logger hclog.Logger) (Client, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a nice refactoring 👌


logger = logger.Named("consul").With("name", config.Name)
// NewConsulClientFactory returns a ConsulClientFunc that closes over the
// partition
func NewConsulClientFactory(node *structs.Node) ConsulClientFunc {
partition := node.Attributes["consul.partition"]

c := &consulClient{
config: config,
logger: logger,
}
return func(config *config.ConsulConfig, logger hclog.Logger) (Client, error) {
if config == nil {
return nil, fmt.Errorf("nil consul config")
}

// Get the Consul API configuration
apiConf, err := config.ApiConfig()
if err != nil {
logger.Error("error creating default Consul API config", "error", err)
return nil, err
}
logger = logger.Named("consul").With("name", config.Name)

// Create the API client
client, err := consulapi.NewClient(apiConf)
if err != nil {
logger.Error("error creating Consul client", "error", err)
return nil, err
}
c := &consulClient{
config: config,
logger: logger,
partition: partition,
}

useragent.SetHeaders(client)
c.client = client
// Get the Consul API configuration
apiConf, err := config.ApiConfig()
if err != nil {
logger.Error("error creating default Consul API config", "error", err)
return nil, err
}

return c, nil
// Create the API client
client, err := consulapi.NewClient(apiConf)
if err != nil {
logger.Error("error creating Consul client", "error", err)
return nil, err
}

useragent.SetHeaders(client)
c.client = client

return c, nil

}
}

// DeriveTokenWithJWT takes a JWT from request and returns a consul token.
Expand All @@ -108,7 +121,10 @@ func (c *consulClient) DeriveTokenWithJWT(req JWTLoginRequest) (*consulapi.ACLTo
AuthMethod: req.AuthMethodName,
BearerToken: req.JWT,
Meta: req.Meta,
}, nil)
}, &consulapi.WriteOptions{
Partition: c.partition,
})

return t, err
}

Expand Down
Loading