Support registering plugin with name only (#5787)
* Support registering plugin with name only * Make RegisterPlugin backwards compatible * Add CLI backwards compat command to plugin info and deregister * Add server-side deprecation warnings if old read/dereg API endpoints are called * Address feedback
This commit is contained in:
parent
192c8b5c84
commit
e99957aed9
|
@ -129,8 +129,9 @@ type GetPluginResponse struct {
|
|||
SHA256 string `json:"sha256"`
|
||||
}
|
||||
|
||||
// GetPlugin retrieves information about the plugin.
|
||||
func (c *Sys) GetPlugin(i *GetPluginInput) (*GetPluginResponse, error) {
|
||||
path := fmt.Sprintf("/v1/sys/plugins/catalog/%s/%s", i.Type, i.Name)
|
||||
path := catalogPathByType(i.Type, i.Name)
|
||||
req := c.c.NewRequest(http.MethodGet, path)
|
||||
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
|
@ -142,13 +143,13 @@ func (c *Sys) GetPlugin(i *GetPluginInput) (*GetPluginResponse, error) {
|
|||
defer resp.Body.Close()
|
||||
|
||||
var result struct {
|
||||
Data GetPluginResponse
|
||||
Data *GetPluginResponse
|
||||
}
|
||||
err = resp.DecodeJSON(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result.Data, err
|
||||
return result.Data, err
|
||||
}
|
||||
|
||||
// RegisterPluginInput is used as input to the RegisterPlugin function.
|
||||
|
@ -171,8 +172,9 @@ type RegisterPluginInput struct {
|
|||
|
||||
// RegisterPlugin registers the plugin with the given information.
|
||||
func (c *Sys) RegisterPlugin(i *RegisterPluginInput) error {
|
||||
path := fmt.Sprintf("/v1/sys/plugins/catalog/%s/%s", i.Type, i.Name)
|
||||
path := catalogPathByType(i.Type, i.Name)
|
||||
req := c.c.NewRequest(http.MethodPut, path)
|
||||
|
||||
if err := req.SetJSONBody(i); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -198,7 +200,7 @@ type DeregisterPluginInput struct {
|
|||
// DeregisterPlugin removes the plugin with the given name from the plugin
|
||||
// catalog.
|
||||
func (c *Sys) DeregisterPlugin(i *DeregisterPluginInput) error {
|
||||
path := fmt.Sprintf("/v1/sys/plugins/catalog/%s/%s", i.Type, i.Name)
|
||||
path := catalogPathByType(i.Type, i.Name)
|
||||
req := c.c.NewRequest(http.MethodDelete, path)
|
||||
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
|
@ -209,3 +211,15 @@ func (c *Sys) DeregisterPlugin(i *DeregisterPluginInput) error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// catalogPathByType is a helper to construct the proper API path by plugin type
|
||||
func catalogPathByType(pluginType consts.PluginType, name string) string {
|
||||
path := fmt.Sprintf("/v1/sys/plugins/catalog/%s/%s", pluginType, name)
|
||||
|
||||
// Backwards compat, if type is not provided then use old path
|
||||
if pluginType == consts.PluginTypeUnknown {
|
||||
path = fmt.Sprintf("/v1/sys/plugins/catalog/%s", name)
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
|
|
@ -58,14 +58,23 @@ func (c *PluginDeregisterCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
var pluginNameRaw, pluginTypeRaw string
|
||||
args = f.Args()
|
||||
switch {
|
||||
case len(args) < 2:
|
||||
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 2, got %d)", len(args)))
|
||||
case len(args) < 1:
|
||||
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1 or 2, got %d)", len(args)))
|
||||
return 1
|
||||
case len(args) > 2:
|
||||
c.UI.Error(fmt.Sprintf("Too many arguments (expected 2, got %d)", len(args)))
|
||||
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1 or 2, got %d)", len(args)))
|
||||
return 1
|
||||
|
||||
// These cases should come after invalid cases have been checked
|
||||
case len(args) == 1:
|
||||
pluginTypeRaw = "unknown"
|
||||
pluginNameRaw = args[0]
|
||||
case len(args) == 2:
|
||||
pluginTypeRaw = args[0]
|
||||
pluginNameRaw = args[1]
|
||||
}
|
||||
|
||||
client, err := c.Client()
|
||||
|
@ -74,12 +83,12 @@ func (c *PluginDeregisterCommand) Run(args []string) int {
|
|||
return 2
|
||||
}
|
||||
|
||||
pluginType, err := consts.ParsePluginType(strings.TrimSpace(args[0]))
|
||||
pluginType, err := consts.ParsePluginType(strings.TrimSpace(pluginTypeRaw))
|
||||
if err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 2
|
||||
}
|
||||
pluginName := strings.TrimSpace(args[1])
|
||||
pluginName := strings.TrimSpace(pluginNameRaw)
|
||||
|
||||
if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{
|
||||
Name: pluginName,
|
||||
|
|
|
@ -58,14 +58,23 @@ func (c *PluginInfoCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
var pluginNameRaw, pluginTypeRaw string
|
||||
args = f.Args()
|
||||
switch {
|
||||
case len(args) < 2:
|
||||
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1, got %d)", len(args)))
|
||||
case len(args) < 1:
|
||||
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1 or 2, got %d)", len(args)))
|
||||
return 1
|
||||
case len(args) > 2:
|
||||
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args)))
|
||||
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1 or 2, got %d)", len(args)))
|
||||
return 1
|
||||
|
||||
// These cases should come after invalid cases have been checked
|
||||
case len(args) == 1:
|
||||
pluginTypeRaw = "unknown"
|
||||
pluginNameRaw = args[0]
|
||||
case len(args) == 2:
|
||||
pluginTypeRaw = args[0]
|
||||
pluginNameRaw = args[1]
|
||||
}
|
||||
|
||||
client, err := c.Client()
|
||||
|
@ -74,12 +83,12 @@ func (c *PluginInfoCommand) Run(args []string) int {
|
|||
return 2
|
||||
}
|
||||
|
||||
pluginType, err := consts.ParsePluginType(strings.TrimSpace(args[0]))
|
||||
pluginType, err := consts.ParsePluginType(strings.TrimSpace(pluginTypeRaw))
|
||||
if err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 2
|
||||
}
|
||||
pluginName := strings.TrimSpace(args[1])
|
||||
pluginName := strings.TrimSpace(pluginNameRaw)
|
||||
|
||||
resp, err := client.Sys().GetPlugin(&api.GetPluginInput{
|
||||
Name: pluginName,
|
||||
|
@ -90,6 +99,11 @@ func (c *PluginInfoCommand) Run(args []string) int {
|
|||
return 2
|
||||
}
|
||||
|
||||
if resp == nil {
|
||||
c.UI.Error(fmt.Sprintf("No value found for plugin %q", pluginName))
|
||||
return 2
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"args": resp.Args,
|
||||
"builtin": resp.Builtin,
|
||||
|
|
|
@ -96,17 +96,26 @@ func (c *PluginRegisterCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
var pluginNameRaw, pluginTypeRaw string
|
||||
args = f.Args()
|
||||
switch {
|
||||
case len(args) < 2:
|
||||
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 2, got %d)", len(args)))
|
||||
case len(args) < 1:
|
||||
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1 or 2, got %d)", len(args)))
|
||||
return 1
|
||||
case len(args) > 2:
|
||||
c.UI.Error(fmt.Sprintf("Too many arguments (expected 2, got %d)", len(args)))
|
||||
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1 or 2, got %d)", len(args)))
|
||||
return 1
|
||||
case c.flagSHA256 == "":
|
||||
c.UI.Error("SHA256 is required for all plugins, please provide -sha256")
|
||||
return 1
|
||||
|
||||
// These cases should come after invalid cases have been checked
|
||||
case len(args) == 1:
|
||||
pluginTypeRaw = "unknown"
|
||||
pluginNameRaw = args[0]
|
||||
case len(args) == 2:
|
||||
pluginTypeRaw = args[0]
|
||||
pluginNameRaw = args[1]
|
||||
}
|
||||
|
||||
client, err := c.Client()
|
||||
|
@ -115,12 +124,12 @@ func (c *PluginRegisterCommand) Run(args []string) int {
|
|||
return 2
|
||||
}
|
||||
|
||||
pluginType, err := consts.ParsePluginType(strings.TrimSpace(args[0]))
|
||||
pluginType, err := consts.ParsePluginType(strings.TrimSpace(pluginTypeRaw))
|
||||
if err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 2
|
||||
}
|
||||
pluginName := strings.TrimSpace(args[1])
|
||||
pluginName := strings.TrimSpace(pluginNameRaw)
|
||||
|
||||
command := c.flagCommand
|
||||
if command == "" {
|
||||
|
|
|
@ -54,6 +54,6 @@ func ParsePluginType(pluginType string) (PluginType, error) {
|
|||
case "secret":
|
||||
return PluginTypeSecrets, nil
|
||||
default:
|
||||
return PluginTypeUnknown, fmt.Errorf("%s is not a supported plugin type", pluginType)
|
||||
return PluginTypeUnknown, fmt.Errorf("%q is not a supported plugin type", pluginType)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -349,7 +349,17 @@ func (b *SystemBackend) handlePluginCatalogRead(ctx context.Context, req *logica
|
|||
return logical.ErrorResponse("missing plugin name"), nil
|
||||
}
|
||||
|
||||
pluginType, err := consts.ParsePluginType(d.Get("type").(string))
|
||||
pluginTypeStr := d.Get("type").(string)
|
||||
if pluginTypeStr == "" {
|
||||
// If the plugin type is not provided (i.e. the old
|
||||
// sys/plugins/catalog/:name endpoint is being requested) short-circuit here
|
||||
// and return a warning
|
||||
resp := &logical.Response{}
|
||||
resp.AddWarning(fmt.Sprintf("Deprecated API endpoint, cannot read plugin information from catalog for %q", pluginName))
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
pluginType, err := consts.ParsePluginType(pluginTypeStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -388,7 +398,20 @@ func (b *SystemBackend) handlePluginCatalogDelete(ctx context.Context, req *logi
|
|||
if pluginName == "" {
|
||||
return logical.ErrorResponse("missing plugin name"), nil
|
||||
}
|
||||
pluginType, err := consts.ParsePluginType(d.Get("type").(string))
|
||||
|
||||
var resp *logical.Response
|
||||
pluginTypeStr := d.Get("type").(string)
|
||||
if pluginTypeStr == "" {
|
||||
// If the plugin type is not provided (i.e. the old
|
||||
// sys/plugins/catalog/:name endpoint is being requested), set type to
|
||||
// unknown and let pluginCatalog.Delete proceed. It should handle
|
||||
// deregistering out of the old storage path (root of core/plugin-catalog)
|
||||
resp = new(logical.Response)
|
||||
resp.AddWarning(fmt.Sprintf("Deprecated API endpoint, cannot deregister plugin from catalog for %q", pluginName))
|
||||
pluginTypeStr = "unknown"
|
||||
}
|
||||
|
||||
pluginType, err := consts.ParsePluginType(pluginTypeStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -396,7 +419,7 @@ func (b *SystemBackend) handlePluginCatalogDelete(ctx context.Context, req *logi
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (b *SystemBackend) handlePluginReloadUpdate(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
|
|
Loading…
Reference in New Issue