Total usage
diff --git a/components/gitpod-protocol/package.json b/components/gitpod-protocol/package.json
index 824e371e63a1fc..21ba4c09ce83f1 100644
--- a/components/gitpod-protocol/package.json
+++ b/components/gitpod-protocol/package.json
@@ -22,6 +22,7 @@
"@types/random-number-csprng": "^1.0.0",
"@types/uuid": "^8.3.1",
"@types/ws": "^5.1.2",
+ "@types/google-protobuf": "^3.15.5",
"chai": "^4.3.4",
"chai-subset": "^1.6.0",
"mocha": "^5.0.0",
@@ -62,6 +63,7 @@
"vscode-languageserver-types": "3.17.0",
"vscode-uri": "^3.0.3",
"vscode-ws-jsonrpc": "^0.2.0",
- "ws": "^7.4.6"
+ "ws": "^7.4.6",
+ "google-protobuf": "^3.18.0-rc.2"
}
}
diff --git a/components/gitpod-protocol/src/gitpod-service.ts b/components/gitpod-protocol/src/gitpod-service.ts
index 8be6f5339a45de..41ef4f40c1fd0b 100644
--- a/components/gitpod-protocol/src/gitpod-service.ts
+++ b/components/gitpod-protocol/src/gitpod-service.ts
@@ -293,7 +293,7 @@ export interface GitpodServer extends JsonRpcServer
, AdminServer,
getSpendingLimitForTeam(teamId: string): Promise;
setSpendingLimitForTeam(teamId: string, spendingLimit: number): Promise;
- listBilledUsage(attributionId: string): Promise;
+ listBilledUsage(attributionId: string, from?: number, to?: number): Promise;
setUsageAttribution(usageAttribution: string): Promise;
/**
diff --git a/components/server/ee/src/workspace/gitpod-server-impl.ts b/components/server/ee/src/workspace/gitpod-server-impl.ts
index efbcdab9bf05da..700b8ad5fcb78c 100644
--- a/components/server/ee/src/workspace/gitpod-server-impl.ts
+++ b/components/server/ee/src/workspace/gitpod-server-impl.ts
@@ -110,6 +110,7 @@ import { getExperimentsClientForBackend } from "@gitpod/gitpod-protocol/lib/expe
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution";
import { CachingUsageServiceClientProvider } from "@gitpod/usage-api/lib/usage/v1/sugar";
import * as usage from "@gitpod/usage-api/lib/usage/v1/usage_pb";
+import { Timestamp } from "google-protobuf/google/protobuf/timestamp_pb";
@injectable()
export class GitpodServerEEImpl extends GitpodServerImpl {
@@ -2095,14 +2096,27 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
return result;
}
- async listBilledUsage(ctx: TraceContext, attributionId: string): Promise {
+ async listBilledUsage(
+ ctx: TraceContext,
+ attributionId: string,
+ from?: number,
+ to?: number,
+ ): Promise {
traceAPIParams(ctx, { attributionId });
+ let timestampFrom;
+ let timestampTo;
const user = this.checkAndBlockUser("listBilledUsage");
await this.guardCostCenterAccess(ctx, user.id, attributionId, "get");
+ if (from) {
+ timestampFrom = new Timestamp().setSeconds(from);
+ }
+ if (to) {
+ timestampTo = new Timestamp().setSeconds(to);
+ }
const usageClient = this.usageServiceClientProvider.getDefault();
- const response = await usageClient.listBilledUsage(ctx, attributionId);
+ const response = await usageClient.listBilledUsage(ctx, attributionId, timestampFrom, timestampTo);
const sessions = response.getSessionsList().map((s) => this.mapBilledSession(s));
return sessions;
diff --git a/components/server/package.json b/components/server/package.json
index 556cc1e503954f..13917ec7b48095 100644
--- a/components/server/package.json
+++ b/components/server/package.json
@@ -99,6 +99,7 @@
"@types/express-mysql-session": "^2.1.3",
"@types/express-session": "1.17.4",
"@types/fs-extra": "^9.0.12",
+ "@types/google-protobuf": "^3.15.5",
"@types/heapdump": "^0.3.1",
"@types/http-proxy": "^1.17.7",
"@types/js-yaml": "^4.0.3",
diff --git a/components/server/src/workspace/gitpod-server-impl.ts b/components/server/src/workspace/gitpod-server-impl.ts
index 7767c15a332d01..270ec99caf6251 100644
--- a/components/server/src/workspace/gitpod-server-impl.ts
+++ b/components/server/src/workspace/gitpod-server-impl.ts
@@ -3191,7 +3191,12 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
throw new ResponseError(ErrorCodes.SAAS_FEATURE, `Not implemented in this version`);
}
- async listBilledUsage(ctx: TraceContext, attributionId: string): Promise {
+ async listBilledUsage(
+ ctx: TraceContext,
+ attributionId: string,
+ from?: number,
+ to?: number,
+ ): Promise {
throw new ResponseError(ErrorCodes.SAAS_FEATURE, `Not implemented in this version`);
}
async getSpendingLimitForTeam(ctx: TraceContext, teamId: string): Promise {
diff --git a/components/usage-api/typescript/src/usage/v1/sugar.ts b/components/usage-api/typescript/src/usage/v1/sugar.ts
index c7489f49fb6a59..3e897c136d8864 100644
--- a/components/usage-api/typescript/src/usage/v1/sugar.ts
+++ b/components/usage-api/typescript/src/usage/v1/sugar.ts
@@ -12,6 +12,7 @@ import { ListBilledUsageRequest, ListBilledUsageResponse } from "./usage_pb";
import { injectable, inject, optional } from "inversify";
import { createClientCallMetricsInterceptor, IClientCallMetrics } from "@gitpod/gitpod-protocol/lib/util/grpc";
import * as grpc from "@grpc/grpc-js";
+import { Timestamp } from "google-protobuf/google/protobuf/timestamp_pb";
export const UsageServiceClientProvider = Symbol("UsageServiceClientProvider");
@@ -90,12 +91,14 @@ export class PromisifiedUsageServiceClient {
);
}
- public async listBilledUsage(_ctx: TraceContext, attributionId: string): Promise {
+ public async listBilledUsage(_ctx: TraceContext, attributionId: string, from?: Timestamp, to?: Timestamp): Promise {
const ctx = TraceContext.childContext(`/usage-service/listBilledUsage`, _ctx);
try {
const req = new ListBilledUsageRequest();
req.setAttributionId(attributionId);
+ req.setFrom(from);
+ req.setTo(to);
const response = await new Promise((resolve, reject) => {
this.client.listBilledUsage(