diff --git a/.changeset/cost-insights-rich-dodos-smell.md b/.changeset/cost-insights-rich-dodos-smell.md new file mode 100644 index 0000000000..a579797437 --- /dev/null +++ b/.changeset/cost-insights-rich-dodos-smell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +expose alerts utilities for export diff --git a/plugins/cost-insights/src/api/CostInsightsApi.ts b/plugins/cost-insights/src/api/CostInsightsApi.ts index be5cd54fdb..bedbf8319d 100644 --- a/plugins/cost-insights/src/api/CostInsightsApi.ts +++ b/plugins/cost-insights/src/api/CostInsightsApi.ts @@ -26,6 +26,34 @@ import { MetricData, } from '../types'; +export type ProductInsightsOptions = { + /** + * The product from the cost-insights configuration in app-config.yaml + */ + product: string; + + /** + * The group id from getUserGroups or query parameters + */ + group: string; + + /** + * A time duration, such as P1M. See the Duration type for a detailed explanation + * of how the durations are interpreted in Cost Insights. + */ + duration: Duration; + + /** + * The most current date for which billing data is complete, in YYYY-MM-DD format. + */ + lastCompleteBillingDate: string; + + /** + * (optional) The project id from getGroupProjects or query parameters + */ + project: Maybe; +}; + export type CostInsightsApi = { /** * Get the most current date for which billing data is complete, in YYYY-MM-DD format. This helps @@ -108,19 +136,9 @@ export type CostInsightsApi = { * The time period is supplied as a Duration rather than intervals, since this is always expected * to return data for two bucketed time period (e.g. month vs month, or quarter vs quarter). * - * @param product The product from the cost-insights configuration in app-config.yaml - * @param group - * @param duration A time duration, such as P1M. See the Duration type for a detailed explanation - * of how the durations are interpreted in Cost Insights. - * @param project (optional) The project id from getGroupProjects or query parameters + * @param options Options to use when fetching insights for a particular cloud product and interval timeframe. */ - getProductInsights( - product: string, - group: string, - duration: Duration, - project: Maybe, - ): Promise; - + getProductInsights(options: ProductInsightsOptions): Promise; /** * Get current cost alerts for a given group. These show up as Action Items for the group on the * Cost Insights page. Alerts may include cost-saving recommendations, such as infrastructure diff --git a/plugins/cost-insights/src/client.ts b/plugins/cost-insights/src/client.ts index f7671bcce0..1fa57c624a 100644 --- a/plugins/cost-insights/src/client.ts +++ b/plugins/cost-insights/src/client.ts @@ -17,7 +17,7 @@ import dayjs from 'dayjs'; import regression, { DataPoint } from 'regression'; -import { CostInsightsApi } from '../src/api'; +import { CostInsightsApi, ProductInsightsOptions } from '../src/api'; import { Alert, ChangeStatistic, @@ -26,7 +26,6 @@ import { DEFAULT_DATE_FORMAT, Duration, Group, - Maybe, MetricData, ProductCost, Project, @@ -194,41 +193,35 @@ export class ExampleCostInsightsClient implements CostInsightsApi { } async getProductInsights( - product: string, - group: string, - duration: Duration, - project: Maybe, + productInsightsOptions: ProductInsightsOptions, ): Promise { - const projectProductInsights = await this.request( - { product, group, duration, project }, - { - aggregation: [80_000, 110_000], - change: { - ratio: 0.375, - amount: 30_000, - }, - entities: [ - { - id: null, // entities with null ids will be appear as "Unlabeled" in product panels - aggregation: [45_000, 50_000], - }, - { - id: 'entity-a', - aggregation: [15_000, 20_000], - }, - { - id: 'entity-b', - aggregation: [20_000, 30_000], - }, - { - id: 'entity-e', - aggregation: [0, 10_000], - }, - ], + const projectProductInsights = await this.request(productInsightsOptions, { + aggregation: [80_000, 110_000], + change: { + ratio: 0.375, + amount: 30_000, }, - ); + entities: [ + { + id: null, // entities with null ids will be appear as "Unlabeled" in product panels + aggregation: [45_000, 50_000], + }, + { + id: 'entity-a', + aggregation: [15_000, 20_000], + }, + { + id: 'entity-b', + aggregation: [20_000, 30_000], + }, + { + id: 'entity-e', + aggregation: [0, 10_000], + }, + ], + }); const productInsights: ProductCost = await this.request( - { product, group, duration, project }, + productInsightsOptions, { aggregation: [200_000, 250_000], change: { @@ -276,7 +269,9 @@ export class ExampleCostInsightsClient implements CostInsightsApi { }, ); - return project ? projectProductInsights : productInsights; + return productInsightsOptions.project + ? projectProductInsights + : productInsights; } async getAlerts(group: string): Promise { diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx index 840c99522a..17b1624c05 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx @@ -82,12 +82,13 @@ export const ProductInsightsCard = ({ product }: ProductInsightsCardProps) => { async function load() { if (loadingProduct) { try { - const p: ProductCost = await client.getProductInsights( - product.kind, - group!, - productFilter!.duration, + const p: ProductCost = await client.getProductInsights({ + product: product.kind, + group: group!, + duration: productFilter!.duration, + lastCompleteBillingDate, project, - ); + }); setResource(p); } catch (e) { setError(e); @@ -107,6 +108,7 @@ export const ProductInsightsCard = ({ product }: ProductInsightsCardProps) => { group, product.kind, project, + lastCompleteBillingDate, ]); const onPeriodSelect = (duration: Duration) => { diff --git a/plugins/cost-insights/src/index.ts b/plugins/cost-insights/src/index.ts index 1e6172d568..28bdb1a8b3 100644 --- a/plugins/cost-insights/src/index.ts +++ b/plugins/cost-insights/src/index.ts @@ -22,3 +22,4 @@ export { useCurrency } from './hooks'; export * from './types'; export * from './utils/tests'; export * from './utils/duration'; +export * from './utils/alerts';