Skip to content

Commit 97b331c

Browse files
committed
Merge remote-tracking branch 'origin/main' into APL-1200
2 parents 1658874 + 4eaa765 commit 97b331c

23 files changed

+2318
-3842
lines changed

ARCHITECTURE.md

Lines changed: 527 additions & 0 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 23 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"swagger-ui-express": "5.0.1",
3838
"ts-custom-error": "3.3.1",
3939
"uuid": "13.0.0",
40-
"yaml": "2.8.2"
40+
"yaml": "2.8.2",
41+
"zod": "^4.1.12"
4142
},
4243
"description": "The brain of the Otomi Container Platform. Handling console input and talking to core, it knows what to do.",
4344
"devDependencies": {
@@ -50,6 +51,7 @@
5051
"@redocly/openapi-cli": "1.0.0-beta.95",
5152
"@semantic-release/changelog": "6.0.3",
5253
"@semantic-release/git": "10.0.1",
54+
"@types/debug": "^4.1.12",
5355
"@types/expect": "24.3.2",
5456
"@types/express": "^5.0.0",
5557
"@types/fs-extra": "11.0.4",

src/api.authz.test.ts

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import request from 'supertest'
77
import { HttpError } from './error'
88
import { Git } from './git'
99
import { getSessionStack } from './middleware'
10-
import { App, CodeRepo, Repo, SealedSecret } from './otomi-models'
11-
import { RepoService } from './services/RepoService'
10+
import { App, CodeRepo, SealedSecret } from './otomi-models'
1211
import * as getValuesSchemaModule from './utils'
1312
import TestAgent from 'supertest/lib/agent'
13+
import { FileStore } from './fileStore/file-store'
1414

1515
const platformAdminToken = getToken(['platform-admin'])
1616
const teamAdminToken = getToken(['team-admin', 'team-team1'])
@@ -40,22 +40,33 @@ describe('API authz tests', () => {
4040
beforeAll(async () => {
4141
const _otomiStack = await getSessionStack()
4242
_otomiStack.git = mockDeep<Git>()
43-
_otomiStack.transformApps = jest.fn().mockReturnValue([])
44-
_otomiStack.repoService = new RepoService({} as Repo)
43+
_otomiStack.fileStore = new FileStore()
4544
otomiStack = _otomiStack as jest.Mocked<OtomiStack>
4645

4746
otomiStack.saveTeam = jest.fn().mockResolvedValue(undefined)
48-
otomiStack.doRepoDeployment = jest.fn().mockImplementation(() => Promise.resolve())
49-
otomiStack.doTeamDeployment = jest.fn().mockImplementation(() => Promise.resolve())
50-
otomiStack.isLoaded = true
51-
await otomiStack.createTeam({
52-
name: 'team1',
53-
resourceQuota: [],
54-
})
55-
await otomiStack.createTeam({
56-
name: 'team2',
57-
resourceQuota: [],
47+
otomiStack.doDeleteDeployment = jest.fn().mockImplementation(() => Promise.resolve())
48+
otomiStack.doDeployment = jest.fn().mockImplementation(() => Promise.resolve())
49+
otomiStack.fileStore.set('env/teams/team1/settings.yaml', {
50+
kind: 'AplTeamSettingSet',
51+
spec: {},
52+
metadata: {
53+
name: 'team1',
54+
labels: {
55+
'apl.io/teamId': 'team1',
56+
},
57+
},
58+
})
59+
otomiStack.fileStore.set('env/teams/team2/settings.yaml', {
60+
kind: 'AplTeamSettingSet',
61+
spec: {},
62+
metadata: {
63+
name: 'team2',
64+
labels: {
65+
'apl.io/teamId': 'team2',
66+
},
67+
},
5868
})
69+
otomiStack.isLoaded = true
5970
app = await initApp(otomiStack)
6071
agent = request.agent(app)
6172
agent.set('Accept', 'application/json')
@@ -92,6 +103,7 @@ describe('API authz tests', () => {
92103
})
93104

94105
test('platform admin can update team self-service-flags', async () => {
106+
jest.spyOn(otomiStack, 'editTeam').mockReturnValue({} as any)
95107
await agent
96108
.put('/v1/teams/team1')
97109
.send({
@@ -746,6 +758,7 @@ describe('API authz tests', () => {
746758
})
747759

748760
test('platform admin can update policies', async () => {
761+
jest.spyOn(otomiStack, 'editAplPolicy').mockReturnValue({} as any)
749762
await agent
750763
.put('/v1/teams/team1/policies/disallow-selinux')
751764
.send(data)
@@ -1031,7 +1044,7 @@ describe('API authz tests', () => {
10311044
})
10321045

10331046
test('platform admin can get specific agent', async () => {
1034-
jest.spyOn(otomiStack, 'getAplAgent').mockResolvedValue({} as any)
1047+
jest.spyOn(otomiStack, 'getAplAgent').mockReturnValue({} as any)
10351048
await agent
10361049
.get('/alpha/teams/team1/agents/test-agent')
10371050
.set('Authorization', `Bearer ${platformAdminToken}`)
@@ -1040,7 +1053,7 @@ describe('API authz tests', () => {
10401053
})
10411054

10421055
test('team admin can get specific agent', async () => {
1043-
jest.spyOn(otomiStack, 'getAplAgent').mockResolvedValue({} as any)
1056+
jest.spyOn(otomiStack, 'getAplAgent').mockReturnValue({} as any)
10441057
await agent
10451058
.get('/alpha/teams/team1/agents/test-agent')
10461059
.set('Authorization', `Bearer ${teamAdminToken}`)
@@ -1049,7 +1062,7 @@ describe('API authz tests', () => {
10491062
})
10501063

10511064
test('team member can get specific agent', async () => {
1052-
jest.spyOn(otomiStack, 'getAplAgent').mockResolvedValue({} as any)
1065+
jest.spyOn(otomiStack, 'getAplAgent').mockReturnValue({} as any)
10531066
await agent
10541067
.get('/alpha/teams/team1/agents/test-agent')
10551068
.set('Authorization', `Bearer ${teamMemberToken}`)

src/app.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ const resourceStatus = async (errorSet) => {
8686
const { cluster } = otomiStack.getSettings(['cluster'])
8787
const domainSuffix = cluster?.domainSuffix
8888
const resources: Record<string, AplResponseObject[]> = {
89-
workloads: otomiStack.repoService.getAllWorkloads(),
90-
builds: otomiStack.repoService.getAllBuilds(),
91-
services: otomiStack.repoService.getAllServices(),
92-
secrets: otomiStack.repoService.getAllSealedSecrets(),
89+
workloads: otomiStack.getAllAplWorkloads(),
90+
builds: otomiStack.getAllAplBuilds(),
91+
services: otomiStack.getAllAplServices(),
92+
secrets: otomiStack.getAllAplSealedSecrets(),
9393
}
9494
const statusFunctions = {
9595
workloads: getWorkloadStatus,
@@ -132,6 +132,10 @@ export const loadSpec = async (): Promise<void> => {
132132
export const getSpec = (): OtomiSpec => {
133133
return otomiSpec
134134
}
135+
export function getSecretPaths(): string[] {
136+
const { secretPaths } = getSpec()
137+
return secretPaths
138+
}
135139
export const getAppSchema = (appId: string): Schema => {
136140
let id: string = appId
137141
if (appId.startsWith('ingress-nginx')) id = 'ingress-nginx-platform'

src/error.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ export class OtomiError extends CustomError {
1414
}
1515
export class ForbiddenError extends OtomiError {
1616
public constructor(err?: string) {
17-
super('Forbidden', err)
17+
super(err || 'Forbidden', err)
1818
this.code = 403
1919
}
2020
}
2121
export class NotExistError extends OtomiError {
2222
public constructor(err?: string) {
23-
super('Not Found', err)
23+
super(err || 'Not Found', err)
2424
this.code = 404
2525
}
2626
}
2727
export class AlreadyExists extends OtomiError {
2828
public constructor(err?: string) {
29-
super('Conflict', err)
29+
super(err || 'Conflict', err)
3030
this.code = 409
3131
}
3232
}
@@ -45,7 +45,7 @@ export class PublicUrlExists extends OtomiError {
4545
}
4646
export class ValidationError extends OtomiError {
4747
public constructor(err?: string) {
48-
super('Invalid values detected', err)
48+
super(err || 'Invalid values detected', err)
4949
this.code = 422
5050
}
5151
}

0 commit comments

Comments
 (0)