Skip to content

Commit 973939a

Browse files
authored
Merge pull request #2125 from thestupd/master
fix: KubernetesObjectSerializer::deserialize() should support list api
2 parents 15c6ef8 + 82832c7 commit 973939a

File tree

2 files changed

+113
-3
lines changed

2 files changed

+113
-3
lines changed

src/serializer.ts

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ObjectSerializer } from './api';
22
import { V1ObjectMeta } from './gen/model/v1ObjectMeta';
3+
import { V1ListMeta } from './gen/model/v1ListMeta';
34

45
type AttributeType = {
56
name: string;
@@ -37,9 +38,52 @@ class KubernetesObject {
3738
];
3839
}
3940

41+
class KubernetesObjectList {
42+
/**
43+
* APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
44+
*/
45+
'apiVersion'?: string;
46+
/**
47+
* Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
48+
*/
49+
'kind'?: string;
50+
'metadata'?: V1ListMeta;
51+
'items'?: KubernetesObject[];
52+
53+
static attributeTypeMap: AttributeType[] = [
54+
{
55+
name: 'apiVersion',
56+
baseName: 'apiVersion',
57+
type: 'string',
58+
},
59+
{
60+
name: 'kind',
61+
baseName: 'kind',
62+
type: 'string',
63+
},
64+
{
65+
name: 'metadata',
66+
baseName: 'metadata',
67+
type: 'V1ListMeta',
68+
},
69+
];
70+
}
71+
4072
const isKubernetesObject = (data: unknown): boolean =>
4173
!!data && typeof data === 'object' && 'apiVersion' in data && 'kind' in data;
4274

75+
const isKubernetesObjectList = (data: any): boolean => isKubernetesObject(data) && 'items' in data;
76+
77+
const getClassOfKubernetesInstance = (data: any): any => {
78+
if (!isKubernetesObject(data)) {
79+
return null;
80+
}
81+
if (isKubernetesObjectList(data)) {
82+
return KubernetesObjectList;
83+
}
84+
return KubernetesObject;
85+
};
86+
4387
/**
4488
* Wraps the ObjectSerializer to support custom resources and generic Kubernetes objects.
4589
*/
@@ -90,12 +134,13 @@ class KubernetesObjectSerializer {
90134
return obj;
91135
}
92136

93-
if (!isKubernetesObject(data)) {
137+
const kubernetesClass = getClassOfKubernetesInstance(data);
138+
if (!kubernetesClass) {
94139
return obj;
95140
}
96141

97-
const instance = new KubernetesObject();
98-
for (const attributeType of KubernetesObject.attributeTypeMap) {
142+
const instance = new kubernetesClass();
143+
for (const attributeType of kubernetesClass.attributeTypeMap) {
99144
instance[attributeType.name] = ObjectSerializer.deserialize(
100145
data[attributeType.baseName],
101146
attributeType.type,
@@ -108,6 +153,10 @@ class KubernetesObjectSerializer {
108153
}
109154
instance[key] = value;
110155
}
156+
if (instance.items) {
157+
instance.items = instance.items.map((item: any) => this.deserialize(item, ''));
158+
}
159+
111160
return instance;
112161
}
113162
}

src/serializer_test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,5 +186,66 @@ describe('KubernetesObjectSerializer', () => {
186186
const res = KubernetesObjectSerializer.serialize(s, 'unknown');
187187
expect(res).to.deep.equal(s);
188188
});
189+
190+
it('should deserialize a list of unknown objects', () => {
191+
const s = {
192+
apiVersion: 'v1alpha1',
193+
kind: 'MyCustomResourceList',
194+
metadata: {
195+
resourceVersion: '1',
196+
},
197+
items: [
198+
{
199+
apiVersion: 'v1alpha1',
200+
kind: 'MyCustomResource',
201+
metadata: {
202+
name: 'k8s-js-client-test',
203+
namespace: 'default',
204+
creationTimestamp: '2022-01-01T00:00:00.000Z',
205+
},
206+
data: {
207+
key: 'value',
208+
},
209+
},
210+
],
211+
};
212+
const res = KubernetesObjectSerializer.deserialize(s, 'v1alpha1MyCustomResource');
213+
expect(res).to.deep.equal({
214+
apiVersion: 'v1alpha1',
215+
kind: 'MyCustomResourceList',
216+
metadata: {
217+
_continue: undefined,
218+
remainingItemCount: undefined,
219+
resourceVersion: '1',
220+
selfLink: undefined,
221+
},
222+
items: [
223+
{
224+
apiVersion: 'v1alpha1',
225+
kind: 'MyCustomResource',
226+
metadata: {
227+
name: 'k8s-js-client-test',
228+
namespace: 'default',
229+
creationTimestamp: new Date('2022-01-01T00:00:00.000Z'),
230+
uid: undefined,
231+
annotations: undefined,
232+
labels: undefined,
233+
finalizers: undefined,
234+
generateName: undefined,
235+
selfLink: undefined,
236+
resourceVersion: undefined,
237+
generation: undefined,
238+
ownerReferences: undefined,
239+
deletionTimestamp: undefined,
240+
deletionGracePeriodSeconds: undefined,
241+
managedFields: undefined,
242+
},
243+
data: {
244+
key: 'value',
245+
},
246+
},
247+
],
248+
});
249+
});
189250
});
190251
});

0 commit comments

Comments
 (0)