From cff0a558e5f0cee605963a32892e3adad5f9cea6 Mon Sep 17 00:00:00 2001 From: Brenda Sukh Date: Tue, 3 Nov 2020 13:52:39 -0500 Subject: [PATCH 1/5] Expose alerts for internal use --- plugins/cost-insights/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/cost-insights/src/index.ts b/plugins/cost-insights/src/index.ts index 1e6172d568..cefdefb9c9 100644 --- a/plugins/cost-insights/src/index.ts +++ b/plugins/cost-insights/src/index.ts @@ -18,7 +18,8 @@ export { plugin } from './plugin'; export * from './client'; export * from './api'; export * from './components'; -export { useCurrency } from './hooks'; +export { useCurrency, CurrencyContext } from './hooks'; export * from './types'; export * from './utils/tests'; export * from './utils/duration'; +export * from './utils/alerts'; From 02f3e571ade91ce49aca0def49df3b70e5b3a2d7 Mon Sep 17 00:00:00 2001 From: Brenda Sukh Date: Tue, 3 Nov 2020 13:52:57 -0500 Subject: [PATCH 2/5] Make lastBillingDate a param for product insights --- plugins/cost-insights/src/api/CostInsightsApi.ts | 2 ++ plugins/cost-insights/src/client.ts | 3 ++- .../src/components/ProductInsightsCard/ProductInsightsCard.tsx | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/cost-insights/src/api/CostInsightsApi.ts b/plugins/cost-insights/src/api/CostInsightsApi.ts index be5cd54fdb..a9048dedb8 100644 --- a/plugins/cost-insights/src/api/CostInsightsApi.ts +++ b/plugins/cost-insights/src/api/CostInsightsApi.ts @@ -112,12 +112,14 @@ export type CostInsightsApi = { * @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 lastBillingDate The most current date for which billing data is complete, in YYYY-MM-DD format. * @param project (optional) The project id from getGroupProjects or query parameters */ getProductInsights( product: string, group: string, duration: Duration, + lastBillingDate: string, project: Maybe, ): Promise; diff --git a/plugins/cost-insights/src/client.ts b/plugins/cost-insights/src/client.ts index f7671bcce0..69822d7a63 100644 --- a/plugins/cost-insights/src/client.ts +++ b/plugins/cost-insights/src/client.ts @@ -197,10 +197,11 @@ export class ExampleCostInsightsClient implements CostInsightsApi { product: string, group: string, duration: Duration, + lastBillingDate: string, project: Maybe, ): Promise { const projectProductInsights = await this.request( - { product, group, duration, project }, + { product, group, duration, lastBillingDate, project }, { aggregation: [80_000, 110_000], change: { diff --git a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx index 840c99522a..abf56d91db 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx @@ -86,6 +86,7 @@ export const ProductInsightsCard = ({ product }: ProductInsightsCardProps) => { product.kind, group!, productFilter!.duration, + lastCompleteBillingDate, project, ); setResource(p); @@ -107,6 +108,7 @@ export const ProductInsightsCard = ({ product }: ProductInsightsCardProps) => { group, product.kind, project, + lastCompleteBillingDate, ]); const onPeriodSelect = (duration: Duration) => { From 522132e5e8a9c2d9b0aaef9634cc9cac8cb945e9 Mon Sep 17 00:00:00 2001 From: Brenda Sukh Date: Tue, 3 Nov 2020 13:53:05 -0500 Subject: [PATCH 3/5] Add changeset --- .changeset/rich-dodos-smell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rich-dodos-smell.md diff --git a/.changeset/rich-dodos-smell.md b/.changeset/rich-dodos-smell.md new file mode 100644 index 0000000000..a579797437 --- /dev/null +++ b/.changeset/rich-dodos-smell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +expose alerts utilities for export From db3d03228350f97cde1925ca7add53f2ddd1eeab Mon Sep 17 00:00:00 2001 From: Brenda Sukh Date: Tue, 3 Nov 2020 15:25:01 -0500 Subject: [PATCH 4/5] Update getProductInsights to accept a single object with fields --- .../cost-insights/src/api/CostInsightsApi.ts | 44 +++++++++---- plugins/cost-insights/src/client.ts | 66 +++++++++---------- .../ProductInsightsCard.tsx | 10 +-- plugins/cost-insights/src/index.ts | 2 +- 4 files changed, 66 insertions(+), 56 deletions(-) diff --git a/plugins/cost-insights/src/api/CostInsightsApi.ts b/plugins/cost-insights/src/api/CostInsightsApi.ts index a9048dedb8..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,21 +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 lastBillingDate The most current date for which billing data is complete, in YYYY-MM-DD format. - * @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, - lastBillingDate: string, - 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 69822d7a63..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,42 +193,35 @@ export class ExampleCostInsightsClient implements CostInsightsApi { } async getProductInsights( - product: string, - group: string, - duration: Duration, - lastBillingDate: string, - project: Maybe, + productInsightsOptions: ProductInsightsOptions, ): Promise { - const projectProductInsights = await this.request( - { product, group, duration, lastBillingDate, 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: { @@ -277,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 abf56d91db..17b1624c05 100644 --- a/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx +++ b/plugins/cost-insights/src/components/ProductInsightsCard/ProductInsightsCard.tsx @@ -82,13 +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); diff --git a/plugins/cost-insights/src/index.ts b/plugins/cost-insights/src/index.ts index cefdefb9c9..28bdb1a8b3 100644 --- a/plugins/cost-insights/src/index.ts +++ b/plugins/cost-insights/src/index.ts @@ -18,7 +18,7 @@ export { plugin } from './plugin'; export * from './client'; export * from './api'; export * from './components'; -export { useCurrency, CurrencyContext } from './hooks'; +export { useCurrency } from './hooks'; export * from './types'; export * from './utils/tests'; export * from './utils/duration'; From 5c70f3d353be1e848a277cddcef19293753ceecb Mon Sep 17 00:00:00 2001 From: Brenda Sukh Date: Tue, 3 Nov 2020 15:25:24 -0500 Subject: [PATCH 5/5] Update changeset filename --- .../{rich-dodos-smell.md => cost-insights-rich-dodos-smell.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changeset/{rich-dodos-smell.md => cost-insights-rich-dodos-smell.md} (100%) diff --git a/.changeset/rich-dodos-smell.md b/.changeset/cost-insights-rich-dodos-smell.md similarity index 100% rename from .changeset/rich-dodos-smell.md rename to .changeset/cost-insights-rich-dodos-smell.md