Skip to content

Commit 7ddfb48

Browse files
committed
Add "spending limit is reached" notification
1 parent e0579ef commit 7ddfb48

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

components/gitpod-protocol/src/gitpod-service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
302302
trackEvent(event: RemoteTrackMessage): Promise<void>;
303303
trackLocation(event: RemotePageMessage): Promise<void>;
304304
identifyUser(event: RemoteIdentifyMessage): Promise<void>;
305+
306+
/**
307+
* Frontend notifications
308+
*/
309+
getNotifications(): Promise<string[]>;
305310
}
306311

307312
export interface RateLimiterError {

components/server/ee/src/workspace/gitpod-server-impl.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,26 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
20962096
});
20972097
}
20982098

2099+
async getNotifications(ctx: TraceContext): Promise<string[]> {
2100+
const result = await super.getNotifications(ctx);
2101+
const user = this.checkAndBlockUser("getNotifications");
2102+
if (user.usageAttributionId) {
2103+
const allSessions = await this.listBilledUsage(ctx, user.usageAttributionId);
2104+
const totalUsage = allSessions.map((s) => s.credits).reduce((a, b) => a + b, 0);
2105+
const costCenter = await this.costCenterDB.findById(user.usageAttributionId);
2106+
if (costCenter) {
2107+
if (totalUsage > costCenter.spendingLimit) {
2108+
result.unshift("The spending limit is reached.");
2109+
} else if (totalUsage > 0.8 * costCenter.spendingLimit * 0.8) {
2110+
result.unshift("The spending limit is almost reached.");
2111+
}
2112+
} else {
2113+
log.warn("No costcenter found.", { userId: user.id, attributionId: user.usageAttributionId });
2114+
}
2115+
}
2116+
return result;
2117+
}
2118+
20992119
async listBilledUsage(ctx: TraceContext, attributionId: string): Promise<BillableSession[]> {
21002120
traceAPIParams(ctx, { attributionId });
21012121
const user = this.checkAndBlockUser("listBilledUsage");

components/server/src/auth/rate-limiter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ function getConfig(config: RateLimiterConfig): RateLimiterConfig {
219219
setUsageAttribution: { group: "default", points: 1 },
220220
getSpendingLimitForTeam: { group: "default", points: 1 },
221221
setSpendingLimitForTeam: { group: "default", points: 1 },
222+
getNotifications: { group: "default", points: 1 },
222223
};
223224

224225
return {

components/server/src/workspace/gitpod-server-impl.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3243,4 +3243,9 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
32433243
return this.imagebuilderClientProvider.getClient(user, workspace, instance);
32443244
}
32453245
}
3246+
3247+
async getNotifications(ctx: TraceContext): Promise<string[]> {
3248+
this.checkAndBlockUser("getNotifications");
3249+
return [];
3250+
}
32463251
}

0 commit comments

Comments
 (0)