mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 11:08:10 +00:00
Add deprecation status to plugin api and cli (#17077)
* api: Add deprecation status to plugin endpoints * cli: Add -detailed flag to `plugin list` * docs: Update plugin list/info docs
This commit is contained in:
@@ -36,6 +36,7 @@ type PluginDetails struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Version string `json:"version,omitempty"`
|
Version string `json:"version,omitempty"`
|
||||||
Builtin bool `json:"builtin"`
|
Builtin bool `json:"builtin"`
|
||||||
|
DeprecationStatus string `json:"deprecation_status,omitempty" mapstructure:"deprecation_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListPlugins wraps ListPluginsWithContext using context.Background.
|
// ListPlugins wraps ListPluginsWithContext using context.Background.
|
||||||
@@ -163,6 +164,7 @@ type GetPluginResponse struct {
|
|||||||
Command string `json:"command"`
|
Command string `json:"command"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
SHA256 string `json:"sha256"`
|
SHA256 string `json:"sha256"`
|
||||||
|
DeprecationStatus string `json:"deprecation_status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPlugin wraps GetPluginWithContext using context.Background.
|
// GetPlugin wraps GetPluginWithContext using context.Background.
|
||||||
|
|||||||
12
changelog/17077.txt
Normal file
12
changelog/17077.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
```release-note:change
|
||||||
|
plugins: `GET /sys/plugins/catalog/:type/:name` endpoint contains deprecation status for builtin plugins.
|
||||||
|
```
|
||||||
|
```release-note:change
|
||||||
|
plugins: `GET /sys/plugins/catalog/` endpoint contains deprecation status in `detailed` list.
|
||||||
|
```
|
||||||
|
```release-note:change
|
||||||
|
plugins: `plugin list` now accepts a `-detailed` flag, which display deprecation status and version info.
|
||||||
|
```
|
||||||
|
```release-note:change
|
||||||
|
plugins: `plugin info` displays deprecation status for builtin plugins.
|
||||||
|
```
|
||||||
@@ -112,6 +112,7 @@ func (c *PluginInfoCommand) Run(args []string) int {
|
|||||||
"command": resp.Command,
|
"command": resp.Command,
|
||||||
"name": resp.Name,
|
"name": resp.Name,
|
||||||
"sha256": resp.SHA256,
|
"sha256": resp.SHA256,
|
||||||
|
"deprecation_status": resp.DeprecationStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.flagField != "" {
|
if c.flagField != "" {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ var (
|
|||||||
|
|
||||||
type PluginListCommand struct {
|
type PluginListCommand struct {
|
||||||
*BaseCommand
|
*BaseCommand
|
||||||
|
|
||||||
|
flagDetailed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PluginListCommand) Synopsis() string {
|
func (c *PluginListCommand) Synopsis() string {
|
||||||
@@ -40,13 +42,30 @@ Usage: vault plugin list [options] [TYPE]
|
|||||||
|
|
||||||
$ vault plugin list database
|
$ vault plugin list database
|
||||||
|
|
||||||
|
List all available plugins with detailed output:
|
||||||
|
|
||||||
|
$ vault plugin list -detailed
|
||||||
|
|
||||||
` + c.Flags().Help()
|
` + c.Flags().Help()
|
||||||
|
|
||||||
return strings.TrimSpace(helpText)
|
return strings.TrimSpace(helpText)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PluginListCommand) Flags() *FlagSets {
|
func (c *PluginListCommand) Flags() *FlagSets {
|
||||||
return c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
|
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
|
||||||
|
|
||||||
|
f := set.NewFlagSet("Command Options")
|
||||||
|
|
||||||
|
f.BoolVar(&BoolVar{
|
||||||
|
Name: "detailed",
|
||||||
|
Target: &c.flagDetailed,
|
||||||
|
Default: false,
|
||||||
|
Usage: "Print detailed plugin information such as plugin type, " +
|
||||||
|
"version, and deprecation status for each plugin. This option " +
|
||||||
|
"is only applicable to table-formatted output.",
|
||||||
|
})
|
||||||
|
|
||||||
|
return set
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PluginListCommand) AutocompleteArgs() complete.Predictor {
|
func (c *PluginListCommand) AutocompleteArgs() complete.Predictor {
|
||||||
@@ -105,19 +124,11 @@ func (c *PluginListCommand) Run(args []string) int {
|
|||||||
|
|
||||||
switch Format(c.UI) {
|
switch Format(c.UI) {
|
||||||
case "table":
|
case "table":
|
||||||
var flattenedNames []string
|
if c.flagDetailed {
|
||||||
namesAdded := make(map[string]bool)
|
c.UI.Output(tableOutput(c.detailedResponse(resp), nil))
|
||||||
for _, names := range resp.PluginsByType {
|
return 0
|
||||||
for _, name := range names {
|
|
||||||
if ok := namesAdded[name]; !ok {
|
|
||||||
flattenedNames = append(flattenedNames, name)
|
|
||||||
namesAdded[name] = true
|
|
||||||
}
|
}
|
||||||
}
|
c.UI.Output(tableOutput(c.simpleResponse(resp), nil))
|
||||||
sort.Strings(flattenedNames)
|
|
||||||
}
|
|
||||||
list := append([]string{"Plugins"}, flattenedNames...)
|
|
||||||
c.UI.Output(tableOutput(list, nil))
|
|
||||||
return 0
|
return 0
|
||||||
default:
|
default:
|
||||||
res := make(map[string]interface{})
|
res := make(map[string]interface{})
|
||||||
@@ -127,3 +138,28 @@ func (c *PluginListCommand) Run(args []string) int {
|
|||||||
return OutputData(c.UI, res)
|
return OutputData(c.UI, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *PluginListCommand) simpleResponse(plugins *api.ListPluginsResponse) []string {
|
||||||
|
var flattenedNames []string
|
||||||
|
namesAdded := make(map[string]bool)
|
||||||
|
for _, names := range plugins.PluginsByType {
|
||||||
|
for _, name := range names {
|
||||||
|
if ok := namesAdded[name]; !ok {
|
||||||
|
flattenedNames = append(flattenedNames, name)
|
||||||
|
namesAdded[name] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(flattenedNames)
|
||||||
|
}
|
||||||
|
list := append([]string{"Plugins"}, flattenedNames...)
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PluginListCommand) detailedResponse(plugins *api.ListPluginsResponse) []string {
|
||||||
|
out := []string{"Name | Type | Version | Deprecation Status"}
|
||||||
|
for _, plugin := range plugins.Details {
|
||||||
|
out = append(out, fmt.Sprintf("%s | %s | %s | %s", plugin.Name, plugin.Type, plugin.Version, plugin.DeprecationStatus))
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ type VersionedPlugin struct {
|
|||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
SHA256 string `json:"sha256,omitempty"`
|
SHA256 string `json:"sha256,omitempty"`
|
||||||
Builtin bool `json:"builtin"`
|
Builtin bool `json:"builtin"`
|
||||||
|
DeprecationStatus string `json:"deprecation_status,omitempty"`
|
||||||
|
|
||||||
// Pre-parsed semver struct of the Version field
|
// Pre-parsed semver struct of the Version field
|
||||||
SemanticVersion *version.Version `json:"-"`
|
SemanticVersion *version.Version `json:"-"`
|
||||||
|
|||||||
@@ -572,6 +572,11 @@ func (b *SystemBackend) handlePluginCatalogRead(ctx context.Context, _ *logical.
|
|||||||
"version": plugin.Version,
|
"version": plugin.Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if plugin.Builtin {
|
||||||
|
status, _ := b.Core.builtinRegistry.DeprecationStatus(plugin.Name, plugin.Type)
|
||||||
|
data["deprecation_status"] = status.String()
|
||||||
|
}
|
||||||
|
|
||||||
return &logical.Response{
|
return &logical.Response{
|
||||||
Data: data,
|
Data: data,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -2989,6 +2989,9 @@ func TestSystemBackend_PluginCatalog_CRUD(t *testing.T) {
|
|||||||
t.Fatalf("err: %v", err)
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get deprecation status directly from the registry so we can compare it to the API response
|
||||||
|
deprecationStatus, _ := c.builtinRegistry.DeprecationStatus("mysql-database-plugin", consts.PluginTypeDatabase)
|
||||||
|
|
||||||
actualRespData := resp.Data
|
actualRespData := resp.Data
|
||||||
expectedRespData := map[string]interface{}{
|
expectedRespData := map[string]interface{}{
|
||||||
"name": "mysql-database-plugin",
|
"name": "mysql-database-plugin",
|
||||||
@@ -2997,6 +3000,7 @@ func TestSystemBackend_PluginCatalog_CRUD(t *testing.T) {
|
|||||||
"sha256": "",
|
"sha256": "",
|
||||||
"builtin": true,
|
"builtin": true,
|
||||||
"version": c.pluginCatalog.getBuiltinVersion(consts.PluginTypeDatabase, "mysql-database-plugin"),
|
"version": c.pluginCatalog.getBuiltinVersion(consts.PluginTypeDatabase, "mysql-database-plugin"),
|
||||||
|
"deprecation_status": deprecationStatus.String(),
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(actualRespData, expectedRespData) {
|
if !reflect.DeepEqual(actualRespData, expectedRespData) {
|
||||||
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actualRespData, expectedRespData)
|
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actualRespData, expectedRespData)
|
||||||
|
|||||||
@@ -853,6 +853,7 @@ func (c *PluginCatalog) listInternal(ctx context.Context, pluginType consts.Plug
|
|||||||
|
|
||||||
version := c.getBuiltinVersion(pluginType, plugin)
|
version := c.getBuiltinVersion(pluginType, plugin)
|
||||||
semanticVersion, err := semver.NewVersion(version)
|
semanticVersion, err := semver.NewVersion(version)
|
||||||
|
deprecationStatus, _ := c.builtinRegistry.DeprecationStatus(plugin, pluginType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -862,6 +863,7 @@ func (c *PluginCatalog) listInternal(ctx context.Context, pluginType consts.Plug
|
|||||||
Version: version,
|
Version: version,
|
||||||
Builtin: true,
|
Builtin: true,
|
||||||
SemanticVersion: semanticVersion,
|
SemanticVersion: semanticVersion,
|
||||||
|
DeprecationStatus: deprecationStatus.String(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ description: The "plugin info" command displays information about a plugin in th
|
|||||||
The `plugin info` displays information about a plugin in the catalog.
|
The `plugin info` displays information about a plugin in the catalog.
|
||||||
The plugin's type of "auth", "database", or "secret" must be included.
|
The plugin's type of "auth", "database", or "secret" must be included.
|
||||||
|
|
||||||
|
## deprecation_status field
|
||||||
|
|
||||||
|
As of 1.12, all builtin plugins will have an associated Deprecation
|
||||||
|
Status. This status will be reflected in the `deprecation_status` key/value
|
||||||
|
pair, seen below.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Display information about a plugin
|
Display information about a plugin
|
||||||
@@ -21,10 +27,23 @@ Key Value
|
|||||||
args []
|
args []
|
||||||
builtin false
|
builtin false
|
||||||
command my-custom-plugin
|
command my-custom-plugin
|
||||||
|
deprecation_status n/a
|
||||||
name my-custom-plugin
|
name my-custom-plugin
|
||||||
sha256 d3f0a8be02f6c074cf38c9c99d4d04c9c6466249
|
sha256 d3f0a8be02f6c074cf38c9c99d4d04c9c6466249
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault plugin info database postgresql-database-plugin
|
||||||
|
Key Value
|
||||||
|
--- -----
|
||||||
|
args []
|
||||||
|
builtin true
|
||||||
|
command n/a
|
||||||
|
deprecation_status supported
|
||||||
|
name postgresql-database-plugin
|
||||||
|
sha256 n/a
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The following flags are available in addition to the [standard set of
|
The following flags are available in addition to the [standard set of
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ description: The "plugin list" command lists all available plugins in the plugin
|
|||||||
The `plugin list` command lists all available plugins in the plugin catalog.
|
The `plugin list` command lists all available plugins in the plugin catalog.
|
||||||
It can be used alone or with a type such as "auth", "database", or "secret".
|
It can be used alone or with a type such as "auth", "database", or "secret".
|
||||||
|
|
||||||
|
## Deprecation Status Column
|
||||||
|
|
||||||
|
As of 1.12, all builtin plugins will have an associated Deprecation
|
||||||
|
Status. This status will be reflected in the `Deprecation Status` column, seen
|
||||||
|
below. All non-builtin plugins will show a `Deprecation Status` of "n/a".
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
List all available plugins in the catalog.
|
List all available plugins in the catalog.
|
||||||
@@ -28,6 +34,16 @@ cassandra-database-plugin
|
|||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
List detailed plugin information:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault plugin list -detailed
|
||||||
|
Name Type Version Deprecation Status
|
||||||
|
---- ---- ------- ------------------
|
||||||
|
alicloud auth v0.12.0+builtin supported
|
||||||
|
app-id auth v1.12.0+builtin.vault pending removal
|
||||||
|
# ...
|
||||||
|
```
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The following flags are available in addition to the [standard set of
|
The following flags are available in addition to the [standard set of
|
||||||
@@ -38,3 +54,8 @@ flags](/docs/commands) included on all commands.
|
|||||||
- `-format` `(string: "table")` - Print the output in the given format. Valid
|
- `-format` `(string: "table")` - Print the output in the given format. Valid
|
||||||
formats are "table", "json", or "yaml". This can also be specified via the
|
formats are "table", "json", or "yaml". This can also be specified via the
|
||||||
`VAULT_FORMAT` environment variable.
|
`VAULT_FORMAT` environment variable.
|
||||||
|
|
||||||
|
### Command Options
|
||||||
|
|
||||||
|
- `-detailed` `(bool: false)` - Print detailed information such as version and
|
||||||
|
deprecation status about each plugin.
|
||||||
|
|||||||
Reference in New Issue
Block a user