mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-11 02:41:12 +01:00
* license: update headers to IBM Corp. * `make proto` * update offset because source file changed Signed-off-by: Ryan Cragun <me@ryan.ec> Co-authored-by: Ryan Cragun <me@ryan.ec>
192 lines
5.8 KiB
TypeScript
192 lines
5.8 KiB
TypeScript
/**
|
|
* Copyright IBM Corp. 2016, 2025
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import Service from '@ember/service';
|
|
import { service } from '@ember/service';
|
|
import { sanitizePath } from 'core/utils/sanitize-path';
|
|
|
|
import type ApiService from 'vault/services/api';
|
|
import type AuthService from 'vault/services/auth';
|
|
import type NamespaceService from 'vault/services/namespace';
|
|
|
|
export interface PluginCatalogPlugin {
|
|
name: string;
|
|
type: string;
|
|
builtin: boolean;
|
|
version: string;
|
|
deprecation_status?: string;
|
|
oci_image?: string;
|
|
runtime?: string;
|
|
}
|
|
|
|
export interface PluginCatalogData {
|
|
detailed: Array<PluginCatalogPlugin>;
|
|
}
|
|
|
|
export interface EnhancedPluginCatalogData extends PluginCatalogData {
|
|
secret: Array<string>;
|
|
auth: Array<string>;
|
|
database: Array<string>;
|
|
}
|
|
|
|
export interface PluginCatalogResponse {
|
|
data: EnhancedPluginCatalogData | null;
|
|
error: boolean;
|
|
}
|
|
|
|
export interface PluginCatalogRawDataResponse {
|
|
data: {
|
|
secret: Array<PluginCatalogPlugin>;
|
|
auth: Array<PluginCatalogPlugin>;
|
|
database: Array<PluginCatalogPlugin>;
|
|
detailed: Array<PluginCatalogPlugin>;
|
|
} | null;
|
|
error: boolean;
|
|
}
|
|
|
|
export default class PluginCatalogService extends Service {
|
|
@service declare readonly api: ApiService;
|
|
@service declare readonly auth: AuthService;
|
|
@service declare readonly namespace: NamespaceService;
|
|
|
|
/**
|
|
* Fetches the plugin catalog from the Vault API
|
|
* Uses the API service middleware for authentication, namespacing, and error handling
|
|
* @returns Promise resolving to plugin catalog data and error state
|
|
*/
|
|
async fetchPluginCatalog(): Promise<PluginCatalogResponse> {
|
|
try {
|
|
const response = await this.api.sys.pluginsCatalogListPlugins({
|
|
headers: {
|
|
token: this.auth.currentToken,
|
|
namespace: sanitizePath(this.namespace.path),
|
|
},
|
|
});
|
|
|
|
if (response && response.detailed && Array.isArray(response.detailed) && response.detailed.length > 0) {
|
|
const detailedPlugins = response.detailed as PluginCatalogPlugin[];
|
|
|
|
const secretPlugins = detailedPlugins
|
|
.filter((plugin) => plugin.type === 'secret')
|
|
.map((plugin) => plugin.name);
|
|
|
|
const authPlugins = detailedPlugins
|
|
.filter((plugin) => plugin.type === 'auth')
|
|
.map((plugin) => plugin.name);
|
|
|
|
const databasePlugins = detailedPlugins
|
|
.filter((plugin) => plugin.type === 'database')
|
|
.map((plugin) => plugin.name);
|
|
|
|
return {
|
|
data: {
|
|
secret: secretPlugins,
|
|
auth: authPlugins,
|
|
database: databasePlugins,
|
|
detailed: detailedPlugins,
|
|
},
|
|
error: false,
|
|
};
|
|
}
|
|
|
|
return {
|
|
data: null,
|
|
error: true,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
data: null,
|
|
error: true,
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetches the plugin catalog from the Vault API and groups the data by plugin type
|
|
* Uses the API service middleware for authentication, namespacing, and error handling
|
|
* @returns Promise resolving to plugin catalog data and error state
|
|
*/
|
|
async getRawPluginCatalogData(): Promise<PluginCatalogRawDataResponse> {
|
|
try {
|
|
const response = await this.api.sys.pluginsCatalogListPlugins({
|
|
headers: {
|
|
token: this.auth.currentToken,
|
|
namespace: sanitizePath(this.namespace.path),
|
|
},
|
|
});
|
|
|
|
if (response && response.detailed && Array.isArray(response.detailed) && response.detailed.length > 0) {
|
|
const detailedPlugins = response.detailed as PluginCatalogPlugin[];
|
|
|
|
const secretPlugins = detailedPlugins.filter((plugin) => plugin.type === 'secret');
|
|
|
|
const authPlugins = detailedPlugins.filter((plugin) => plugin.type === 'auth');
|
|
|
|
const databasePlugins = detailedPlugins.filter((plugin) => plugin.type === 'database');
|
|
|
|
return {
|
|
data: {
|
|
secret: secretPlugins,
|
|
auth: authPlugins,
|
|
database: databasePlugins,
|
|
detailed: detailedPlugins,
|
|
},
|
|
error: false,
|
|
};
|
|
}
|
|
|
|
return {
|
|
data: null,
|
|
error: true,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
data: null,
|
|
error: true,
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets plugins of a specific type from the catalog
|
|
* @param type - The plugin type ('secret', 'auth', 'database')
|
|
* @returns Promise resolving to array of plugin names for the specified type
|
|
*/
|
|
async getPluginsByType(type: keyof Omit<EnhancedPluginCatalogData, 'detailed'>): Promise<Array<string>> {
|
|
const response = await this.fetchPluginCatalog();
|
|
return response.data?.[type] || [];
|
|
}
|
|
|
|
/**
|
|
* Gets detailed plugin information for all plugins
|
|
* @returns Promise resolving to array of detailed plugin objects
|
|
*/
|
|
async getDetailedPlugins(): Promise<Array<PluginCatalogPlugin>> {
|
|
const response = await this.fetchPluginCatalog();
|
|
return response.data?.detailed || [];
|
|
}
|
|
|
|
/**
|
|
* Gets detailed plugin information filtered by type
|
|
* @param type - The plugin type to filter by ('secret', 'auth', 'database')
|
|
* @returns Promise resolving to array of detailed plugin objects of the specified type
|
|
*/
|
|
async getDetailedPluginsByType(type: string): Promise<Array<PluginCatalogPlugin>> {
|
|
const response = await this.fetchPluginCatalog();
|
|
return response.data?.detailed.filter((plugin) => plugin.type === type) || [];
|
|
}
|
|
|
|
/**
|
|
* Gets a specific plugin by name and type
|
|
* @param name - The plugin name
|
|
* @param type - The plugin type ('secret', 'auth', 'database')
|
|
* @returns Promise resolving to the plugin object or undefined if not found
|
|
*/
|
|
async getPlugin(name: string, type: string): Promise<PluginCatalogPlugin | undefined> {
|
|
const response = await this.fetchPluginCatalog();
|
|
return response.data?.detailed.find((plugin) => plugin.name === name && plugin.type === type);
|
|
}
|
|
}
|