Skip to content
Open
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: 2 additions & 0 deletions src/operators/harbor/lib/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export const HARBOR_GROUP_TYPE = {
http: 2,
}

export const DEFAULT_OIDC_SCOPE = 'openid'
export const DEFAULT_OIDC_NAME = 'otomi'
export const ROBOT_PREFIX = 'otomi-'
export const SYSTEM_SECRET_NAME = 'harbor-robot-admin'
export const PROJECT_PULL_SECRET_NAME = 'harbor-pullsecret'
Expand Down
96 changes: 96 additions & 0 deletions src/operators/harbor/lib/managers/harbor-oidc.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Configurations, ConfigureApi } from '@linode/harbor-client-fetch'
import { DEFAULT_OIDC_NAME, DEFAULT_OIDC_SCOPE } from '../consts'
import { HarborConfig } from '../types/oidc'
import manageHarborOidcConfig from './harbor-oidc'

describe('manageHarborOidcConfig', () => {
const mockConfigureApi = {
updateConfigurations: jest.fn(),
}

const configureApi = mockConfigureApi as unknown as ConfigureApi

const expectConfigurations = (configurations: Partial<Configurations>) =>
expect.objectContaining({ configurations: expect.objectContaining(configurations) })

const harborConfig = (overrides: Partial<HarborConfig> = {}): HarborConfig =>
({
harborBaseRepoUrl: 'harbor.example.com',
harborUser: 'admin',
harborPassword: 'password',
oidcClientId: 'otomi',
oidcClientSecret: 'client-secret',
oidcEndpoint: 'https://idp.example.com',
oidcVerifyCert: true,
oidcUserClaim: 'email',
oidcAutoOnboard: true,
oidcGroupsClaim: 'groups',
oidcName: 'keycloak',
oidcScope: 'openid email profile groups',
teamNamespaces: [],
...overrides,
}) as HarborConfig

beforeEach(() => {
jest.clearAllMocks()
})

it('configures Harbor with the scope supplied in the configuration', async () => {
await manageHarborOidcConfig(configureApi, harborConfig())

expect(mockConfigureApi.updateConfigurations).toHaveBeenCalledWith(
expectConfigurations({ oidcScope: 'openid email profile groups' }),
)
})

it('falls back to the default scope when no scope is supplied', async () => {
await manageHarborOidcConfig(configureApi, harborConfig({ oidcScope: undefined }))

expect(mockConfigureApi.updateConfigurations).toHaveBeenCalledWith(
expectConfigurations({ oidcScope: DEFAULT_OIDC_SCOPE }),
)
})

it('falls back to the default scope when an empty scope is supplied', async () => {
await manageHarborOidcConfig(configureApi, harborConfig({ oidcScope: '' }))

expect(mockConfigureApi.updateConfigurations).toHaveBeenCalledWith(
expectConfigurations({ oidcScope: DEFAULT_OIDC_SCOPE }),
)
})

it('configures Harbor with the identity provider name supplied in the configuration', async () => {
await manageHarborOidcConfig(configureApi, harborConfig({ oidcName: 'dex' }))

expect(mockConfigureApi.updateConfigurations).toHaveBeenCalledWith(expectConfigurations({ oidcName: 'dex' }))
})

it('falls back to the default identity provider name when none is supplied', async () => {
await manageHarborOidcConfig(configureApi, harborConfig({ oidcName: '' }))

expect(mockConfigureApi.updateConfigurations).toHaveBeenCalledWith(
expectConfigurations({ oidcName: DEFAULT_OIDC_NAME }),
)
})

it('keeps the remaining configuration unchanged', async () => {
await manageHarborOidcConfig(configureApi, harborConfig())

expect(mockConfigureApi.updateConfigurations).toHaveBeenCalledWith(
expectConfigurations({
authMode: 'oidc_auth',
oidcAdminGroup: 'platform-admin',
oidcClientId: 'otomi',
oidcClientSecret: 'client-secret',
oidcEndpoint: 'https://idp.example.com',
oidcGroupsClaim: 'groups',
oidcUserClaim: 'email',
oidcAutoOnboard: true,
oidcVerifyCert: true,
projectCreationRestriction: 'adminonly',
selfRegistration: false,
primaryAuthMode: true,
}),
)
})
})
6 changes: 3 additions & 3 deletions src/operators/harbor/lib/managers/harbor-oidc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Configurations, ConfigureApi } from '@linode/harbor-client-fetch'
import { log } from 'console'
import { ROBOT_PREFIX } from '../consts'
import { DEFAULT_OIDC_NAME, DEFAULT_OIDC_SCOPE, ROBOT_PREFIX } from '../consts'
import { HarborConfig } from '../types/oidc'

export default async function manageHarborOidcConfig(
Expand All @@ -14,8 +14,8 @@ export default async function manageHarborOidcConfig(
oidcClientSecret: harborConfig.oidcClientSecret,
oidcEndpoint: harborConfig.oidcEndpoint,
oidcGroupsClaim: 'groups',
oidcName: 'otomi',
oidcScope: 'openid',
oidcName: harborConfig.oidcName || DEFAULT_OIDC_NAME,
oidcScope: harborConfig.oidcScope || DEFAULT_OIDC_SCOPE,
oidcVerifyCert: harborConfig.oidcVerifyCert,
oidcUserClaim: harborConfig.oidcUserClaim,
oidcAutoOnboard: harborConfig.oidcAutoOnboard,
Expand Down
5 changes: 2 additions & 3 deletions src/operators/harbor/lib/types/oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface HarborConfigMapData {
oidcUserClaim: string
oidcGroupsClaim: string
oidcName: string
oidcScope: string
oidcScope?: string
oidcVerifyCert: boolean
teamNamespaces: string[]
}
Expand All @@ -39,7 +39,6 @@ export function validateConfigMapData(configMap: V1ConfigMap): HarborConfigMapDa
'oidcUserClaim',
'oidcGroupsClaim',
'oidcName',
'oidcScope',
'oidcVerifyCert',
'teamNamespaces',
]
Expand Down Expand Up @@ -71,7 +70,7 @@ export class HarborConfig {
oidcAutoOnboard: boolean
oidcGroupsClaim: string
oidcName: string
oidcScope: string
oidcScope?: string
teamNamespaces: string[]

constructor(secretData: HarborSecretData, configMapData: HarborConfigMapData) {
Expand Down
Loading