-
Notifications
You must be signed in to change notification settings - Fork 710
Description
Some validation logic in fabric-ca-client is being executed based on the value of the first CLI argument, which is erroneously assumed to always be a subcommand, when it can be a flag instead. This can cause mystifying problems in some situations, especially given that the ability to place flags before the subcommand (as is conventionally expected of global flags) otherwise works as expected and is quite convenient for writing shell aliases.
Example
When running the enroll subcommand with an (unsurprisingly) empty MSP directory, the following error will be produced:
Error: Enrollment information does not exist. Please execute enroll command first. Example: fabric-ca-client enroll -u http://user:userpw@serverAddr:serverPort
This happens whenever any flag is positioned before the subcommand enroll, such as:
fabric-ca-client --loglevel warning enroll --url (...)
In this situation, the command will only succeed in two situations.
- If
enrollis the very first argument
fabric-ca-client enroll --loglevel warning --url (...)
- If the target MSP directory is already populated, so that the previously failing validation passes.
Relevant code
fabric-ca/cmd/fabric-ca-client/command/root.go
Lines 28 to 32 in 00f89fd
| cmdName := "" | |
| if len(args) > 1 { | |
| cmdName = args[1] | |
| } | |
| ccmd := NewCommand(cmdName) |
fabric-ca/cmd/fabric-ca-client/command/clientcmd.go
Lines 116 to 121 in 00f89fd
| func NewCommand(name string) *ClientCmd { | |
| c := &ClientCmd{ | |
| myViper: viper.New(), | |
| } | |
| c.name = strings.ToLower(name) | |
| c.init() |
fabric-ca/cmd/fabric-ca-client/command/clientcmd.go
Lines 243 to 254 in 00f89fd
| func (c *ClientCmd) requiresEnrollment() bool { | |
| return c.name != enroll && c.name != getcacert && c.name != getcainfo && c.name != gencsr | |
| } | |
| // Create default client configuration file only during an enroll or gencsr command | |
| func (c *ClientCmd) shouldCreateDefaultConfig() bool { | |
| return c.name == enroll || c.name == gencsr | |
| } | |
| func (c *ClientCmd) requiresUser() bool { | |
| return c.name != gencsr | |
| } |