Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/postman.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
- name: Run API tests
#The UUID's are the order the requests are executed in. So that the POST are executed first
run: |
postman collection run 44183872-1d1f2dba-6c47-4764-a847-a6bca216ecea -e 43715313-d380e919-5142-44e6-b52c-02f8b04da8fa -i 44183872-be57d2e3-650d-4494-ba65-6486b68082b0 -i 44183872-f50a0c10-89ef-4352-8a56-3093811b3311 -i 44183872-0a01d698-5d93-4ebf-bd52-6cd7b1af9735 -i 44183872-6229c491-250d-49a4-8388-7a2353129925 -i 44183872-07ac4c2a-037a-4002-a5d1-2e990cfcb1b0 -i 44183872-297df31a-4560-4f27-aa06-31437d59dd7c -i 44183872-47db1e8a-9245-49a6-a6ff-7044b95d8ad3 -i 44183872-beeb6115-2e7b-4a7b-bcd8-eb605a5cd3fc -i 44183872-eff09537-0ab0-4914-a15d-a08270360574 -i 44183872-5003d09d-439f-456a-8864-e6e1f62db807 -i 44183872-a25b9ea2-1c64-4bf1-a5e4-dc905f1a9a6a -i 44183872-7082300f-e721-43f3-9828-1f3bbd25ab0a -i 44183872-6631ed83-0ff4-4515-8fa6-2d57c2959e77 -i 44183872-0a483150-4d00-49f1-8f9a-31ab467f79ec -i 44183872-15ce6497-700f-49f9-949a-ec22bf169c3f -i 44183872-c4097a49-9f17-4d6e-8ff2-a1a1fcec2dff -i 44183872-e357451a-9526-4b57-bb5b-1190e0d6788f -i 44183872-9abfae13-8983-453e-85c5-a3951dddd8e6 -i 44183872-3db33396-563e-4f0a-b074-fc74680c72bd -i 44183872-61b903cb-d623-4b6d-85a3-ab2f7b0575d8 -i 44183872-34fb39a5-5bc2-4528-886a-49e4caf2d9b5 -i 44183872-e34ef3b6-f979-4407-8e69-b972be4d5184 -i 44183872-da7d9d0c-3ab1-457a-a56f-2fa49b151f1d -i 44183872-d7d08dac-364f-4f94-9c48-64dbd77fcadd -i 44183872-a6fad9da-3fae-4c7c-9e15-ec6d67a79b78 -i 44183872-79ff962a-4117-4b91-8cb6-2653b6d5a687 -i 44183872-225a21ca-9106-484c-83b5-1257bc6433e7 -i 44183872-7ac118a2-7f55-4996-a2e6-0b34eb7058ae -i 44183872-4d49d6c6-6367-4ec4-8b4c-6c6154118a3a -i 44183872-dd1b76be-26ee-4b5b-913b-8ce465778229 -i 44183872-ee200410-27ac-4c28-a469-21f487dfbaec -i 44183872-c7676daa-2257-47d6-88ca-178d433a5f28 -i 44183872-f162b5b5-1428-4f9e-8ea5-6bb3b7980b48 -i 44183872-048cddb0-5671-4abb-ac9f-8985c8e4ed6d -i 44183872-a9b4f64a-60be-43e5-bb55-6e16c85c9215 -i 44183872-a26a7e26-0df8-4ad9-95ce-ce168010f631 -i 44183872-9feaad53-dac9-475d-bd71-192d0c844e59 -i 44183872-d09732cd-0395-4b25-85c9-01b9c6a7d43c -i 44183872-1c7dca5b-58aa-4bb6-9224-d703e88b17cd -i 44183872-d183edcc-b144-4e80-9e10-72bf49f535d0 -i 44183872-7451bc15-e0cc-44a8-946b-f09bf024c9eb -i 44183872-3d6e845b-8a82-43b4-a6be-e30effc16d46 -i 44183872-d81fa269-56a3-4eef-934e-39a30e9e5dfd -i 44183872-0ed3bf3e-d78b-4818-bb47-ded64e22525f -i 44183872-fe220b54-58ce-427f-bd19-2f2716cfaa65
postman collection run 44183872-1d1f2dba-6c47-4764-a847-a6bca216ecea -e 43715313-d380e919-5142-44e6-b52c-02f8b04da8fa -i 44183872-16af2563-f99c-41c6-81c5-6d68d8aaef42
- name: Upload logs
if: always()
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ secrets.*.yaml.dec
#intelij
.idea/

# DS_Store
src/.DS_Store
.DS_Store

src/.DS_Store
10 changes: 6 additions & 4 deletions src/api.authz.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/no-empty-function */

import { Express } from 'express'
import { mockDeep } from 'jest-mock-extended'
import { initApp, loadSpec } from 'src/app'
import getToken from 'src/fixtures/jwt'
Expand All @@ -9,8 +8,10 @@ import request, { SuperAgentTest } from 'supertest'
import { HttpError } from './error'
import { Git } from './git'
import { getSessionStack } from './middleware'
import { App, CodeRepo, SealedSecret } from './otomi-models'
import { App, CodeRepo, Repo, SealedSecret } from './otomi-models'
import * as getValuesSchemaModule from './utils'
import { RepoService } from './services/RepoService'
import { Express } from 'express'

