diff --git a/projects/cobbler-api/src/lib/cobbler-api.service.spec.ts b/projects/cobbler-api/src/lib/cobbler-api.service.spec.ts index 5bdbed4d..2869a8bd 100644 --- a/projects/cobbler-api/src/lib/cobbler-api.service.spec.ts +++ b/projects/cobbler-api/src/lib/cobbler-api.service.spec.ts @@ -1,6 +1,7 @@ import {TestBed} from '@angular/core/testing'; import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; import {BackgroundBuildisoOptions, BackgroundImportOptions, BackgroundReplicateOptions} from 'cobbler-api'; +import {Distro} from './custom-types/items'; import {Event, ExtendedVersion, InstallationStatus} from './custom-types/misc'; import {COBBLER_URL} from './lib.config'; import {AngularXmlrpcService} from 'typescript-xmlrpc'; @@ -338,9 +339,46 @@ describe('CobblerApiService', () => { expect(service).toBeFalsy(); }); - xit('should execute the get_distro action on the Cobbler Server', () => { - service.get_distro(''); - expect(service).toBeFalsy(); + it('should execute the get_distro action on the Cobbler Server', () => { + // eslint-disable-next-line max-len + const methodResponse = `parentdepth0ctime1721480439.039089mtime1721480439.039089uid12f034d6781946d1af0783e20684cbd4nametestcommentkernel_optionskernel_options_postautoinstall_metafetchable_filesboot_filestemplate_filesowners<<inherit>>mgmt_classesmgmt_parametersis_subobject0tree_build_time0.0archx86_64boot_loaders<<inherit>>breedinitrd/root/initrdkernel/root/kernelos_versionredhat_management_key<<inherit>>source_reposremote_boot_kernelremote_grub_kernelremote_boot_initrdremote_grub_initrdks_meta` + const result: Distro = { + ctime: 1721480439.039089, + depth: 0, + mtime: 1721480439.039089, + uid: "12f034d6781946d1af0783e20684cbd4", + source_repos: [], + tree_build_time: 0, + arch: "x86_64", + autoinstall_meta: {}, + boot_files: {}, + boot_loaders: "<>", + is_subobject: false, + parent: "", + breed: "", + comment: "", + fetchable_files: {}, + initrd: "/root/initrd", + kernel: "/root/kernel", + remote_boot_initrd: "", + remote_boot_kernel: "", + remote_grub_initrd: "", + remote_grub_kernel: "", + kernel_options: {}, + kernel_options_post: {}, + mgmt_classes: [], + mgmt_parameters: {}, + name: "test", + os_version: "", + owners: "<>", + redhat_management_key: "<>", + template_files: {}, + } + service.get_distro('', false, false, "").subscribe(value => { + expect(value).toEqual(result) + }); + const mockRequest = httpTestingController.expectOne('http://localhost/cobbler_api'); + mockRequest.flush(methodResponse); }); xit('should execute the get_profile action on the Cobbler Server', () => { @@ -383,14 +421,59 @@ describe('CobblerApiService', () => { expect(service).toBeFalsy(); }); - xit('should execute the get_item_names action on the Cobbler Server', () => { - service.get_item_names(''); - expect(service).toBeFalsy(); + it('should execute the get_item_names action on the Cobbler Server', () => { + // eslint-disable-next-line max-len + const methodResponse = `testdistro` + const result = ["testdistro"] + service.get_item_names('distro').subscribe(value => { + expect(value).toEqual(result) + }); + const mockRequest = httpTestingController.expectOne('http://localhost/cobbler_api'); + mockRequest.flush(methodResponse); }); - xit('should execute the get_distros action on the Cobbler Server', () => { - service.get_distros(); - expect(service).toBeFalsy(); + it('should execute the get_distros action on the Cobbler Server', () => { + // eslint-disable-next-line max-len + const methodResponse = `parentdepth0ctime1721480439.039089mtime1721480439.039089uid12f034d6781946d1af0783e20684cbd4nametestcommentkernel_optionskernel_options_postautoinstall_metafetchable_filesboot_filestemplate_filesowners<<inherit>>mgmt_classesmgmt_parametersis_subobject0tree_build_time0.0archx86_64boot_loaders<<inherit>>breedinitrd/root/initrdkernel/root/kernelos_versionredhat_management_key<<inherit>>source_reposremote_boot_kernelremote_grub_kernelremote_boot_initrdremote_grub_initrdks_meta` + const result: Array = [ + { + ctime: 1721480439.039089, + depth: 0, + mtime: 1721480439.039089, + uid: "12f034d6781946d1af0783e20684cbd4", + source_repos: [], + tree_build_time: 0, + arch: "x86_64", + autoinstall_meta: {}, + boot_files: {}, + boot_loaders: "<>", + is_subobject: false, + parent: "", + breed: "", + comment: "", + fetchable_files: {}, + initrd: "/root/initrd", + kernel: "/root/kernel", + remote_boot_initrd: "", + remote_boot_kernel: "", + remote_grub_initrd: "", + remote_grub_kernel: "", + kernel_options: {}, + kernel_options_post: {}, + mgmt_classes: [], + mgmt_parameters: {}, + name: "test", + os_version: "", + owners: "<>", + redhat_management_key: "<>", + template_files: {} + } + ] + service.get_distros().subscribe(value => { + expect(value).toEqual(result) + }); + const mockRequest = httpTestingController.expectOne('http://localhost/cobbler_api'); + mockRequest.flush(methodResponse); }); xit('should execute the get_profiles action on the Cobbler Server', () => { diff --git a/projects/cobbler-api/src/lib/cobbler-api.service.ts b/projects/cobbler-api/src/lib/cobbler-api.service.ts index a7e2f170..479f76e2 100644 --- a/projects/cobbler-api/src/lib/cobbler-api.service.ts +++ b/projects/cobbler-api/src/lib/cobbler-api.service.ts @@ -454,6 +454,27 @@ export class CobblerApiService { ); } + private rebuildItem(xmlrpcStruct: XmlRpcStruct): object { + const result = {} + xmlrpcStruct.members.forEach(value => { + if (value.name === "ks_meta") { + // Skip legacy keys + return; + } + if (AngularXmlrpcService.instanceOfXmlRpcArray(value.value)) { + result[value.name] = this.convertXmlRpcArrayToTypeScriptArray(value.value) + } else if (AngularXmlrpcService.instanceOfXmlRpcStruct(value.value)) { + result[value.name] = this.convertXmlRpcStructToTypeScriptObject(value.value) + } else if (value.value === "<<inherit>>") { + // FIXME: Maybe we need to XML encode this as other strings potentially also could need encoding + result[value.name] = "<>" + } else { + result[value.name] = value.value + } + }) + return result + } + // TODO: Create casting magic to output the right item type get_item(what: string, name: string, flatten: boolean = false): Observable { return this.client @@ -470,14 +491,17 @@ export class CobblerApiService { ); } - get_distro(name: string, flatten: boolean = false): Observable { + get_distro(name: string, flatten: boolean = false, resolved: boolean = false, token: string): Observable { return this.client - .methodCall('get_distro', [name, flatten]) + .methodCall('get_distro', [name, flatten, resolved, token]) .pipe( map((data: MethodResponse | MethodFault) => { if (AngularXmlrpcService.instanceOfMethodResponse(data)) { - // FIXME: Make the cast without the unknown possible - return data.value as unknown as Distro; + if (!AngularXmlrpcService.instanceOfXmlRpcStruct(data.value)) { + throw new Error("Expected XML-RPC Struct not something else!") + } + const result = this.rebuildItem(data.value) + return result as Distro; } else if (AngularXmlrpcService.instanceOfMethodFault(data)) { throw new Error('Getting the requested distro failed with code "' + data.faultCode + '" and error message "' + data.faultString + '"'); @@ -623,8 +647,10 @@ export class CobblerApiService { .pipe( map>((data: MethodResponse | MethodFault) => { if (AngularXmlrpcService.instanceOfMethodResponse(data)) { - // FIXME: Make the cast without the unknown possible - return data.value as unknown as Array; + if (!AngularXmlrpcService.instanceOfXmlRpcArray(data.value)) { + throw new Error("Expected XML-RPC Array but got something else!") + } + return data.value.data as Array; } else if (AngularXmlrpcService.instanceOfMethodFault(data)) { throw new Error('Getting the item names failed with code "' + data.faultCode + '" and error message "' + data.faultString + '"'); @@ -639,8 +665,17 @@ export class CobblerApiService { .pipe( map>((data: MethodResponse | MethodFault) => { if (AngularXmlrpcService.instanceOfMethodResponse(data)) { - // FIXME: Make the cast without the unknown possible - return data.value as unknown as Array; + if (!AngularXmlrpcService.instanceOfXmlRpcArray(data.value)) { + throw new Error("Expected XML-RPC Array!") + } + const result = [] + data.value.data.forEach(value => { + if (!AngularXmlrpcService.instanceOfXmlRpcStruct(value)) { + throw new Error("Expected XML-RPC Struct!") + } + result.push(this.rebuildItem(value)) + }) + return result as Array; } else if (AngularXmlrpcService.instanceOfMethodFault(data)) { throw new Error('Getting all distros failed with code "' + data.faultCode + '" and error message "' + data.faultString + '"'); diff --git a/projects/cobbler-api/src/lib/custom-types/items.ts b/projects/cobbler-api/src/lib/custom-types/items.ts index 76efed68..107667fd 100644 --- a/projects/cobbler-api/src/lib/custom-types/items.ts +++ b/projects/cobbler-api/src/lib/custom-types/items.ts @@ -6,25 +6,30 @@ export interface Item { } export interface Distro extends Item { - source_repos: Array; - tree_build_time: string; + is_subobject: boolean; + source_repos: Array; + tree_build_time: number; arch: string; autoinstall_meta: object; - boot_files: Array; - boot_loader: string; + boot_files: object; + boot_loaders: string | Array; breed: string; comment: string; - fetchable_files: Array; + parent: string; + fetchable_files: object; initrd: string; kernel: string; remote_boot_initrd: string; remote_boot_kernel: string; + remote_grub_initrd: string; + remote_grub_kernel: string; kernel_options: object; kernel_options_post: object; - mgmt_classes: Array; + mgmt_classes: Array; + mgmt_parameters: object; name: string; os_version: string; - owners: Array; + owners: string | Array; redhat_management_key: string; template_files: object; }