Skip to content

Commit 7dcd3dc

Browse files
merllsvcAPLBot
andauthored
fix: patches on partially existing tty objects (#1007)
* fix: provide required name argument * fix: set patch method * fix: use patch strategy accepted for custom object * test: add some return value to verify mock function call * test: provide call parameters of valid type --------- Co-authored-by: svcAPLBot <174728082+svcAPLBot@users.noreply.github.com>
1 parent f54fdfe commit 7dcd3dc

2 files changed

Lines changed: 23 additions & 8 deletions

File tree

src/tty.test.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,15 @@ jest.mock('@kubernetes/client-node', () => {
5252
class CoreV1Api {}
5353
class CustomObjectsApi {}
5454
class RbacAuthorizationV1Api {}
55+
const PatchStrategy = { ServerSideApply: 'application/apply-patch+yaml' }
5556

5657
return {
5758
ApiException: MockApiException,
5859
CoreV1Api,
5960
CustomObjectsApi,
6061
RbacAuthorizationV1Api,
62+
PatchStrategy,
63+
setHeaderOptions: jest.fn().mockImplementation(() => 'header-options'),
6164
KubeConfig: jest.fn().mockImplementation(() => ({
6265
makeApiClient: mockMakeApiClient,
6366
loadFromDefault: jest.fn(),
@@ -87,9 +90,10 @@ describe('CloudTty', () => {
8790
const createFn = jest.fn().mockResolvedValue({ kind: 'created' })
8891
const patchFn = jest.fn().mockResolvedValue({ kind: 'patched' })
8992

90-
const result = await tty.createOrPatch(createFn, patchFn, { id: 'x' })
93+
const params = { body: { metadata: { name: 'x' }, spec: {} } }
94+
const result = await tty.createOrPatch(createFn, patchFn, params)
9195

92-
expect(createFn).toHaveBeenCalledWith({ id: 'x' })
96+
expect(createFn).toHaveBeenCalledWith(params)
9397
expect(patchFn).not.toHaveBeenCalled()
9498
expect(result).toEqual({ kind: 'created' })
9599
})
@@ -101,10 +105,14 @@ describe('CloudTty', () => {
101105
})
102106
const patchFn = jest.fn().mockResolvedValue({ kind: 'patched' })
103107

104-
const result = await tty.createOrPatch(createFn, patchFn, { id: 'x' })
108+
const params = { body: { metadata: { name: 'x' }, spec: {} } }
109+
const result = await tty.createOrPatch(createFn, patchFn, params)
105110

106-
expect(createFn).toHaveBeenCalledWith({ id: 'x' })
107-
expect(patchFn).toHaveBeenCalledWith({ id: 'x' })
111+
expect(createFn).toHaveBeenCalledWith(params)
112+
expect(patchFn).toHaveBeenCalledWith(
113+
{ name: 'x', body: params.body, fieldManager: 'apl-api', force: true },
114+
'header-options',
115+
)
108116
expect(result).toEqual({ kind: 'patched' })
109117
})
110118

src/tty.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import {
22
ApiException,
3+
ConfigurationOptions,
34
CoreV1Api,
45
CustomObjectsApi,
56
KubeConfig,
67
KubernetesObject,
8+
PatchStrategy,
79
RbacAuthorizationV1Api,
10+
setHeaderOptions,
811
} from '@kubernetes/client-node'
912
import Debug from 'debug'
1013
import { SessionUser } from './otomi-models'
@@ -35,16 +38,20 @@ export default class CloudTty {
3538
this.debug = Debug('tty')
3639
}
3740

38-
async createOrPatch<T>(
41+
async createOrPatch<T extends { body: KubernetesObject }>(
3942
createFunc: (params: T) => Promise<KubernetesObject>,
40-
patchFunc: (params: T) => Promise<KubernetesObject>,
43+
patchFunc: (params: T, options?: ConfigurationOptions) => Promise<KubernetesObject>,
4144
params: T,
4245
): Promise<KubernetesObject> {
4346
try {
4447
return await createFunc(params)
4548
} catch (error) {
4649
if (error instanceof ApiException && error.code === 409) {
47-
return await patchFunc(params)
50+
const { name } = params.body.metadata!
51+
return await patchFunc(
52+
{ name, ...params, fieldManager: 'apl-api', force: true },
53+
setHeaderOptions('Content-Type', PatchStrategy.ServerSideApply),
54+
)
4855
} else {
4956
throw error
5057
}

0 commit comments

Comments
 (0)