const platformAdminToken = getToken(['platform-admin'])
const teamAdminToken = getToken(['team-admin', 'team-team1'])
Expand Down Expand Up @@ -42,14 +43,14 @@ describe('API authz tests', () => {
_otomiStack.git = mockDeep<Git>()
_otomiStack.doDeployment = jest.fn().mockImplementation(() => Promise.resolve())
_otomiStack.transformApps = jest.fn().mockReturnValue([])
await _otomiStack.initRepo()
_otomiStack.repoService = new RepoService({} as Repo)
otomiStack = _otomiStack as jest.Mocked<OtomiStack>

otomiStack.saveTeam = jest.fn().mockResolvedValue(undefined)
otomiStack.doDeployment = jest.fn().mockImplementation(() => Promise.resolve())
otomiStack.doRepoDeployment = jest.fn().mockImplementation(() => Promise.resolve())
otomiStack.doTeamDeployment = jest.fn().mockImplementation(() => Promise.resolve())
await otomiStack.loadValues()
otomiStack.isLoaded = true
await otomiStack.createTeam({ name: 'team1' })
await otomiStack.createTeam({ name: 'team2' })
app = await initApp(otomiStack)
Expand Down Expand Up @@ -717,6 +718,7 @@ describe('API authz tests', () => {
})

test('team member can test code repository url', async () => {
jest.spyOn(otomiStack, 'getTestRepoConnect').mockResolvedValue({})
await agent
.get(`/v1/testRepoConnect`)
.query({ url: data.repositoryUrl })
Expand Down
29 changes: 29 additions & 0 deletions src/api/v2/teams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Debug from 'debug'
import { Operation, OperationHandlerArray } from 'express-openapi'
import { AplTeamSettingsRequest, OpenApiRequestExt } from 'src/otomi-models'

const debug = Debug('otomi:api:v2:teams')

export default function (): OperationHandlerArray {
const get: Operation = [
({ otomi }: OpenApiRequestExt, res): void => {
debug('getTeams')
// we filter admin team here as it is not for console
const teams = otomi.getAplTeams() || []

res.json(teams)
},
]
const post: Operation = [
async ({ otomi, body }: OpenApiRequestExt, res): Promise<void> => {
debug('createTeam')
const data = await otomi.createAplTeam(body as AplTeamSettingsRequest)
res.json(data)
},
]
const api = {
get,
post,
}
return api
}
43 changes: 43 additions & 0 deletions src/api/v2/teams/{teamId}.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Debug from 'debug'
import { Operation, OperationHandlerArray } from 'express-openapi'
import { AplTeamSettingsRequest, OpenApiRequestExt } from 'src/otomi-models'

const debug = Debug('otomi:api:v2:teams')

export default function (): OperationHandlerArray {
const del: Operation = [
async ({ otomi, params: { teamId } }: OpenApiRequestExt, res): Promise<void> => {
debug(`deleteTeam(${teamId})`)
await otomi.deleteTeam(teamId)
res.json({})
},
]
const get: Operation = [
({ otomi, params: { teamId } }: OpenApiRequestExt, res): void => {
debug(`getTeam(${teamId})`)
const data = otomi.getAplTeam(teamId)
res.json(data)
},
]
const put: Operation = [
async ({ otomi, params: { teamId }, body }: OpenApiRequestExt, res): Promise<void> => {
debug(`editTeam(${teamId})`)
const data = await otomi.editAplTeam(teamId, body as AplTeamSettingsRequest)
res.json(data)
},
]
const patch: Operation = [
async ({ otomi, params: { teamId }, body }: OpenApiRequestExt, res): Promise<void> => {
debug(`editTeam(${teamId}, patch)`)
const data = await otomi.editAplTeam(teamId, body as AplTeamSettingsRequest, true)
res.json(data)
},
]
const api = {
delete: del,
get,
put,
patch,
}
return api
}
39 changes: 21 additions & 18 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export const getAppList = (): string[] => {
return appsSchema.enum as string[]
}

export async function initApp(inOtomiStack?: OtomiStack | undefined) {
export async function initApp(inOtomiStack?: OtomiStack) {
const lightship = createLightship()
const app = express()
const apiRoutesPath = path.resolve(__dirname, 'api')
Expand All @@ -166,12 +166,14 @@ export async function initApp(inOtomiStack?: OtomiStack | undefined) {
})
}
// Transforms the interval to minutes
const gitCheckVersionInterval = env.CHECK_LATEST_COMMIT_INTERVAL * 60 * 1000
setInterval(async function () {
await checkAgainstGitea()
}, gitCheckVersionInterval)
if (!env.isTest) {
const gitCheckVersionInterval = env.CHECK_LATEST_COMMIT_INTERVAL * 60 * 1000
setInterval(async function () {
await checkAgainstGitea()
}, gitCheckVersionInterval)
}
let server: Server | undefined
if (!inOtomiStack) {
if (!inOtomiStack && !env.isTest) {
// initialize full server
const { PORT = 8080 } = process.env
server = app
Expand All @@ -190,19 +192,20 @@ export async function initApp(inOtomiStack?: OtomiStack | undefined) {
})
}

// emit resource status every 10 seconds
const emitResourceStatusInterval = 10 * 1000
const errorSet = new Set()
setInterval(async function () {
try {
await resourceStatus(errorSet)
} catch (e) {
debug(e)
}
}, emitResourceStatusInterval)

// and register session middleware
if (!env.isTest) {
// emit resource status every 10 seconds
const emitResourceStatusInterval = 10 * 1000
const errorSet = new Set()
setInterval(async function () {
try {
await resourceStatus(errorSet)
} catch (e) {
debug(e)
}
}, emitResourceStatusInterval)
}
app.use(sessionMiddleware(server as Server))
// and register session middleware
// now we can initialize the more specific routes
initialize({
// @ts-ignore
Expand Down
84 changes: 81 additions & 3 deletions src/openapi/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Team'

'/v1/teams/{teamId}':
parameters:
- $ref: '#/components/parameters/teamParams'
Expand Down Expand Up @@ -154,6 +155,83 @@ paths:
'200':
description: Successfully deleted a team

/v2/teams:
get:
operationId: getAplTeams
description: Get teams collection
x-aclSchema: Team
responses:
'200':
description: Successfully obtained teams collection
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/AplTeamSettingsResponse'
post:
operationId: createAplTeam
description: Create a team
x-aclSchema: Team
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AplTeamSettingsRequest'
description: Team object that needs to be added to the collection
required: true
responses:
<<: *DefaultPostResponses
'200':
description: Successfully obtained teams collection
content:
application/json:
schema:
$ref: '#/components/schemas/AplTeamSettingsResponse'

'/v2/teams/{teamId}':
parameters:
- $ref: '#/components/parameters/teamParams'
get:
operationId: getAplTeam
description: Get a specific team
x-aclSchema: Team
responses:
<<: *DefaultGetResponses
'200':
description: Successfully obtained team
content:
application/json:
schema:
$ref: '#/components/schemas/AplTeamSettingsResponse'
put:
operationId: editAplTeam
description: Edit a team
x-aclSchema: Team
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AplTeamSettingsRequest'
description: Team object that contains updated values
required: true
responses:
<<: *DefaultGetResponses
'200':
description: Successfully edited team
content:
application/json:
schema:
$ref: '#/components/schemas/AplTeamSettingsResponse'
delete:
operationId: deleteAplTeam
description: Delete team
x-aclSchema: Team
responses:
<<: *DefaultGetResponses
'200':
description: Successfully deleted a team

/v1/services:
get:
operationId: getAllServices
Expand Down Expand Up @@ -2850,7 +2928,7 @@ components:
properties:
kind:
type: string
enum: [AplTeamSettings]
enum: [AplTeamSettingSet]
spec:
$ref: 'team.yaml#/AplTeamSpec'
required:
Expand All @@ -2859,12 +2937,12 @@ components:
AplTeamSettingsRequest:
allOf:
- $ref: '#/components/schemas/AplTeamSettings'
- $ref: '#/components/schemas/aplMetadata'
- $ref: '#/components/schemas/aplTeamMetadata'
AplTeamSettingsResponse:
type: object
allOf:
- $ref: '#/components/schemas/AplTeamSettings'
- $ref: '#/components/schemas/aplMetadata'
- $ref: '#/components/schemas/aplTeamMetadata'
- $ref: '#/components/schemas/aplStatusResponse'
AplWorkload:
type: object
Expand Down
6 changes: 5 additions & 1 deletion src/otomi-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export type RepoBranches = components['schemas']['RepoBranches']
export type TestRepoConnect = components['schemas']['TestRepoConnect']
export type InternalRepoUrls = components['schemas']['InternalRepoUrls']
export type Team = components['schemas']['Team']
export type AplTeamSettingsRequest = components['schemas']['AplTeamSettingsRequest']
export type AplTeamSettingsResponse = components['schemas']['AplTeamSettingsResponse']
export type TeamSelfService = components['schemas']['Team']['selfService']
export type SessionUser = components['schemas']['SessionUser']
export type UserAuthz = components['schemas']['SessionUser']['authz']
Expand Down Expand Up @@ -78,6 +80,7 @@ export type AplRequestObject =
| AplSecretRequest
| AplServiceRequest
| AplWorkloadRequest
| AplTeamSettingsRequest
export type AplResponseObject =
| AplBackupResponse
| AplBuildResponse
Expand All @@ -88,6 +91,7 @@ export type AplResponseObject =
| AplSecretResponse
| AplServiceResponse
| AplWorkloadResponse
| AplTeamSettingsResponse
export type AplKind =
| 'AplApp'
| 'AplAlertSet'
Expand Down Expand Up @@ -254,6 +258,6 @@ export interface TeamConfig {
projects: AplProjectResponse[]
sealedsecrets: AplSecretResponse[]
services: AplServiceResponse[]
settings: Team
settings: AplTeamSettingsResponse
workloads: AplWorkloadResponse[]
}
Loading
Loading