Skip to content

Commit d65afc6

Browse files
committed
[db][protocol] Implement a CostCenter entity to attribute workspace usage to
1 parent 839628f commit d65afc6

File tree

9 files changed

+111
-1
lines changed

9 files changed

+111
-1
lines changed

components/gitpod-db/src/container-module.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ import { TypeORMBlockedRepositoryDBImpl } from "./typeorm/blocked-repository-db-
6767
import { BlockedRepositoryDB } from "./blocked-repository-db";
6868
import { WebhookEventDB } from "./webhook-event-db";
6969
import { WebhookEventDBImpl } from "./typeorm/webhook-event-db-impl";
70+
import { CostCenterDB } from "./cost-center-db";
71+
import { CostCenterDBImpl } from "./typeorm/cost-center-db-impl";
7072

7173
// THE DB container module that contains all DB implementations
7274
export const dbContainerModule = new ContainerModule((bind, unbind, isBound, rebind) => {
@@ -144,6 +146,9 @@ export const dbContainerModule = new ContainerModule((bind, unbind, isBound, reb
144146
bind(WebhookEventDBImpl).toSelf().inSingletonScope();
145147
bind(WebhookEventDB).toService(WebhookEventDBImpl);
146148

149+
bind(CostCenterDBImpl).toSelf().inSingletonScope();
150+
bind(CostCenterDB).toService(CostCenterDBImpl);
151+
147152
// com concerns
148153
bind(AccountingDB).to(TypeORMAccountingDBImpl).inSingletonScope();
149154
bind(TransactionalAccountingDBFactory).toFactory((ctx) => {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the Gitpod Enterprise Source Code License,
4+
* See License.enterprise.txt in the project root folder.
5+
*/
6+
7+
import { CostCenter } from "@gitpod/gitpod-protocol";
8+
9+
export const CostCenterDB = Symbol("CostCenterDB");
10+
export interface CostCenterDB {
11+
storeEntry(ts: CostCenter): Promise<void>;
12+
findById(id: string): Promise<CostCenter | undefined>;
13+
}

components/gitpod-db/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ export * from "./project-db";
3939
export * from "./team-db";
4040
export * from "./installation-admin-db";
4141
export * from "./webhook-event-db";
42+
export * from "./cost-center-db";

components/gitpod-db/src/tables.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,12 @@ export class GitpodTableDescriptionProvider implements TableDescriptionProvider
280280
deletionColumn: "deleted",
281281
timeColumn: "_lastModified",
282282
},
283+
{
284+
name: "d_b_cost_center",
285+
primaryKeys: ["id"],
286+
deletionColumn: "deleted",
287+
timeColumn: "_lastModified",
288+
},
283289
];
284290

285291
public getSortedTables(): TableDescription[] {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the Gitpod Enterprise Source Code License,
4+
* See License.enterprise.txt in the project root folder.
5+
*/
6+
7+
import { injectable, inject } from "inversify";
8+
import { Repository } from "typeorm";
9+
10+
import { CostCenter } from "@gitpod/gitpod-protocol";
11+
12+
import { CostCenterDB } from "../cost-center-db";
13+
import { DBCostCenter } from "./entity/db-cost-center";
14+
import { TypeORM } from "./typeorm";
15+
16+
@injectable()
17+
export class CostCenterDBImpl implements CostCenterDB {
18+
@inject(TypeORM) protected readonly typeORM: TypeORM;
19+
20+
protected async getEntityManager() {
21+
return (await this.typeORM.getConnection()).manager;
22+
}
23+
24+
protected async getRepo(): Promise<Repository<DBCostCenter>> {
25+
return (await this.getEntityManager()).getRepository(DBCostCenter);
26+
}
27+
28+
async storeEntry(ts: CostCenter): Promise<void> {
29+
const repo = await this.getRepo();
30+
await repo.save(ts);
31+
}
32+
33+
async findById(id: string): Promise<CostCenter | undefined> {
34+
const repo = await this.getRepo();
35+
return repo.findOne(id);
36+
}
37+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the Gitpod Enterprise Source Code License,
4+
* See License.enterprise.txt in the project root folder.
5+
*/
6+
7+
import { Entity, Column, PrimaryColumn } from "typeorm";
8+
import { CostCenter } from "@gitpod/gitpod-protocol";
9+
10+
@Entity()
11+
// on DB but not Typeorm: @Index("ind_lastModified", ["_lastModified"]) // DBSync
12+
export class DBCostCenter implements CostCenter {
13+
@PrimaryColumn()
14+
id: string;
15+
16+
@Column()
17+
spendingLimit: number;
18+
19+
// This column triggers the db-sync deletion mechanism. It's not intended for public consumption.
20+
@Column()
21+
deleted: boolean;
22+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License-AGPL.txt in the project root for license information.
5+
*/
6+
7+
import { MigrationInterface, QueryRunner } from "typeorm";
8+
9+
export class CostCenter1658241900000 implements MigrationInterface {
10+
public async up(queryRunner: QueryRunner): Promise<void> {
11+
await queryRunner.query(
12+
"CREATE TABLE IF NOT EXISTS `d_b_cost_center` (`id` char(255) NOT NULL, `spendingLimit` int(11) NOT NULL DEFAULT '0', `deleted` tinyint(4) NOT NULL DEFAULT '0', `_lastModified` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (`id`), KEY `ind_dbsync` (`_lastModified`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;",
13+
);
14+
}
15+
16+
public async down(queryRunner: QueryRunner): Promise<void> {}
17+
}

components/gitpod-protocol/src/protocol.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,3 +1481,11 @@ export interface Terms {
14811481
readonly content: string;
14821482
readonly formElements?: object;
14831483
}
1484+
1485+
export interface CostCenter {
1486+
readonly id: string;
1487+
/**
1488+
* Unit: credits
1489+
*/
1490+
spendingLimit: number;
1491+
}

components/server/src/user/user-service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
WORKSPACE_TIMEOUT_EXTENDED,
1717
WORKSPACE_TIMEOUT_EXTENDED_ALT,
1818
} from "@gitpod/gitpod-protocol";
19-
import { ProjectDB, TermsAcceptanceDB, UserDB } from "@gitpod/gitpod-db/lib";
19+
import { CostCenterDB, ProjectDB, TermsAcceptanceDB, UserDB } from "@gitpod/gitpod-db/lib";
2020
import { HostContextProvider } from "../auth/host-context-provider";
2121
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
2222
import { Config } from "../config";
@@ -65,6 +65,7 @@ export class UserService {
6565
@inject(TermsAcceptanceDB) protected readonly termsAcceptanceDb: TermsAcceptanceDB;
6666
@inject(TermsProvider) protected readonly termsProvider: TermsProvider;
6767
@inject(ProjectDB) protected readonly projectDb: ProjectDB;
68+
@inject(CostCenterDB) protected readonly costCenterDb: CostCenterDB;
6869

6970
/**
7071
* Takes strings in the form of <authHost>/<authName> and returns the matching User

0 commit comments

Comments
 (0)