From f99b7e9291825099e46067c54ac10418727845f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 11:56:54 +0200 Subject: [PATCH 001/104] renaming webapplication.py into webApplication.py --- itopapi/model/webapplication.py | 132 -------------------------------- 1 file changed, 132 deletions(-) delete mode 100644 itopapi/model/webapplication.py diff --git a/itopapi/model/webapplication.py b/itopapi/model/webapplication.py deleted file mode 100644 index 9435f80..0000000 --- a/itopapi/model/webapplication.py +++ /dev/null @@ -1,132 +0,0 @@ -# -*- coding: utf8 -*-fr -# pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements -""" -ItopapiWebApplication is a abstraction of Rack representation on iTop -""" - -from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod -from itopapi.model.rack import ItopapiRack - -__version__ = '1.0' -__authors__ = ['Guillaume Philippon '] - - -class ItopapiWebApplication(ItopapiPrototype): - """ - ItopapiWebApplication is a object that represent a WebApplication from iTop - """ - - # Configuration specific to itop - itop = { - # Name of the class in Itop - 'name': 'WebApplication', - # Define which fields to save when creating or updating from the python API - 'save': ['name', 'url', 'business_criticity', - 'move2production', 'description'], - 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, - {'id': 'webserver_id', 'name': 'webserver_name', 'table': 'WebServer'}, - ], - 'list_types': {'services_list': 'Service'} - } - - @staticmethod - def find(key): - """ Retrieve one or mor instance of WebApplication with the given key or criteria """ - return ItopapiPrototype.find(ItopapiWebApplication, key) - - @staticmethod - def find_by_name(name): - return ItopapiPrototype.find_by_name(ItopapiWebApplication, name) - - @staticmethod - def find_all(): - """ Retrieve all instance of WebApplication """ - return ItopapiPrototype.find_all(ItopapiWebApplication) - - def __init__(self, data=None): - super(ItopapiWebApplication, self).__init__(data) - - ################################## - # Properties/General Information # - ################################## - # WebApplication's organization id. Call findOrganization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # WebApplication's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # WebApplication's organization name - self.organization_name = None - # WebServer hosting the application - self.webserver_id = None - self.webserver_id_friendlyname = None - self.webserver_name = None - # WebApplication's URL - self.url = None - # WebApplication's business criticity. Values within [high, medium, low] - self.business_criticity = None - # WebApplication's move to production date - self.move2production = None - # WebApplication's description, as a free text - self.description = None - - ################################## - # Contacts # - ################################## - # WebApplication's contacts list - self.contacts_list = {} - - ################################## - # Documents # - ################################## - # WebApplication's documents list - self.documents_list = {} - - ################################## - # Tickets # - ################################## - # WebApplication's tickets list - self.tickets_list = {} - - ################################## - # Application solutions # - ################################## - # WebApplication's application solutions list - self.applicationsolution_list = {} - - ################################## - # Provider contracts # - ################################## - # WebApplication's provider contracts list - self.providercontracts_list = {} - - ################################## - # Services # - ################################## - # WebApplication's services list - self.services_list = {} - - def load_from_json_quattor(self, json_quattor): - """ - Create a ItopapiWebApplication description based on quattor s JSON output - :param json_quattor: json - """ - pass - - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this WebApplication - """ - if self.org_id is not None: - # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) - raise ItopapiUnimplementedMethod() - return None - - def find_web_server(self): - """ - Retrieve the ItopapiOrganization corresponding to this WebApplication - """ - if self.webserver_id is not None: - # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) - raise ItopapiUnimplementedMethod() - return None From b4fca701f53d71bab37cdfa07682b19845c72c62 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 11:57:40 +0200 Subject: [PATCH 002/104] renaming part 2 --- itopapi/model/webApplication.py | 132 ++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 itopapi/model/webApplication.py diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py new file mode 100644 index 0000000..9435f80 --- /dev/null +++ b/itopapi/model/webApplication.py @@ -0,0 +1,132 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements +""" +ItopapiWebApplication is a abstraction of Rack representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.rack import ItopapiRack + +__version__ = '1.0' +__authors__ = ['Guillaume Philippon '] + + +class ItopapiWebApplication(ItopapiPrototype): + """ + ItopapiWebApplication is a object that represent a WebApplication from iTop + """ + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'WebApplication', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'url', 'business_criticity', + 'move2production', 'description'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'webserver_id', 'name': 'webserver_name', 'table': 'WebServer'}, + ], + 'list_types': {'services_list': 'Service'} + } + + @staticmethod + def find(key): + """ Retrieve one or mor instance of WebApplication with the given key or criteria """ + return ItopapiPrototype.find(ItopapiWebApplication, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiWebApplication, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of WebApplication """ + return ItopapiPrototype.find_all(ItopapiWebApplication) + + def __init__(self, data=None): + super(ItopapiWebApplication, self).__init__(data) + + ################################## + # Properties/General Information # + ################################## + # WebApplication's organization id. Call findOrganization to get the full information or just + # use org_id_friendlyname and organization_name + self.org_id = None + # WebApplication's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # WebApplication's organization name + self.organization_name = None + # WebServer hosting the application + self.webserver_id = None + self.webserver_id_friendlyname = None + self.webserver_name = None + # WebApplication's URL + self.url = None + # WebApplication's business criticity. Values within [high, medium, low] + self.business_criticity = None + # WebApplication's move to production date + self.move2production = None + # WebApplication's description, as a free text + self.description = None + + ################################## + # Contacts # + ################################## + # WebApplication's contacts list + self.contacts_list = {} + + ################################## + # Documents # + ################################## + # WebApplication's documents list + self.documents_list = {} + + ################################## + # Tickets # + ################################## + # WebApplication's tickets list + self.tickets_list = {} + + ################################## + # Application solutions # + ################################## + # WebApplication's application solutions list + self.applicationsolution_list = {} + + ################################## + # Provider contracts # + ################################## + # WebApplication's provider contracts list + self.providercontracts_list = {} + + ################################## + # Services # + ################################## + # WebApplication's services list + self.services_list = {} + + def load_from_json_quattor(self, json_quattor): + """ + Create a ItopapiWebApplication description based on quattor s JSON output + :param json_quattor: json + """ + pass + + def find_organization(self): + """ + Retrieve the ItopapiOrganization corresponding to this WebApplication + """ + if self.org_id is not None: + # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) + raise ItopapiUnimplementedMethod() + return None + + def find_web_server(self): + """ + Retrieve the ItopapiOrganization corresponding to this WebApplication + """ + if self.webserver_id is not None: + # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) + raise ItopapiUnimplementedMethod() + return None From 09bef07642258ebfed81dca0149a1f1c9605f3d5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 12:01:51 +0200 Subject: [PATCH 003/104] typo --- itopapi/model/applicationSolution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index a4ede64..d1991a3 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -34,7 +34,7 @@ def find_by_name(name): @staticmethod def find_all(): - """ Retrieve all instance of OSFamily """ + """ Retrieve all instance of ApplicationSolution """ return ItopapiPrototype.find_all(ItopapiApplicationSolution) """ From d9055e559a23e539274f74be9ee1d9e99ecc7976 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 12:12:38 +0200 Subject: [PATCH 004/104] Comments were the other way around --- itopapi/model/applicationSolution.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index d1991a3..f40e66b 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -45,21 +45,21 @@ def __init__(self, data=None): ################################## # Properties # ################################## - self.org_id = None # Application Solution's organization id. Call findOrganization to get the full information or just use # org_id_friendlyname and organization_name - self.org_id_friendlyname = None + self.org_id = None # Application Solution's organization friendly name. Not sure the difference with organization_name - self.organization_name = None + self.org_id_friendlyname = None # Application Solution's organization name - self.status = None + self.organization_name = None # Application Solution's status. Values within [inactive, active] - self.business_criticity = None + self.status = None # Application Solution's business criticity. Values within [high, medium, low] - self.move2production = None + self.business_criticity = None # Application Solution's move to production date - self.description = None + self.move2production = None # Application Solution's description, as a free text + self.description = None ################################## # Lists # ################################## From f54e2dad032719cff14ba10661c1cb946b870182 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 14:34:08 +0200 Subject: [PATCH 005/104] Added Organization, DeliveryModel and all find_organization methods --- itopapi/model/__init__.py | 1 + itopapi/model/deliveryModel.py | 62 ++++++++++++++++++++++++++++ itopapi/model/organization.py | 73 +++++++++++++++++++++++++++++++++ itopapi/model/prototype.py | 2 - itopapi/model/rack.py | 10 ++++- itopapi/model/server.py | 8 ++-- itopapi/model/subnet.py | 9 +++- itopapi/model/virtualMachine.py | 5 +-- itopapi/model/vlan.py | 8 +++- itopapi/model/webApplication.py | 10 ++--- itopapi/model/webServer.py | 5 +-- 11 files changed, 171 insertions(+), 22 deletions(-) create mode 100644 itopapi/model/deliveryModel.py create mode 100644 itopapi/model/organization.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 5d7df78..4cc3c10 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -18,4 +18,5 @@ from itopapi.model.webServer import ItopapiWebServer from itopapi.model.webApplication import ItopapiWebApplication from itopapi.model.service import ItopapiService +from itopapi.model.organization import ItopapiOrganization from itopapi.model.applicationSolution import ItopapiApplicationSolution diff --git a/itopapi/model/deliveryModel.py b/itopapi/model/deliveryModel.py new file mode 100644 index 0000000..8920e2a --- /dev/null +++ b/itopapi/model/deliveryModel.py @@ -0,0 +1,62 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiDeliveryModel is a abstraction of Organization representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + +class ItopapiDeliveryModel(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'DeliveryModel', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'description'], + 'foreign_keys': [ + {'id': 'organization_id', 'name': 'organization_name', 'table': 'Organization'}, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ApplicationSolution with the given key or criteria """ + return ItopapiPrototype.find(ItopapiDeliveryModel, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiDeliveryModel, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSFamily """ + return ItopapiPrototype.find_all(ItopapiDeliveryModel) + + """ + ItopapiDeliveryModel is a object that represent an Application Solution from iTop + """ + def __init__(self, data=None): + super(ItopapiDeliveryModel, self).__init__(data) + + self.description = None + self.org_id = None + self.organization_name = None + self.org_id_friendlyname = None + + ################################## + # Lists # + ################################## + self.customers_list = [] + self.contacts_list = [] + + def find_organization(self): + """ + Retrieve the parent ItopapiOrganization + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None \ No newline at end of file diff --git a/itopapi/model/organization.py b/itopapi/model/organization.py new file mode 100644 index 0000000..d40c0bd --- /dev/null +++ b/itopapi/model/organization.py @@ -0,0 +1,73 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiOrganization is a abstraction of Organization representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.deliveryModel import ItopapiDeliveryModel + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + +class ItopapiOrganization(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Organization', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'code', 'status'], + 'foreign_keys': [ + {'id': 'parent_id', 'name': 'parent_name', 'table': 'Organization'}, + {'id': 'deliverymodel_id', 'name': 'deliverymodel_name', 'table': 'DeliveryModel'}, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ApplicationSolution with the given key or criteria """ + return ItopapiPrototype.find(ItopapiOrganization, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiOrganization, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSFamily """ + return ItopapiPrototype.find_all(ItopapiOrganization) + + """ + ItopapiOrganization is a object that represent an Application Solution from iTop + """ + def __init__(self, data=None): + super(ItopapiOrganization, self).__init__(data) + + self.code = None + # Application Solution's status. Values within [inactive, active] + self.status = None + # Parent information + self.parent_id = None + self.parent_name = None + self.parent_id_friendlyname = None + # Delivery model + self.deliverymodel_id = None + self.deliverymodel_name = None + self.deliverymodel_id_friendlyname = None + + def find_parent(self): + """ + Retrieve the parent ItopapiOrganization + """ + if self.parent_id is not None: + return ItopapiOrganization.find(self.parent_id) + return None + + def find_delivery_model(self): + """ + Retrieve the ItopapiDeliveryModel associated with this entry + """ + if self.deliverymodel_id is not None: + return ItopapiDeliveryModel.find(self.deliverymodel_id) + return None \ No newline at end of file diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 76a1c20..6353b57 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -137,8 +137,6 @@ def find(itop_class, key): if data['objects'] is None: return None - ItopapiPrototype.parse_data(data) - objects = [] for information in data['objects']: obj = itop_class({}) diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index 6d95e04..8c3ff04 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -123,7 +123,15 @@ def __init__(self, data=None): # Rack's services list self.services_list = {} - # TODO WTF is this doing here?!? + # Other lists self.applicationsolution_list = None self.softwares_list = None self.logicalvolumes_list = None + + def find_organization(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 031abc2..b8d2c18 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -5,7 +5,6 @@ """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod -from itopapi.model.rack import ItopapiRack __version__ = '1.0' __authors__ = ['Guillaume Philippon '] @@ -231,7 +230,7 @@ def find_rack(self): Retrieve the ItopapiRack corresponding to this server """ if self.rack_id is not None: - return ItopapiRack.find(self.rack_id) + ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None def find_organization(self): @@ -239,13 +238,12 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_location(self): """ - Retrieve the ItopapiLocation corresponding to this server + Retrieve the ItopapiLocation related to this instance """ if self.location_id is not None: # TODO define ItopapiLocation return ItopapiLocation.find(self.location_id) diff --git a/itopapi/model/subnet.py b/itopapi/model/subnet.py index 5a327be..992f771 100644 --- a/itopapi/model/subnet.py +++ b/itopapi/model/subnet.py @@ -61,4 +61,11 @@ def __init__(self, data=None): # VLANs associated with this Subnet self.vlans_list = None - # TODO findOrganization method, based on Server \ No newline at end of file + + def find_organization(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None \ No newline at end of file diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index cae3a21..10c2fc7 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -166,11 +166,10 @@ def load_from_json_quattor(self, json_quattor): def find_organization(self): """ - Retrieve the ItopapiOrganization corresponding to this VirtualMachine + Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_os_family(self): diff --git a/itopapi/model/vlan.py b/itopapi/model/vlan.py index 7c3949a..6e0b2a7 100644 --- a/itopapi/model/vlan.py +++ b/itopapi/model/vlan.py @@ -60,4 +60,10 @@ def __init__(self, data=None): # subnets self.subnets_list = None - # TODO findOrganization method, based on Server \ No newline at end of file + def find_organization(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None \ No newline at end of file diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 9435f80..aa168db 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -115,18 +115,16 @@ def load_from_json_quattor(self, json_quattor): def find_organization(self): """ - Retrieve the ItopapiOrganization corresponding to this WebApplication + Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_web_server(self): """ - Retrieve the ItopapiOrganization corresponding to this WebApplication + Retrieve the ItopapiWebServer corresponding to this WebApplication """ if self.webserver_id is not None: - # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('WebServer').find(self.webserver_id) return None diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 7c5ce72..f3576a6 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -162,11 +162,10 @@ def load_from_json_quattor(self, json_quattor): def find_organization(self): """ - Retrieve the ItopapiOrganization corresponding to this WebServer + Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - # TODO define ItopapiOrganization return ItopapiOrganization.find(self.org_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_system(self): From 7b7dc1b46910f8b3347d6ffbc43fbcb2e782517d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 17:13:57 +0200 Subject: [PATCH 006/104] Added enclosure and location --- itopapi/model/__init__.py | 2 + itopapi/model/applicationSolution.py | 4 +- itopapi/model/deliveryModel.py | 2 +- itopapi/model/enclosure.py | 115 +++++++++++++++++++++++++++ itopapi/model/location.py | 70 ++++++++++++++++ itopapi/model/organization.py | 2 +- itopapi/model/os.py | 4 +- itopapi/model/physicalInterface.py | 2 +- itopapi/model/prototype.py | 6 +- itopapi/model/rack.py | 14 +++- itopapi/model/server.py | 25 +++--- itopapi/model/service.py | 4 +- itopapi/model/subnet.py | 4 +- itopapi/model/virtualMachine.py | 4 +- itopapi/model/vlan.py | 4 +- itopapi/model/webApplication.py | 6 +- itopapi/model/webServer.py | 6 +- 17 files changed, 236 insertions(+), 38 deletions(-) create mode 100644 itopapi/model/enclosure.py create mode 100644 itopapi/model/location.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 4cc3c10..b1de78b 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -19,4 +19,6 @@ from itopapi.model.webApplication import ItopapiWebApplication from itopapi.model.service import ItopapiService from itopapi.model.organization import ItopapiOrganization +from itopapi.model.location import ItopapiLocation +from itopapi.model.enclosure import ItopapiEnclosure from itopapi.model.applicationSolution import ItopapiApplicationSolution diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index f40e66b..bad12fc 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -38,14 +38,14 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiApplicationSolution) """ - ItopapiApplicationSolution is a object that represent an Application Solution from iTop + ItopapiApplicationSolution is a object that represents an Application Solution from iTop """ def __init__(self, data=None): super(ItopapiApplicationSolution, self).__init__(data) ################################## # Properties # ################################## - # Application Solution's organization id. Call findOrganization to get the full information or just use + # Application Solution's organization id. Call find_organization to get the full information or just use # org_id_friendlyname and organization_name self.org_id = None # Application Solution's organization friendly name. Not sure the difference with organization_name diff --git a/itopapi/model/deliveryModel.py b/itopapi/model/deliveryModel.py index 8920e2a..5743352 100644 --- a/itopapi/model/deliveryModel.py +++ b/itopapi/model/deliveryModel.py @@ -37,7 +37,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiDeliveryModel) """ - ItopapiDeliveryModel is a object that represent an Application Solution from iTop + ItopapiDeliveryModel is a object that represents an Application Solution from iTop """ def __init__(self, data=None): super(ItopapiDeliveryModel, self).__init__(data) diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py new file mode 100644 index 0000000..07aec6a --- /dev/null +++ b/itopapi/model/enclosure.py @@ -0,0 +1,115 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiEnclosure is a abstraction of Rack representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiEnclosure(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Enclosure', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'nb_u', 'serialnumber', 'asset_number', + 'move2production', 'purchase_date', 'end_of_warranty', 'description'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'location_id', 'name': 'location_name', 'table': 'Localization'}, + {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, + {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, + {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, + ] + } + @staticmethod + def find(key): + """ Retrieve one or more instance of Enclosure with the given key or criteria """ + return ItopapiPrototype.find(ItopapiEnclosure, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiEnclosure, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Enclosure """ + return ItopapiPrototype.find_all(ItopapiEnclosure) + + """ + """ + def __init__(self, data=None): + super(ItopapiEnclosure, self).__init__(data) + # Enclosure's organization id. Call find_organization to get the full information or just + # use org_id_friendlyname and organization_name + self.org_id = None + # Enclosure's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Enclosure's organization name + self.organization_name = None + # Enclosure's status. Values within [implementation, obsolete, production, stock] + self.status = None + # Enclosure's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Enclosure's location id. Call find_location to get the full information or just use + # location_id_friendlyname and location_name + self.location_id = None + # Enclosure's location id's friendly name. Not sure the difference with location_name + self.location_id_friendlyname = None + # Enclosure's location name + self.location_name = None + # Enclosure's rack id. Call findRack to get the full information or just use rack_id + # friendlyname and rack_name + self.rack_id = None + # Enclosure's rack id's friendly name. Not sure the difference with rack_name + self.rack_id_friendlyname = None + # Enclosure's rack name + self.rack_name = None + self.brand_id = None + self.brand_id_friendlyname = None + self.brand_name = None + self.model_id = None + self.model_id_friendlyname = None + self.model_name = None + # Rack units + self.nb_u = None + # Serial number + self.serialnumber = None + # Asset number + self.asset_number = None + # Server's move to production date + self.move2production = None + # Server's purchase date + self.purchase_date = None + # Server's end of warranty date + self.end_of_warranty = None + self.description = None + + def find_organization(self): + """ + Retrieve the ItopapiOrganization corresponding to this server + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None + + def find_location(self): + """ + Retrieve the ItopapiLocation related to this instance + """ + if self.location_id is not None: + ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return None + + def find_rack(self): + """ + Retrieve the ItopapiRack corresponding to this server + """ + if self.rack_id is not None: + ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) + return None diff --git a/itopapi/model/location.py b/itopapi/model/location.py new file mode 100644 index 0000000..df6b5b2 --- /dev/null +++ b/itopapi/model/location.py @@ -0,0 +1,70 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiLocation is a abstraction of a Location representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiLocation(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Location', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'address', 'postal_code', 'city', 'country'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of OSFamily with the given key or criteria """ + return ItopapiPrototype.find(ItopapiLocation, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiLocation, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSFamily """ + return ItopapiPrototype.find_all(ItopapiLocation) + + """ + ItopapiLocation is an object that represents an OS Family from iTop + """ + def __init__(self, data=None): + super(ItopapiLocation, self).__init__(data) + # Location's status. Values within [inactive, active] + self.status = None + # Location's organization id. Call find_organization to get the full information or just + # use org_id_friendlyname and organization_name + self.org_id = None + # Server's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Server's organization name + self.organization_name = None + # Location's street address. Generally multiline + self.address = None + self.postal_code = None + self.city = None + self.country = None + # Lists + self.person_list = {} + self.physicaldevice_list = {} + + + def find_organization(self): + """ + Retrieve the ItopapiOrganization corresponding to this server + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None diff --git a/itopapi/model/organization.py b/itopapi/model/organization.py index d40c0bd..dada9c9 100644 --- a/itopapi/model/organization.py +++ b/itopapi/model/organization.py @@ -39,7 +39,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiOrganization) """ - ItopapiOrganization is a object that represent an Application Solution from iTop + ItopapiOrganization is a object that represents an Application Solution from iTop """ def __init__(self, data=None): super(ItopapiOrganization, self).__init__(data) diff --git a/itopapi/model/os.py b/itopapi/model/os.py index 89c7004..76ac065 100644 --- a/itopapi/model/os.py +++ b/itopapi/model/os.py @@ -7,7 +7,7 @@ from itopapi.model.prototype import ItopapiPrototype __version__ = '1.0' -__authors__ = ['Guillaume Philippon '] +__authors__ = ['Julien Nauroy '] class ItopapiOSFamily(ItopapiPrototype): @@ -36,7 +36,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiOSFamily) """ - ItopapiOSFamily is an object that represent an OS Family from iTop + ItopapiOSFamily is an object that represents an OS Family from iTop """ def __init__(self, data=None): super(ItopapiOSFamily, self).__init__(data) diff --git a/itopapi/model/physicalInterface.py b/itopapi/model/physicalInterface.py index 6115ba4..09ba42c 100644 --- a/itopapi/model/physicalInterface.py +++ b/itopapi/model/physicalInterface.py @@ -43,7 +43,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiPhysicalInterface) """ - ItopapiPhysicalInterface is an object that represent a PhysicalInterface from iTop + ItopapiPhysicalInterface is an object that represents a PhysicalInterface from iTop """ def __init__(self, data=None): super(ItopapiPhysicalInterface, self).__init__(data) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 6353b57..8d29f22 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -120,7 +120,7 @@ def find(itop_class, key): Find a list of objects given its id or some criteria passed as a dictionary :param itop_class: :param key: - :return: array or None if there is no object + :return: array """ json_data = json.dumps({ 'operation': 'core/get', @@ -135,7 +135,7 @@ def find(itop_class, key): # If there's no object to process, return immediately if data['objects'] is None: - return None + return [] objects = [] for information in data['objects']: @@ -145,6 +145,8 @@ def find(itop_class, key): obj.__dict__.update(data['objects'][information]['fields']) obj.__process_lists() objects.append(obj) + print obj.__dict__ + exit(0) # Return None, as a commodity, if there's 0 result if len(objects) == 0: diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index 8c3ff04..802c765 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -12,7 +12,7 @@ class ItopapiRack(ItopapiPrototype): """ - ItopapiRack is a object that represent a Rack from iTop + ItopapiRack is a object that represents a Rack from iTop """ """ Configuration specific to itop """ @@ -48,7 +48,7 @@ def __init__(self, data=None): ################################## # Properties # ################################## - # Rack's organization id. Call findOrganization to get the full information or just use + # Rack's organization id. Call find_organization to get the full information or just use # org_id_friendlyname and organization_name self.org_id = None # Rack's organization friendly name. Not sure the difference with organization_name @@ -59,7 +59,7 @@ def __init__(self, data=None): self.status = None # Rack's business criticity. Values within [high, medium, low] self.business_criticity = None - # Rack's location id. Call findLocation to get the full information or just use location_id + # Rack's location id. Call find_location to get the full information or just use location_id # _friendlyname and location_name self.location_id = None # Rack's location id's friendly name. Not sure the difference with location_name @@ -135,3 +135,11 @@ def find_organization(self): if self.org_id is not None: ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None + + def find_location(self): + """ + Retrieve the ItopapiLocation related to this instance + """ + if self.location_id is not None: + ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index b8d2c18..d833375 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -7,12 +7,12 @@ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod __version__ = '1.0' -__authors__ = ['Guillaume Philippon '] +__authors__ = ['Julien Nauroy '] class ItopapiServer(ItopapiPrototype): """ - ItopapiServers is a object that represent a Servers from iTop + ItopapiServers is a object that represents a Servers from iTop """ # Configuration specific to itop @@ -20,17 +20,19 @@ class ItopapiServer(ItopapiPrototype): # Name of the class in Itop 'name': 'Server', # Define which fields to save when creating or updating from the python API - 'save': ['name', 'status', 'business_criticity', - 'rack_id', 'enclosure_id', 'brand_id', 'model_id', 'managementip', + 'save': ['name', 'status', 'business_criticity', 'managementip', 'cpu', 'ram', 'nb_u', 'serialnumber', 'asset_number', 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, {'id': 'location_id', 'name': 'location_name', 'table': 'Localization'}, + {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, + {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, + {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, + {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, - # TODO which is the relevant table? {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, ] @@ -56,7 +58,7 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # Server's organization id. Call findOrganization to get the full information or just + # Server's organization id. Call find_organization to get the full information or just # use org_id_friendlyname and organization_name self.org_id = None # Server's organization friendly name. Not sure the difference with organization_name @@ -67,7 +69,7 @@ def __init__(self, data=None): self.status = None # Server's business criticity. Values within [high, medium, low] self.business_criticity = None - # Server's location id. Call findLocation to get the full information or just use + # Server's location id. Call find_location to get the full information or just use # location_id_friendlyname and location_name self.location_id = None # Server's location id's friendly name. Not sure the difference with location_name @@ -79,7 +81,7 @@ def __init__(self, data=None): self.rack_id = None # Server's rack id's friendly name. Not sure the difference with rack_name self.rack_id_friendlyname = None - # Server's rack name""" + # Server's rack name self.rack_name = None # Server's enclosure (chassis) id. Call findEnclosure to get the full information or just # use enclosure_id_friendlyname and enclosure_name @@ -118,6 +120,7 @@ def __init__(self, data=None): self.ram = None # Rack units self.nb_u = None + # Server's serial number self.serialnumber = None # Server's asset number self.asset_number = None @@ -246,8 +249,7 @@ def find_location(self): Retrieve the ItopapiLocation related to this instance """ if self.location_id is not None: - # TODO define ItopapiLocation return ItopapiLocation.find(self.location_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('Location').find(self.location_id) return None def find_enclosure(self): @@ -255,8 +257,7 @@ def find_enclosure(self): Retrieve the ItopapiEnclosure corresponding to this server """ if self.enclosure_id is not None: - # TODO define ItopapiEnclosure return ItopapiEnclosure.find(self.enclosure_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None def find_brand(self): diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 51c008d..8e3566e 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -39,7 +39,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiService) """ - ItopapiPhysicalInterface is an object that represent a PhysicalInterface from iTop + ItopapiPhysicalInterface is an object that represents a PhysicalInterface from iTop """ def __init__(self, data=None): super(ItopapiService, self).__init__(data) @@ -60,4 +60,4 @@ def __init__(self, data=None): self.providercontracts_list = None self.functionalcis_list = None - # TODO findOrganization method, based on Server \ No newline at end of file + # TODO find_organization method, based on Server \ No newline at end of file diff --git a/itopapi/model/subnet.py b/itopapi/model/subnet.py index 992f771..403192b 100644 --- a/itopapi/model/subnet.py +++ b/itopapi/model/subnet.py @@ -39,7 +39,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiSubnet) """ - ItopapiPhysicalInterface is an object that represent a PhysicalInterface from iTop + ItopapiPhysicalInterface is an object that represents a PhysicalInterface from iTop """ def __init__(self, data=None): super(ItopapiSubnet, self).__init__(data) @@ -49,7 +49,7 @@ def __init__(self, data=None): self.ip_mask = None # Subnet name self.subnet_name = None - # Subnet's organization id. Call findOrganization to get the full information or just use + # Subnet's organization id. Call find_organization to get the full information or just use # org_id_friendlyname and organization_name self.org_id = None # Subnet's organization friendly name. Not sure the difference with organization_name diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 10c2fc7..5661078 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -43,7 +43,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiVirtualMachine) """ - ItopapiPhysicalInterface is an object that represent a PhysicalInterface from iTop + ItopapiPhysicalInterface is an object that represents a PhysicalInterface from iTop """ def __init__(self, data=None): super(ItopapiVirtualMachine, self).__init__(data) @@ -51,7 +51,7 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # VirtualMachine's organization id. Call findOrganization to get the full information or just + # VirtualMachine's organization id. Call find_organization to get the full information or just # use org_id_friendlyname and organization_name self.org_id = None # VirtualMachine's organization friendly name. Not sure the difference with organization_name diff --git a/itopapi/model/vlan.py b/itopapi/model/vlan.py index 6e0b2a7..75db39a 100644 --- a/itopapi/model/vlan.py +++ b/itopapi/model/vlan.py @@ -40,13 +40,13 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiVLAN) """ - ItopapiPhysicalInterface is an object that represent a PhysicalInterface from iTop + ItopapiPhysicalInterface is an object that represents a PhysicalInterface from iTop """ def __init__(self, data=None): super(ItopapiVLAN, self).__init__(data) # VLAN tag, replaces the "name" value for other classes self.vlan_tag = None - # VLAN's organization id. Call findOrganization to get the full information or just use + # VLAN's organization id. Call find_organization to get the full information or just use # org_id_friendlyname and organization_name self.org_id = None # VLAN's organization friendly name. Not sure the difference with organization_name diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index aa168db..2a3a568 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -8,12 +8,12 @@ from itopapi.model.rack import ItopapiRack __version__ = '1.0' -__authors__ = ['Guillaume Philippon '] +__authors__ = ['Julien Nauroy '] class ItopapiWebApplication(ItopapiPrototype): """ - ItopapiWebApplication is a object that represent a WebApplication from iTop + ItopapiWebApplication is a object that represents a WebApplication from iTop """ # Configuration specific to itop @@ -50,7 +50,7 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # WebApplication's organization id. Call findOrganization to get the full information or just + # WebApplication's organization id. Call find_organization to get the full information or just # use org_id_friendlyname and organization_name self.org_id = None # WebApplication's organization friendly name. Not sure the difference with organization_name diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index f3576a6..6991717 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -8,12 +8,12 @@ from itopapi.model.rack import ItopapiRack __version__ = '1.0' -__authors__ = ['Guillaume Philippon '] +__authors__ = ['Julien Nauroy '] class ItopapiWebServer(ItopapiPrototype): """ - ItopapiWebServer is a object that represent a WebServer from iTop + ItopapiWebServer is a object that represents a WebServer from iTop """ # Configuration specific to itop @@ -50,7 +50,7 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # WebServer's organization id. Call findOrganization to get the full information or just + # WebServer's organization id. Call find_organization to get the full information or just # use org_id_friendlyname and organization_name self.org_id = None # WebServer's organization friendly name. Not sure the difference with organization_name From 161633f975e1819ac5c7bacc419da4457cc0a468 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 17:18:18 +0200 Subject: [PATCH 007/104] Removing debug commands --- itopapi/model/prototype.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 8d29f22..5d609e7 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -145,8 +145,6 @@ def find(itop_class, key): obj.__dict__.update(data['objects'][information]['fields']) obj.__process_lists() objects.append(obj) - print obj.__dict__ - exit(0) # Return None, as a commodity, if there's 0 result if len(objects) == 0: From d3aa3934121130263d33c771995317771d606230 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 18:19:41 +0200 Subject: [PATCH 008/104] Added Brand and find_brand --- itopapi/model/__init__.py | 1 + itopapi/model/brand.py | 44 ++++++++++++++++++++++++++++++++++++++ itopapi/model/enclosure.py | 8 +++++++ itopapi/model/server.py | 3 +-- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 itopapi/model/brand.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index b1de78b..32b1aa9 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -21,4 +21,5 @@ from itopapi.model.organization import ItopapiOrganization from itopapi.model.location import ItopapiLocation from itopapi.model.enclosure import ItopapiEnclosure +from itopapi.model.brand import ItopapiBrand from itopapi.model.applicationSolution import ItopapiApplicationSolution diff --git a/itopapi/model/brand.py b/itopapi/model/brand.py new file mode 100644 index 0000000..4168472 --- /dev/null +++ b/itopapi/model/brand.py @@ -0,0 +1,44 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiBrand is a abstraction of Brand representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiBrand(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Brand', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Brand with the given key or criteria """ + return ItopapiPrototype.find(ItopapiBrand, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiBrand, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Brand """ + return ItopapiPrototype.find_all(ItopapiBrand) + + """ + ItopapiBrand is an object that represents a Brand from iTop + """ + def __init__(self, data=None): + super(ItopapiBrand, self).__init__(data) + # Physical devices using this brand + self.physicaldevices_list = None \ No newline at end of file diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 07aec6a..11efc19 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -113,3 +113,11 @@ def find_rack(self): if self.rack_id is not None: ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None + + def find_brand(self): + """ + Retrieve the ItopapiBrand corresponding to this server + """ + if self.brand_id is not None: + ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) + return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index d833375..24159c4 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -265,8 +265,7 @@ def find_brand(self): Retrieve the ItopapiBrand corresponding to this server """ if self.brand_id is not None: - # TODO define ItopapiBrand return ItopapiBrand.find(self.brand_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) return None def find_model(self): From 936c56adf2a7b171c83773cfd06843ead6031597 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 May 2015 22:26:20 +0200 Subject: [PATCH 009/104] Added Brand --- itopapi/model/__init__.py | 1 + itopapi/model/brand.py | 2 +- itopapi/model/enclosure.py | 11 ++++++- itopapi/model/model.py | 61 ++++++++++++++++++++++++++++++++++++++ itopapi/model/server.py | 2 +- 5 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 itopapi/model/model.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 32b1aa9..5005b64 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -22,4 +22,5 @@ from itopapi.model.location import ItopapiLocation from itopapi.model.enclosure import ItopapiEnclosure from itopapi.model.brand import ItopapiBrand +from itopapi.model.model import ItopapiModel from itopapi.model.applicationSolution import ItopapiApplicationSolution diff --git a/itopapi/model/brand.py b/itopapi/model/brand.py index 4168472..af1f9b5 100644 --- a/itopapi/model/brand.py +++ b/itopapi/model/brand.py @@ -41,4 +41,4 @@ def find_all(): def __init__(self, data=None): super(ItopapiBrand, self).__init__(data) # Physical devices using this brand - self.physicaldevices_list = None \ No newline at end of file + self.physicaldevices_list = None diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 11efc19..0b03726 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -116,8 +116,17 @@ def find_rack(self): def find_brand(self): """ - Retrieve the ItopapiBrand corresponding to this server + Retrieve the ItopapiBrand corresponding to this instance """ if self.brand_id is not None: ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) return None + + def find_model(self): + """ + Retrieve the ItopapiModel corresponding to this instance + """ + if self.model_id is not None: + ItopapiPrototype.get_itop_class('Model').find(self.model_id) + raise ItopapiUnimplementedMethod() + return None diff --git a/itopapi/model/model.py b/itopapi/model/model.py new file mode 100644 index 0000000..afd7899 --- /dev/null +++ b/itopapi/model/model.py @@ -0,0 +1,61 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiModel is a abstraction of Model representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiModel(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Model', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'type'], + 'foreign_keys': [ + {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Model with the given key or criteria """ + return ItopapiPrototype.find(ItopapiModel, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiModel, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Model """ + return ItopapiPrototype.find_all(ItopapiModel) + + """ + ItopapiModel is an object that represents a Model from iTop + """ + def __init__(self, data=None): + super(ItopapiModel, self).__init__(data) + # Physical devices using this brand + self.physicaldevices_list = None + self.brand_id = None + self.brand_id_friendlyname = None + self.brand_name = None + # Type of item the Brand refers to. Values are within + # [DiskArray, Enclosure, IPPhone, MobilePhone, NAS, NetworkDevice, PC, PDU, Peripheral, Phone, + # PowerSource, Printer, Rack, SANSwitch, Server, StorageSystem, Tablet, TapeLibrary] + self.type = None + + def find_brand(self): + """ + Retrieve the ItopapiBrand corresponding to this server + """ + if self.brand_id is not None: + ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) + return None \ No newline at end of file diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 24159c4..4106618 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -273,7 +273,7 @@ def find_model(self): Retrieve the ItopapiModel corresponding to this server """ if self.model_id is not None: - # TODO define ItopapiModel return ItopapiModel.find(self.model_id) + ItopapiPrototype.get_itop_class('Model').find(self.model_id) raise ItopapiUnimplementedMethod() return None From 95175ab3990cbe602e64cb20f6fcbdf1ac630b1f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 13 May 2015 11:28:10 +0200 Subject: [PATCH 010/104] Updated OSFamily and related functions --- itopapi/model/__init__.py | 2 +- itopapi/model/{os.py => osFamily.py} | 0 itopapi/model/server.py | 4 +--- itopapi/model/virtualMachine.py | 3 +-- 4 files changed, 3 insertions(+), 6 deletions(-) rename itopapi/model/{os.py => osFamily.py} (100%) diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 5005b64..fcb7cf4 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -10,7 +10,7 @@ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod from itopapi.model.rack import ItopapiRack from itopapi.model.server import ItopapiServer -from itopapi.model.os import ItopapiOSFamily +from itopapi.model.osFamily import ItopapiOSFamily from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.physicalInterface import ItopapiPhysicalInterface diff --git a/itopapi/model/os.py b/itopapi/model/osFamily.py similarity index 100% rename from itopapi/model/os.py rename to itopapi/model/osFamily.py diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 4106618..8fb2da1 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -274,7 +274,6 @@ def find_model(self): """ if self.model_id is not None: ItopapiPrototype.get_itop_class('Model').find(self.model_id) - raise ItopapiUnimplementedMethod() return None def find_os_family(self): @@ -282,8 +281,7 @@ def find_os_family(self): Retrieve the ItopapiOSFamily corresponding to this server """ if self.osfamily_id is not None: - # TODO define ItopapiOSFamily return ItopapiOSFamily.find(self.osfamily_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) return None def find_os_version(self): diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 5661078..cda2dc8 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -177,8 +177,7 @@ def find_os_family(self): Retrieve the ItopapiOSFamily corresponding to this VirtualMachine """ if self.osfamily_id is not None: - # TODO define ItopapiOSFamily return ItopapiOSFamily.find(self.osfamily_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) return None def find_os_version(self): From 1dae68e9bff707c407970922dbca40ae9df141d6 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 13 May 2015 11:33:23 +0200 Subject: [PATCH 011/104] Added OSVersion and related functions --- itopapi/model/__init__.py | 1 + itopapi/model/osVersion.py | 56 +++++++++++++++++++++++++++++++++ itopapi/model/server.py | 3 +- itopapi/model/virtualMachine.py | 5 ++- 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 itopapi/model/osVersion.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index fcb7cf4..3314c51 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -11,6 +11,7 @@ from itopapi.model.rack import ItopapiRack from itopapi.model.server import ItopapiServer from itopapi.model.osFamily import ItopapiOSFamily +from itopapi.model.osVersion import ItopapiOSVersion from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.physicalInterface import ItopapiPhysicalInterface diff --git a/itopapi/model/osVersion.py b/itopapi/model/osVersion.py new file mode 100644 index 0000000..790f576 --- /dev/null +++ b/itopapi/model/osVersion.py @@ -0,0 +1,56 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiOSVersion is a abstraction of Rack representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiOSVersion(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'OSVersion', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [ + {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of OSVersion with the given key or criteria """ + return ItopapiPrototype.find(ItopapiOSVersion, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiOSVersion, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSVersion """ + return ItopapiPrototype.find_all(ItopapiOSVersion) + + """ + ItopapiOSVersion is an object that represents an OS Version from iTop + """ + def __init__(self, data=None): + super(ItopapiOSVersion, self).__init__(data) + # OSFamily this OSVersion is attached to + self.osfamily_id = None + self.osfamily_id_friendlyname = None + self.osfamily_name = None + + def find_os_family(self): + """ + Retrieve the ItopapiOSFamily corresponding to this server + """ + if self.osfamily_id is not None: + ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) + return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 8fb2da1..8ce8ad6 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -289,8 +289,7 @@ def find_os_version(self): Retrieve the ItopapiOSVersion corresponding to this server """ if self.osversion_id is not None: - # TODO define ItopapiOSVersion return ItopapiOSVersion.find(self.osversion_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) return None def find_os_licence(self): diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index cda2dc8..b473ad3 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -182,11 +182,10 @@ def find_os_family(self): def find_os_version(self): """ - Retrieve the ItopapiOSVersion corresponding to this VirtualMachine + Retrieve the ItopapiOSVersion corresponding to this server """ if self.osversion_id is not None: - # TODO define ItopapiOSVersion return ItopapiOSVersion.find(self.osversion_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) return None def find_os_licence(self): From fc639642062e3718c022537a256bb6a48494ca9f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 13 May 2015 11:42:01 +0200 Subject: [PATCH 012/104] Added OSLicence and related methods --- itopapi/model/__init__.py | 1 + itopapi/model/osLicence.py | 83 +++++++++++++++++++++++++++++++++ itopapi/model/server.py | 3 +- itopapi/model/virtualMachine.py | 5 +- 4 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 itopapi/model/osLicence.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 3314c51..b9da67c 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -12,6 +12,7 @@ from itopapi.model.server import ItopapiServer from itopapi.model.osFamily import ItopapiOSFamily from itopapi.model.osVersion import ItopapiOSVersion +from itopapi.model.osLicence import ItopapiOSLicence from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.physicalInterface import ItopapiPhysicalInterface diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py new file mode 100644 index 0000000..7b66ffc --- /dev/null +++ b/itopapi/model/osLicence.py @@ -0,0 +1,83 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiOSLicence is a abstraction of Rack representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiOSLicence(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'OSLicence', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'usage_limit', 'description', 'perpetual', 'start_date', 'end_date', 'licence_key'], + 'foreign_keys': [ + {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of OSLicence with the given key or criteria """ + return ItopapiPrototype.find(ItopapiOSLicence, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiOSLicence, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSLicence """ + return ItopapiPrototype.find_all(ItopapiOSLicence) + + """ + ItopapiOSLicence is an object that represents an OSLicence from iTop + """ + def __init__(self, data=None): + super(ItopapiOSLicence, self).__init__(data) + self.osversion_id = None + self.osversion_id_friendlyname = None + self.osversion_name = None + # OSLicence's organization id. Call find_organization to get the full information or just + # use org_id_friendlyname and organization_name + self.org_id = None + # OSLicence's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # OSLicence's organization name + self.organization_name = None + # Number of concurrent users or licences + self.usage_limit = None + self.description = None + # Possible values are ['yes', 'no'] + self.perpetual = 'no' + self.start_date = None + self.end_date = None + self.licence_key = None + # Lists + self.documents_list = [] + self.servers_list = [] + self.virtualmachines_list = [] + + def find_os_version(self): + """ + Retrieve the ItopapiOSVersion corresponding to this server + """ + if self.osversion_id is not None: + ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) + return None + + def find_organization(self): + """ + Retrieve the ItopapiOrganization corresponding to this server + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 8ce8ad6..9c257c1 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -297,8 +297,7 @@ def find_os_licence(self): Retrieve the ItopapiOSLicence corresponding to this server """ if self.oslicence_id is not None: - # TODO define ItopapiOSLicence return ItopapiOSLicence.find(self.oslicence_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) return None def find_power_a(self): diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index b473ad3..a69f4c5 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -190,9 +190,8 @@ def find_os_version(self): def find_os_licence(self): """ - Retrieve the ItopapiOSLicence corresponding to this VirtualMachine + Retrieve the ItopapiOSLicence corresponding to this server """ if self.oslicence_id is not None: - # TODO define ItopapiOSLicence return ItopapiOSLicence.find(self.oslicence_id) - raise ItopapiUnimplementedMethod() + ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) return None \ No newline at end of file From edb737112d3f4c3f40b1f5e865b7eb544fc4fb7b Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 13 May 2015 12:05:11 +0200 Subject: [PATCH 013/104] Found that "provider" is in fact "Organization" for Service. Problem solved! --- itopapi/model/service.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 8e3566e..364aab8 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -20,6 +20,7 @@ class ItopapiService(ItopapiPrototype): 'save': ['name', 'description', 'status'], 'foreign_keys': [ {'id': 'servicefamily_id', 'name': 'servicefamily_name', 'table': 'ServiceFamily'}, + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, ], 'list_types': {'functionalcis_list': None}, } @@ -39,11 +40,14 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiService) """ - ItopapiPhysicalInterface is an object that represents a PhysicalInterface from iTop + ItopapiService is an object that represents a Service from iTop """ def __init__(self, data=None): super(ItopapiService, self).__init__(data) - # TODO provider not returned ?!? + # Note: the Organization is called "Provider" for Services + self.org_id = None + self.org_id_friendlyname = None + self.organization_name = None # Service Family self.servicefamily_id = None self.servicefamily_id_friendlyname = None @@ -60,4 +64,10 @@ def __init__(self, data=None): self.providercontracts_list = None self.functionalcis_list = None - # TODO find_organization method, based on Server \ No newline at end of file + def find_organization(self): + """ + Retrieve the ItopapiOrganization corresponding to this server + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None From dc20b9056f9b4a84a837f763506de8d8eb55b95a Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 13 May 2015 12:05:21 +0200 Subject: [PATCH 014/104] corrected typos --- itopapi/model/webServer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 6991717..15c41e5 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -170,7 +170,7 @@ def find_organization(self): def find_system(self): """ - Retrieve the ItopapiPowerB corresponding to this WebServer + Retrieve the System (Server or VirtualMachine) corresponding to this WebServer """ if self.system_id is not None: # TODO @@ -179,7 +179,7 @@ def find_system(self): def find_software(self): """ - Retrieve the ItopapiPowerB corresponding to this WebServer + Retrieve the Software corresponding to this WebServer """ if self.software_id is not None: # TODO @@ -188,7 +188,7 @@ def find_software(self): def find_software_licence(self): """ - Retrieve the ItopapiPowerB corresponding to this WebServer + Retrieve the Software Licence corresponding to this WebServer """ if self.software_licence_id is not None: # TODO From 5e2f3c09f1f66944d0891122b7e57eaef8b97169 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 13 May 2015 12:05:39 +0200 Subject: [PATCH 015/104] added partial list of missing classes to be processed later --- itopapi/model/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index b9da67c..5426643 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -26,3 +26,6 @@ from itopapi.model.brand import ItopapiBrand from itopapi.model.model import ItopapiModel from itopapi.model.applicationSolution import ItopapiApplicationSolution + +# TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, +# Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema, OtherSoftware From 213a040e1006c952b91f72c6d53d454372bad41e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 May 2015 09:25:23 +0200 Subject: [PATCH 016/104] Bug solved with finding element by name --- itopapi/controller/ItopapiController.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itopapi/controller/ItopapiController.py b/itopapi/controller/ItopapiController.py index 1d84612..4ec98e3 100644 --- a/itopapi/controller/ItopapiController.py +++ b/itopapi/controller/ItopapiController.py @@ -114,7 +114,7 @@ def load_one(self, itop_class, id_instance): if id_instance.isdigit(): instance = model.find(id_instance) else: - instance = model.find(model.find_by_name(id_instance)) + instance = model.find_by_name(id_instance) if instance is not None: self.data.extend(instance) From 1275c6fb9dfbd5bcc0d7836ec27b2c12e2fc7de7 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 3 Dec 2015 10:08:21 +0100 Subject: [PATCH 017/104] Corrected a typo --- itopapi/model/vlan.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/itopapi/model/vlan.py b/itopapi/model/vlan.py index 75db39a..325dabe 100644 --- a/itopapi/model/vlan.py +++ b/itopapi/model/vlan.py @@ -27,7 +27,7 @@ class ItopapiVLAN(ItopapiPrototype): @staticmethod def find(key): - """ Retrieve one or more instance of PhysicalInterface with the given key or criteria """ + """ Retrieve one or more instance of VLAN with the given key or criteria """ return ItopapiPrototype.find(ItopapiVLAN, key) @staticmethod @@ -36,11 +36,11 @@ def find_by_name(name): @staticmethod def find_all(): - """ Retrieve all instance of PhysicalInterface """ + """ Retrieve all instance of VLAN """ return ItopapiPrototype.find_all(ItopapiVLAN) """ - ItopapiPhysicalInterface is an object that represents a PhysicalInterface from iTop + ItopapiVLAN is an object that represents a VLAN from iTop """ def __init__(self, data=None): super(ItopapiVLAN, self).__init__(data) From e4b9fee87d3132b5dbb51ed812ef131ba60a0f6e Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 3 Dec 2015 11:35:38 +0100 Subject: [PATCH 018/104] Added the Person class into the API. --- itopapi/model/__init__.py | 1 + itopapi/model/incident.py | 0 itopapi/model/person.py | 46 +++++++++++++++++++++++++++++++++++++++ itopapi/model/server.py | 3 ++- 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 itopapi/model/incident.py create mode 100644 itopapi/model/person.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 5426643..133aace 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -26,6 +26,7 @@ from itopapi.model.brand import ItopapiBrand from itopapi.model.model import ItopapiModel from itopapi.model.applicationSolution import ItopapiApplicationSolution +from itopapi.model.person import ItopapiPerson # TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, # Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema, OtherSoftware diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py new file mode 100644 index 0000000..e69de29 diff --git a/itopapi/model/person.py b/itopapi/model/person.py new file mode 100644 index 0000000..7aaa41a --- /dev/null +++ b/itopapi/model/person.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiPerson is a abstraction of a Person representation on iTop +Note : Person has no finalclass and name. It complicates things... +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiPerson(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Person', + # Define which fields to save when creating or updating from the python API + 'save': ['contact_id', 'contact_name'], + 'foreign_keys': [], + 'list_types': {}, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of PhysicalInterface with the given key or criteria """ + return ItopapiPrototype.find(ItopapiPerson, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiPerson, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Person """ + return ItopapiPrototype.find_all(ItopapiPerson) + + """ + ItopapiPerson is an object that represents a Person from iTop + """ + def __init__(self, data=None): + super(ItopapiPerson, self).__init__(data) + self.contact_id = None + self.contact_name = None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 9c257c1..e7d295c 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -35,7 +35,8 @@ class ItopapiServer(ItopapiPrototype): {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, - ] + ], + 'list_types': {'contacts_list': 'Person'}, } @staticmethod From 411da5d081eaf64c41fc7eea4e5eb9be8889f180 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 14:49:43 +0100 Subject: [PATCH 019/104] wrong comments --- itopapi/model/location.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/itopapi/model/location.py b/itopapi/model/location.py index df6b5b2..398d110 100644 --- a/itopapi/model/location.py +++ b/itopapi/model/location.py @@ -47,9 +47,9 @@ def __init__(self, data=None): # Location's organization id. Call find_organization to get the full information or just # use org_id_friendlyname and organization_name self.org_id = None - # Server's organization friendly name. Not sure the difference with organization_name + # Location's organization friendly name. Not sure the difference with organization_name self.org_id_friendlyname = None - # Server's organization name + # Location's organization name self.organization_name = None # Location's street address. Generally multiline self.address = None From eac770c6343ed0653864f0e4f895890b5825820f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 14:50:13 +0100 Subject: [PATCH 020/104] Wrong class name: Localization => Location --- itopapi/model/enclosure.py | 2 +- itopapi/model/rack.py | 2 +- itopapi/model/server.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 0b03726..989592c 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -21,7 +21,7 @@ class ItopapiEnclosure(ItopapiPrototype): 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, - {'id': 'location_id', 'name': 'location_name', 'table': 'Localization'}, + {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index 802c765..079fd16 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -24,7 +24,7 @@ class ItopapiRack(ItopapiPrototype): 'serialnumber', 'asset_number', 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, - {'id': 'location_id', 'name': 'location_name', 'table': 'Localization'}, + {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, ] } diff --git a/itopapi/model/server.py b/itopapi/model/server.py index e7d295c..d044f26 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -25,7 +25,7 @@ class ItopapiServer(ItopapiPrototype): 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, - {'id': 'location_id', 'name': 'location_name', 'table': 'Localization'}, + {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, From c01574e694075c7733879cc02b38124d01cb5cce Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 14:52:01 +0100 Subject: [PATCH 021/104] Forgot the find_organization method --- itopapi/model/applicationSolution.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index bad12fc..1c78f32 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -71,4 +71,12 @@ def __init__(self, data=None): self.businessprocess_list = None self.services_list = None self.contacts_list = None - self.providercontracts_list = None \ No newline at end of file + self.providercontracts_list = None + + def find_organization(self): + """ + Retrieve the parent ItopapiOrganization + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None \ No newline at end of file From 04a4cffb27bc874d306861ec15fd97ee21c7b9fa Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 17:50:55 +0100 Subject: [PATCH 022/104] Allowed getting the list element types given the dict entry to read, not only the type directly. Thanks Itop :( --- itopapi/model/prototype.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 5d609e7..a72ee66 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -249,9 +249,13 @@ def __process_lists(self): if "finalclass" in element: element_class = ItopapiPrototype.get_itop_class(element["finalclass"]) else: - class_name = self.__class__.itop["list_types"][key] - if class_name is not None: - element_class = ItopapiPrototype.get_itop_class(class_name) + # class_key can be either the class name itself, or the variable pointing to the class name + class_key = self.__class__.itop["list_types"][key] + if class_key is not None: + if class_key in element: + element_class = ItopapiPrototype.get_itop_class(element[class_key]) + else: + element_class = ItopapiPrototype.get_itop_class(class_key) else: element_class = None if element_class is not None: From 8246b3bfe11b0a43315936bac782e0d2f5014e14 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 17:51:34 +0100 Subject: [PATCH 023/104] Completed the Person type. --- itopapi/model/person.py | 67 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/itopapi/model/person.py b/itopapi/model/person.py index 7aaa41a..4392ecd 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -18,9 +18,17 @@ class ItopapiPerson(ItopapiPrototype): # Name of the class in Itop 'name': 'Person', # Define which fields to save when creating or updating from the python API - 'save': ['contact_id', 'contact_name'], - 'foreign_keys': [], - 'list_types': {}, + 'save': ['contact_id', 'contact_name', 'function', 'first_name', 'name', + 'email', 'mobile_phone', 'phone', 'notify', 'employee_number', 'status'], + 'foreign_keys': [ + {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'manager_id', 'name': 'manager_name', 'table': 'Person'}, + ], + 'list_types': { + 'team_list': 'Team', + 'cis_list': 'functionalci_id_finalclass_recall' + }, } @staticmethod @@ -42,5 +50,58 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiPerson, self).__init__(data) + ################################## + # Properties # + ################################## self.contact_id = None self.contact_name = None + # Person's location id. Call find_location to get the full information or just use + # location_id_friendlyname and location_name + self.location_id = None + # Person's location id's friendly name. Not sure the difference with location_name + self.location_id_friendlyname = None + # Person's location name + self.location_name = None + # Person's organization id. Call find_organization to get the full information or just use + # org_id_friendlyname and organization_name + self.org_id = None + # Person's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + self.manager_id = None, + self.manager_id_friendlyname = None, + self.manager_name = None, + # Person's organization name + self.organization_name = None + self.function = None + self.first_name = None + self.name = None + self.email = None + self.mobile_phone = None + self.phone = None + self.organization_name = None + self.notify = None + self.employee_number = None + self.organization_name = None + self.status = None + ################################## + # Lists # + ################################## + self.tickets_list = None + self.tickets_list = None + self.tickets_list = None + + def find_location(self): + """ + Retrieve the ItopapiLocation related to this instance + """ + if self.location_id is not None: + ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return None + + def find_organization(self): + """ + Retrieve the parent ItopapiOrganization + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None From d756fd07c75b66941cb7b6899ea6e14095866331 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 18:05:17 +0100 Subject: [PATCH 024/104] functional CIs can now be read --- itopapi/model/applicationSolution.py | 5 ++++- itopapi/model/service.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index 1c78f32..1b855ac 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -20,7 +20,10 @@ class ItopapiApplicationSolution(ItopapiPrototype): 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, - ] + ], + 'list_types': { + 'functionalcis_list': 'functionalci_id_finalclass_recall' + }, } @staticmethod diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 364aab8..382ba4f 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -22,7 +22,9 @@ class ItopapiService(ItopapiPrototype): {'id': 'servicefamily_id', 'name': 'servicefamily_name', 'table': 'ServiceFamily'}, {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, ], - 'list_types': {'functionalcis_list': None}, + 'list_types': { + 'functionalcis_list': 'functionalci_id_finalclass_recall' + }, } @staticmethod From e6fd7998bc7ff8c2f619e78e975b7262395c8fb7 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 18:05:36 +0100 Subject: [PATCH 025/104] Added Team and Incident classes --- itopapi/model/__init__.py | 2 + itopapi/model/incident.py | 89 +++++++++++++++++++++++++++++++++++++++ itopapi/model/team.py | 79 ++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 itopapi/model/team.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 133aace..caf43df 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -27,6 +27,8 @@ from itopapi.model.model import ItopapiModel from itopapi.model.applicationSolution import ItopapiApplicationSolution from itopapi.model.person import ItopapiPerson +from itopapi.model.team import ItopapiTeam +from itopapi.model.incident import ItopapiIncident # TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, # Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema, OtherSoftware diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index e69de29..172736f 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -0,0 +1,89 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiIncident is a abstraction of a Incident representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiIncident(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Incident', + # Define which fields to save when creating or updating from the python API + 'save': ['title', 'description', 'ref', 'start_date', 'end_date', 'close_date', 'last_update'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'team_id', 'name': 'team_name', 'table': 'Team'}, + ], + 'list_types': { + 'functionalcis_list': 'functionalci_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of PhysicalInterface with the given key or criteria """ + return ItopapiPrototype.find(ItopapiIncident, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiIncident, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Person """ + return ItopapiPrototype.find_all(ItopapiIncident) + + """ + ItopapiPerson is an object that represents a Person from iTop + """ + def __init__(self, data=None): + super(ItopapiIncident, self).__init__(data) + self.title = None + self.friendlyname = None + self.description = None + self.ref = None + self.start_date = None + self.end_date = None + self.close_date = None + self.last_update = None + # Incident's organization id. Call find_organization to get the full information or just + # use org_id_friendlyname and organization_name + self.org_id = None + # Incident's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Incident's organization name + self.organization_name = None + + # TODO what is it? Must be related to some foreign key + self.agent_id = None + self.agent_name = None + + self.team_id = None + self.team_id_friendlyname = None + self.team_name = None + + ################################## + # Lists # + ################################## + self.functionalcis_list = None + self.contacts_list = None + self.workers_list = None + self.private_log = None + + + def find_organization(self): + """ + Retrieve the ItopapiOrganization corresponding to this server + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None + diff --git a/itopapi/model/team.py b/itopapi/model/team.py new file mode 100644 index 0000000..0689afd --- /dev/null +++ b/itopapi/model/team.py @@ -0,0 +1,79 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +ItopapiTeam is a abstraction of Team representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiTeam(ItopapiPrototype): + """ + ItopapiTeam is a object that represents a Team from iTop + """ + + """ Configuration specific to itop """ + itop = { + # Name of the class in Itop + 'name': 'Team', + # Define which fields to save when creating or updating from the python API + 'save': ['status', 'phone', 'notify', 'name', 'function', 'email'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + ], + 'list_types': { + 'persons_list': 'Person', + 'cis_list': 'functionalci_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Team with the given key or criteria """ + return ItopapiPrototype.find(ItopapiTeam, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiTeam, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Rack """ + return ItopapiPrototype.find_all(ItopapiTeam) + + def __init__(self, data=None): + super(ItopapiTeam, self).__init__(data) + + ################################## + # Properties # + ################################## + # Team's organization id. Call find_organization to get the full information or just use + # org_id_friendlyname and organization_name + self.org_id = None + # Team's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Team's organization name + self.organization_name = None + self.status = None + self.phone = None + self.notify = None + self.name = None + self.function = None + self.email = None + ################################## + # Lists # + ################################## + self.cis_list = None + self.tickets_list = None + self.persons_list = None + + def find_organization(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None From 98ad42b336052f150e271f61a90b53b0e1ad0b6d Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 23:03:41 +0100 Subject: [PATCH 026/104] Added OtherSoftware to the list of supported classes --- itopapi/model/__init__.py | 1 + itopapi/model/applicationSolution.py | 3 +- itopapi/model/othersoftware.py | 98 ++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 itopapi/model/othersoftware.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index caf43df..1eaec36 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -29,6 +29,7 @@ from itopapi.model.person import ItopapiPerson from itopapi.model.team import ItopapiTeam from itopapi.model.incident import ItopapiIncident +from itopapi.model.othersoftware import ItopapiOtherSoftware # TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, # Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema, OtherSoftware diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index 1b855ac..a7f5860 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -22,7 +22,8 @@ class ItopapiApplicationSolution(ItopapiPrototype): {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, ], 'list_types': { - 'functionalcis_list': 'functionalci_id_finalclass_recall' + 'functionalcis_list': 'functionalci_id_finalclass_recall', + 'contacts_list': 'contact_id_finalclass_recall' }, } diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py new file mode 100644 index 0000000..2404ecd --- /dev/null +++ b/itopapi/model/othersoftware.py @@ -0,0 +1,98 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +ItopapiOtherSoftware is a abstraction of OtherSoftware representation on iTop +""" +# TODO represent the hierarchy of software classes: PC Software, Middleware, DB server, Web Server, Other Software + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiOtherSoftware(ItopapiPrototype): + """ + ItopapiOtherSoftware is a object that represents a OtherSoftware from iTop + """ + + """ Configuration specific to itop """ + itop = { + # Name of the class in Itop + 'name': 'OtherSoftware', + # Define which fields to save when creating or updating from the python API + 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, + {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of OtherSoftware with the given key or criteria """ + return ItopapiPrototype.find(ItopapiOtherSoftware, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiOtherSoftware, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Rack """ + return ItopapiPrototype.find_all(ItopapiOtherSoftware) + + def __init__(self, data=None): + super(ItopapiOtherSoftware, self).__init__(data) + + ################################## + # Properties # + ################################## + # OtherSoftware's organization id. Call find_organization to get the full information or just + # use org_id_friendlyname and organization_name + self.org_id = None + # OtherSoftware's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # OtherSoftware's organization name + self.organization_name = None + # OtherSoftware's software (good job!) + self.software_id = None + self.software_id_friendlyname = None + self.software_name = None + # OtherSoftware's software licence + self.softwarelicence_id = None + self.softwarelicence_id_friendlyname = None + self.softwarelicence_name = None + # OtherSoftware's status. Values within [implementation, obsolete, production, stock] + self.status = None + # OtherSoftware's business criticity. Values within [high, medium, low] + self.business_criticity = None + # OtherSoftware's path ? + self.path = None + # OtherSoftware's description, as a free text + self.description = None + # OtherSoftware's move to production date + self.move2production = None + + ################################## + # Lists # + ################################## + self.documents_list = {} + self.softwares_list = {} + self.tickets_list = {} + self.services_list = {} + self.contacts_list = {} + self.providercontracts_list = {} + self.applicationsolution_list = {} + + def find_organization(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None From fd76d23bd9fe2ebdf739cba9fb4534c838010073 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 5 Dec 2015 23:04:02 +0100 Subject: [PATCH 027/104] Updated the contacts_list class type in diverse classes. --- itopapi/model/deliveryModel.py | 5 ++++- itopapi/model/incident.py | 3 ++- itopapi/model/person.py | 1 - itopapi/model/prototype.py | 2 ++ itopapi/model/rack.py | 5 ++++- itopapi/model/server.py | 5 ++++- itopapi/model/service.py | 3 ++- itopapi/model/team.py | 1 - itopapi/model/virtualMachine.py | 5 ++++- itopapi/model/webApplication.py | 5 ++++- itopapi/model/webServer.py | 5 ++++- 11 files changed, 30 insertions(+), 10 deletions(-) diff --git a/itopapi/model/deliveryModel.py b/itopapi/model/deliveryModel.py index 5743352..43acfc6 100644 --- a/itopapi/model/deliveryModel.py +++ b/itopapi/model/deliveryModel.py @@ -19,7 +19,10 @@ class ItopapiDeliveryModel(ItopapiPrototype): 'save': ['name', 'description'], 'foreign_keys': [ {'id': 'organization_id', 'name': 'organization_name', 'table': 'Organization'}, - ] + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, } @staticmethod diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index 172736f..f696a92 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -23,7 +23,8 @@ class ItopapiIncident(ItopapiPrototype): {'id': 'team_id', 'name': 'team_name', 'table': 'Team'}, ], 'list_types': { - 'functionalcis_list': 'functionalci_id_finalclass_recall' + 'functionalcis_list': 'functionalci_id_finalclass_recall', + 'contacts_list': 'contact_id_finalclass_recall' }, } diff --git a/itopapi/model/person.py b/itopapi/model/person.py index 4392ecd..97aa44d 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -74,7 +74,6 @@ def __init__(self, data=None): self.organization_name = None self.function = None self.first_name = None - self.name = None self.email = None self.mobile_phone = None self.phone = None diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index a72ee66..73f1ea4 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -245,6 +245,8 @@ def __process_lists(self): # For each element, find its type given by the "finalclass" attribute # and instantiate the corresponding object. In case there's no "finalclass", the class should provide # the type in itop["list_types"] + print key + print value for element in value: if "finalclass" in element: element_class = ItopapiPrototype.get_itop_class(element["finalclass"]) diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index 079fd16..f0c2f9b 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -25,7 +25,10 @@ class ItopapiRack(ItopapiPrototype): 'foreign_keys': [ {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, - ] + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, } @staticmethod diff --git a/itopapi/model/server.py b/itopapi/model/server.py index d044f26..1ea8a45 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -36,7 +36,10 @@ class ItopapiServer(ItopapiPrototype): {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, ], - 'list_types': {'contacts_list': 'Person'}, + 'list_types': { + 'contacts_list': 'Person', + 'contacts_list': 'contact_id_finalclass_recall' + }, } @staticmethod diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 382ba4f..3ba246f 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -23,7 +23,8 @@ class ItopapiService(ItopapiPrototype): {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, ], 'list_types': { - 'functionalcis_list': 'functionalci_id_finalclass_recall' + 'functionalcis_list': 'functionalci_id_finalclass_recall', + 'contacts_list': 'contact_id_finalclass_recall' }, } diff --git a/itopapi/model/team.py b/itopapi/model/team.py index 0689afd..641bbc7 100644 --- a/itopapi/model/team.py +++ b/itopapi/model/team.py @@ -60,7 +60,6 @@ def __init__(self, data=None): self.status = None self.phone = None self.notify = None - self.name = None self.function = None self.email = None ################################## diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index a69f4c5..f0d5d17 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -25,7 +25,10 @@ class ItopapiVirtualMachine(ItopapiPrototype): {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, - ] + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, } @staticmethod diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 2a3a568..9ee2e6b 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -27,7 +27,10 @@ class ItopapiWebApplication(ItopapiPrototype): {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, {'id': 'webserver_id', 'name': 'webserver_name', 'table': 'WebServer'}, ], - 'list_types': {'services_list': 'Service'} + 'list_types': { + 'services_list': 'Service', + 'contacts_list': 'contact_id_finalclass_recall' + }, } @staticmethod diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 15c41e5..fce117a 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -27,7 +27,10 @@ class ItopapiWebServer(ItopapiPrototype): {'id': 'system_id', 'name': 'system_id_friendlyname', 'table': 'Server'}, {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, - ] + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, } @staticmethod From 86c362d6849b3b571a1efa498b3c4815ad83220a Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sun, 6 Dec 2015 15:58:54 +0100 Subject: [PATCH 028/104] Recurse subclasses when looking for subclasses of ItopapiPrototype. Make it possible to inherit between subclasses of ItopapiPrototype (see next commit). --- itopapi/model/prototype.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 73f1ea4..c59be99 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -282,7 +282,10 @@ def get_itop_class(itop_class): itop_class = itop_class.lower() # Populate the list of classes if need be if len(ItopapiPrototype.__classes) == 0: - for c in ItopapiPrototype.__subclasses__(): + def all_subclasses(cls): + return cls.__subclasses__() + [g for s in cls.__subclasses__() + for g in all_subclasses(s)] + for c in all_subclasses(ItopapiPrototype): ItopapiPrototype.__classes[c.itop["name"].lower()] = c # Retrieve the proper class depending on the name From b35722d4c315d676ac156292b192ae1e1877c303 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sun, 6 Dec 2015 15:59:09 +0100 Subject: [PATCH 029/104] Added DBserver as a subclass of OtherSoftware --- itopapi/model/__init__.py | 1 + itopapi/model/dbserver.py | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 itopapi/model/dbserver.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 1eaec36..5815391 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -30,6 +30,7 @@ from itopapi.model.team import ItopapiTeam from itopapi.model.incident import ItopapiIncident from itopapi.model.othersoftware import ItopapiOtherSoftware +from itopapi.model.dbserver import ItopapiDBServer # TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, # Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema, OtherSoftware diff --git a/itopapi/model/dbserver.py b/itopapi/model/dbserver.py new file mode 100644 index 0000000..5622044 --- /dev/null +++ b/itopapi/model/dbserver.py @@ -0,0 +1,51 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +ItopapiDBServer is a abstraction of DBServer representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.othersoftware import ItopapiOtherSoftware + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiDBServer(ItopapiOtherSoftware): + """ + ItopapiDBServer is a object that represents a DBServer from iTop + It has the same attributes as ItopapiOtherSoftware + """ + + """ Configuration specific to itop """ + itop = { + # Name of the class in Itop + 'name': 'DBServer', + # Define which fields to save when creating or updating from the python API + 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, + {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of DBServer with the given key or criteria """ + return ItopapiPrototype.find(ItopapiDBServer, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiDBServer, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Rack """ + return ItopapiPrototype.find_all(ItopapiDBServer) + + def __init__(self, data=None): + super(ItopapiDBServer, self).__init__(data) From a813af6bc5aa7ba170e43fa281f17b43fc0afb6f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sun, 6 Dec 2015 15:59:56 +0100 Subject: [PATCH 030/104] Forgot to remove the debug prints --- itopapi/model/prototype.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index c59be99..dad474f 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -245,8 +245,6 @@ def __process_lists(self): # For each element, find its type given by the "finalclass" attribute # and instantiate the corresponding object. In case there's no "finalclass", the class should provide # the type in itop["list_types"] - print key - print value for element in value: if "finalclass" in element: element_class = ItopapiPrototype.get_itop_class(element["finalclass"]) From ba9b130925562743a9e06fc50484c6cc49332325 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Mon, 7 Dec 2015 11:08:45 +0100 Subject: [PATCH 031/104] Updated the list of missing classes --- itopapi/model/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 5815391..00d99e4 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -33,4 +33,4 @@ from itopapi.model.dbserver import ItopapiDBServer # TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, -# Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema, OtherSoftware +# Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema From bbd1e0f6acacc8105f47d6960cb93d60b0b8f4ab Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Mon, 7 Dec 2015 18:20:40 +0100 Subject: [PATCH 032/104] New ito2centreon connector --- itop-cli.cfg.example | 10 ++- itop2centreon.py | 134 +++++++++++++++++++++++++++++++++++++++ itopapi/itopapiconfig.py | 19 ++++++ 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 itop2centreon.py diff --git a/itop-cli.cfg.example b/itop-cli.cfg.example index 717cadf..9340315 100644 --- a/itop-cli.cfg.example +++ b/itop-cli.cfg.example @@ -18,4 +18,12 @@ prevent_duplicates: False # Default organization when adding servers or VMs organization: # Default virtualhost when adding VMs -virtualhost: \ No newline at end of file +virtualhost: + +[centreon] +# Centreon CLAPI username +username: admin +# Centreon CLAPI password +password: pass +# Centreon CLAPI executable +clapi_path: /usr/bin/centreon \ No newline at end of file diff --git a/itop2centreon.py b/itop2centreon.py new file mode 100644 index 0000000..e3967c7 --- /dev/null +++ b/itop2centreon.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +itop2centreon is a basic CLI interface to export itop data into centreon +""" + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + +from itopapi import ItopapiController, ItopapiConfig, UnsupportedImportFormat +from itopcli import load_configuration_cli, ItopcliConfig, NeedMoreArgs +from itopapi.model import * +import subprocess; + + +def csv_to_dict(csv): + lines = csv.splitlines() + headers = lines.pop(0).split(';') + dict = [] + for line in lines: + dict_line = {} + for i, val in enumerate(line.split(';')): + dict_line[headers[i]] = val.decode('utf-8') + dict.append(dict_line) + return dict + + +def run_clapi_list_command(object): + out, err = subprocess.Popen([ItopapiConfig.centreon_clapi_path, + '-u', ItopapiConfig.centreon_username, + '-p', ItopapiConfig.centreon_password, + '-o', object, + '-a', 'show'], + stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate() + return csv_to_dict(out) + + +def run_clapi_action_command(object, action, values): + out, err = subprocess.Popen([ItopapiConfig.centreon_clapi_path, + '-u', ItopapiConfig.centreon_username, + '-p', ItopapiConfig.centreon_password, + '-o', object, + '-a', action, + '-v', ';'.join(str(x.encode('utf-8')) for x in values)], + stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate() + if out == "": + return True + else: + print "Error running action command:" + print out + exit(0) + + +def main(): + """ + Main function + """ + + ###################################### + # Load Itop & Centreon configuration # + ###################################### + try: + load_configuration_cli() + except NeedMoreArgs as e: + print "Error: {}".format(e.message) + exit(1) + + + #################### + # Some value check # + #################### + if ItopapiConfig.username is None\ + or ItopapiConfig.password is None: + print "Error: Itop Username/Password missing" + exit(1) + if ItopapiConfig.centreon_username is None\ + or ItopapiConfig.centreon_password is None\ + or ItopapiConfig.centreon_clapi_path is None: + print "Error: Centreon Username/Password/Path missing" + exit(1) + + controller = ItopapiController() + + + ###################### + # Synchronize Teams # + ##################### + print "Synchronizing Itop teams..." + centreon_contact_groups = run_clapi_list_command("CG") + itop_teams = ItopapiTeam.find_all() + for team in itop_teams: + group_exists = False + for contact_group in centreon_contact_groups: + # TODO contact_group.name or description? e.g.: "Guest" VS "Guest Group" + if team.name == contact_group['name']: group_exists = True + if not group_exists: + print u"adding team {0} as a contact group".format(team.friendlyname.format('utf-8')) + run_clapi_action_command('CG', 'add', [team.name, team.name + ' (from Itop)']) + # TODO remove groups not in Itop and delete removed contacts (complete resync?) + + ####################### + # Synchronize Persons # + ####################### + print "Synchronizing Itop persons..." + centreon_contacts = run_clapi_list_command("contact") + # Can't get persons from teamps since their email is not listed in team.persons_list + itop_persons = ItopapiPerson.find_all() + for person in itop_persons: + # All persons should have an email + if person.email is None or '@' not in person.email: + continue + + contact_alias = person.email.split('@')[0] + contact_exists = False + for contact in centreon_contacts: + if person.email == contact['email']: contact_exists = True + if not contact_exists: + print u"adding person {0} as a contact".format(person.friendlyname.format('utf-8')) + run_clapi_action_command('contact', 'add', [person.friendlyname, contact_alias, person.email, '', '0', '1', 'en_US', 'ldap']) + # In all cases, add the contact to the contacts list and set various parameters + for team in person.team_list: + run_clapi_action_command('CG', 'addcontact', [team.team_name, person.email.split('@')[0]]) + run_clapi_action_command('contact', 'setParam', [contact_alias, 'enable_notifications', '1']) + run_clapi_action_command('contact', 'setParam', [contact_alias, 'hostnotifcmd', 'host-notify-by-email']) + run_clapi_action_command('contact', 'setParam', [contact_alias, 'hostnotifopt', 'd,u,r']) + run_clapi_action_command('contact', 'setParam', [contact_alias, 'svcnotifcmd', 'service-notify-by-email']) + run_clapi_action_command('contact', 'setParam', [contact_alias, 'servicenotifopt', 'w,u,c,r,f']) + + + + +if __name__ == "__main__": + main() diff --git a/itopapi/itopapiconfig.py b/itopapi/itopapiconfig.py index d1ca712..8f1ee37 100644 --- a/itopapi/itopapiconfig.py +++ b/itopapi/itopapiconfig.py @@ -31,6 +31,12 @@ class ItopapiConfig(object): simulate_deletes = False # Prevent duplicate names when adding new items prevent_duplicates = False + """ + Centreon variables + """ + centreon_username = None + centreon_password = None + centreon_clapi_path = None @staticmethod def read_config(config_file): @@ -90,3 +96,16 @@ def read_config(config_file): ItopapiConfig.prevent_duplicates = True except ConfigParser.NoOptionError: pass + + try: + ItopapiConfig.centreon_username = config_parser.get('centreon', 'username') + except ConfigParser.NoOptionError: + pass + try: + ItopapiConfig.centreon_password = config_parser.get('centreon', 'password') + except ConfigParser.NoOptionError: + pass + try: + ItopapiConfig.centreon_clapi_path = config_parser.get('centreon', 'clapi_path') + except ConfigParser.NoOptionError: + pass From 689ea22263140f586ba69b2d8e655dfd1349f2b7 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Mon, 7 Dec 2015 23:25:04 +0100 Subject: [PATCH 033/104] First try at synchronizing servers and VMs --- itop2centreon.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/itop2centreon.py b/itop2centreon.py index e3967c7..dfb47e2 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -83,7 +83,7 @@ def main(): controller = ItopapiController() - ###################### + ##################### # Synchronize Teams # ##################### print "Synchronizing Itop teams..." @@ -92,7 +92,6 @@ def main(): for team in itop_teams: group_exists = False for contact_group in centreon_contact_groups: - # TODO contact_group.name or description? e.g.: "Guest" VS "Guest Group" if team.name == contact_group['name']: group_exists = True if not group_exists: print u"adding team {0} as a contact group".format(team.friendlyname.format('utf-8')) @@ -128,6 +127,40 @@ def main(): run_clapi_action_command('contact', 'setParam', [contact_alias, 'servicenotifopt', 'w,u,c,r,f']) + ####################### + # Synchronize Servers # + ####################### + print "Synchronizing Itop servers..." + centreon_hosts = run_clapi_list_command("HOST") + itop_servers = ItopapiServer.find_all() + for server in itop_servers: + if server.managementip is None or server.managementip == '': + continue + server_exists = False + for host in centreon_hosts: + if server.name == host['name']: server_exists = True + if not server_exists: + print u"adding server {0} as a host".format(server.name.format('utf-8')) + run_clapi_action_command('HOST', 'add', [server.name, server.name, server.name, 'generic-host', 'central', '']) + # TODO remove servers not in Itop + + ############################### + # Synchronize VirtualMachines # + ############################### + print "Synchronizing Itop VMs..." + itop_vms = ItopapiVirtualMachine.find_all() + for vm in itop_vms: + if vm.managementip is None or vm.managementip == '': + continue + vm_exists = False + for host in centreon_hosts: + if vm.name == host['name']: vm_exists = True + if not vm_exists: + print u"adding virtualmachne {0} as a host".format(vm.name.format('utf-8')) + run_clapi_action_command('HOST', 'add', [vm.name, vm.description, vm.managementip, 'generic-host', 'central', '']) + # TODO remove vms not in Itop + + if __name__ == "__main__": From 0b3036de77e54355467380d6353cb9f7b73bfe70 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Tue, 8 Dec 2015 10:36:04 +0100 Subject: [PATCH 034/104] ignore local pylint script --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e7ac8c4..621b73b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ MANIFEST dist build Makefile -python_itop_api.egg-info \ No newline at end of file +python_itop_api.egg-info +pylint.bat From be6c9e5d82ec0c5d4cdc16426ac16ab42933ea52 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Tue, 8 Dec 2015 12:42:36 +0100 Subject: [PATCH 035/104] Now Synchronizing servers and virtual machines --- itop2centreon.py | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/itop2centreon.py b/itop2centreon.py index dfb47e2..200523e 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -36,11 +36,11 @@ def run_clapi_list_command(object): return csv_to_dict(out) -def run_clapi_action_command(object, action, values): +def run_clapi_action_command(obj, action, values): out, err = subprocess.Popen([ItopapiConfig.centreon_clapi_path, '-u', ItopapiConfig.centreon_username, '-p', ItopapiConfig.centreon_password, - '-o', object, + '-o', obj, '-a', action, '-v', ';'.join(str(x.encode('utf-8')) for x in values)], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate() @@ -103,7 +103,7 @@ def main(): ####################### print "Synchronizing Itop persons..." centreon_contacts = run_clapi_list_command("contact") - # Can't get persons from teamps since their email is not listed in team.persons_list + # Can't get persons from teams since their email is not listed in team.persons_list itop_persons = ItopapiPerson.find_all() for person in itop_persons: # All persons should have an email @@ -119,29 +119,39 @@ def main(): run_clapi_action_command('contact', 'add', [person.friendlyname, contact_alias, person.email, '', '0', '1', 'en_US', 'ldap']) # In all cases, add the contact to the contacts list and set various parameters for team in person.team_list: - run_clapi_action_command('CG', 'addcontact', [team.team_name, person.email.split('@')[0]]) + run_clapi_action_command('CG', 'addcontact', [team.team_name, contact_alias]) run_clapi_action_command('contact', 'setParam', [contact_alias, 'enable_notifications', '1']) run_clapi_action_command('contact', 'setParam', [contact_alias, 'hostnotifcmd', 'host-notify-by-email']) run_clapi_action_command('contact', 'setParam', [contact_alias, 'hostnotifopt', 'd,u,r']) run_clapi_action_command('contact', 'setParam', [contact_alias, 'svcnotifcmd', 'service-notify-by-email']) run_clapi_action_command('contact', 'setParam', [contact_alias, 'servicenotifopt', 'w,u,c,r,f']) - + def sync_servers(servers, centreon_hosts): + for server in servers: + if server.managementip is None or server.managementip == '': + continue + server_exists = False + for host in centreon_hosts: + if server.name == host['name']: server_exists = True + if not server_exists: + print u"adding {0} as a host".format(server.name.format('utf-8')) + run_clapi_action_command('HOST', 'add', [server.name, server.description, server.managementip, + 'generic-host', 'central', '']) + # Set the server parameters + run_clapi_action_command('HOST', 'setParam', [server.name, 'check_period', '24x7']) + # Set the contacts + for contact in server.contacts_list: + if type(contact) is ItopapiTeam: + run_clapi_action_command('HOST', 'addContactGroup', [server.name, contact.contact_name]) + else: + run_clapi_action_command('HOST', 'addContact', [server.name, contact.contact_id_friendlyname]) ####################### # Synchronize Servers # ####################### print "Synchronizing Itop servers..." centreon_hosts = run_clapi_list_command("HOST") itop_servers = ItopapiServer.find_all() - for server in itop_servers: - if server.managementip is None or server.managementip == '': - continue - server_exists = False - for host in centreon_hosts: - if server.name == host['name']: server_exists = True - if not server_exists: - print u"adding server {0} as a host".format(server.name.format('utf-8')) - run_clapi_action_command('HOST', 'add', [server.name, server.name, server.name, 'generic-host', 'central', '']) + sync_servers(itop_servers, centreon_hosts) # TODO remove servers not in Itop ############################### @@ -149,15 +159,7 @@ def main(): ############################### print "Synchronizing Itop VMs..." itop_vms = ItopapiVirtualMachine.find_all() - for vm in itop_vms: - if vm.managementip is None or vm.managementip == '': - continue - vm_exists = False - for host in centreon_hosts: - if vm.name == host['name']: vm_exists = True - if not vm_exists: - print u"adding virtualmachne {0} as a host".format(vm.name.format('utf-8')) - run_clapi_action_command('HOST', 'add', [vm.name, vm.description, vm.managementip, 'generic-host', 'central', '']) + sync_servers(itop_vms, centreon_hosts) # TODO remove vms not in Itop From 908b1b357bf176d70f2d861ce90fbc936638ac15 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Tue, 8 Dec 2015 14:15:44 +0100 Subject: [PATCH 036/104] Bidirectional sync for contacts, contact groups and servers --- itop2centreon.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/itop2centreon.py b/itop2centreon.py index 200523e..8c92a47 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -96,7 +96,16 @@ def main(): if not group_exists: print u"adding team {0} as a contact group".format(team.friendlyname.format('utf-8')) run_clapi_action_command('CG', 'add', [team.name, team.name + ' (from Itop)']) - # TODO remove groups not in Itop and delete removed contacts (complete resync?) + + ################################### + # Cleanup Centreon Contact Groups # + ################################### + print "Cleaning up Centreon contact groups..." + all_contact_group_names = map(lambda s: s.name, itop_teams) + for contact_group in centreon_contact_groups: + if contact_group['name'] not in all_contact_group_names and contact_group['name'] != 'Supervisors': + print u"deleting contact group {0} as is is not defined in itop".format(contact_group['name'].format('utf-8')) + run_clapi_action_command('CG', 'DEL', [contact_group['name']]) ####################### # Synchronize Persons # @@ -126,6 +135,16 @@ def main(): run_clapi_action_command('contact', 'setParam', [contact_alias, 'svcnotifcmd', 'service-notify-by-email']) run_clapi_action_command('contact', 'setParam', [contact_alias, 'servicenotifopt', 'w,u,c,r,f']) + ############################# + # Cleanup Centreon Contacts # + ############################# + print "Cleaning up Centreon contacts..." + all_contact_aliases = map(lambda s: '' if s.email is None else s.email.split('@')[0], itop_persons) + for contact in centreon_contacts: + if contact['alias'] not in all_contact_aliases and contact['alias'] != 'admin': + print u"deleting contact {0} as is is not defined in itop".format(contact['alias'].format('utf-8')) + run_clapi_action_command('contact', 'DEL', [contact['alias']]) + def sync_servers(servers, centreon_hosts): for server in servers: if server.managementip is None or server.managementip == '': @@ -145,6 +164,7 @@ def sync_servers(servers, centreon_hosts): run_clapi_action_command('HOST', 'addContactGroup', [server.name, contact.contact_name]) else: run_clapi_action_command('HOST', 'addContact', [server.name, contact.contact_id_friendlyname]) + ####################### # Synchronize Servers # ####################### @@ -152,7 +172,6 @@ def sync_servers(servers, centreon_hosts): centreon_hosts = run_clapi_list_command("HOST") itop_servers = ItopapiServer.find_all() sync_servers(itop_servers, centreon_hosts) - # TODO remove servers not in Itop ############################### # Synchronize VirtualMachines # @@ -160,8 +179,16 @@ def sync_servers(servers, centreon_hosts): print "Synchronizing Itop VMs..." itop_vms = ItopapiVirtualMachine.find_all() sync_servers(itop_vms, centreon_hosts) - # TODO remove vms not in Itop + ########################## + # Cleanup Centreon Hosts # + ########################## + print "Cleaning up Centreon hosts..." + all_servers_names = map(lambda s: s.name, itop_servers + itop_vms) + for host in centreon_hosts: + if host['name'] not in all_servers_names: + print u"deleting host {0} as is is not defined in itop".format(host['name'].format('utf-8')) + run_clapi_action_command('HOST', 'DEL', [host['name']]) From b4dd0d67fa8a85e7a7c7c7a7d26868a1cb812c68 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 9 Dec 2015 11:37:59 +0100 Subject: [PATCH 037/104] Add only servers in production and remove servers no longer in production --- itop2centreon.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/itop2centreon.py b/itop2centreon.py index 8c92a47..5a9b45a 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -152,10 +152,18 @@ def sync_servers(servers, centreon_hosts): server_exists = False for host in centreon_hosts: if server.name == host['name']: server_exists = True + if server.status != 'production': + if server_exists: + # Remove servers no longer in production + print u"removing {0} as a host as its status is {1}".format(server.name.format('utf-8'), server.status) + run_clapi_action_command('HOST', 'DEL', [server.name]) + continue + if not server_exists: print u"adding {0} as a host".format(server.name.format('utf-8')) - run_clapi_action_command('HOST', 'add', [server.name, server.description, server.managementip, + run_clapi_action_command('HOST', 'ADD', [server.name, server.description, server.managementip, 'generic-host', 'central', '']) + # Set the server parameters run_clapi_action_command('HOST', 'setParam', [server.name, 'check_period', '24x7']) # Set the contacts From dfe397b5fe47cc25106b688f932ac9d6f1543991 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 9 Dec 2015 11:40:17 +0100 Subject: [PATCH 038/104] Making more clear the vocabularies between Itop and Centreon --- itop2centreon.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/itop2centreon.py b/itop2centreon.py index 5a9b45a..15bb745 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -86,7 +86,7 @@ def main(): ##################### # Synchronize Teams # ##################### - print "Synchronizing Itop teams..." + print "Synchronizing Itop teams / Centreon contact groups..." centreon_contact_groups = run_clapi_list_command("CG") itop_teams = ItopapiTeam.find_all() for team in itop_teams: @@ -110,7 +110,7 @@ def main(): ####################### # Synchronize Persons # ####################### - print "Synchronizing Itop persons..." + print "Synchronizing Itop persons / Centreon contacts..." centreon_contacts = run_clapi_list_command("contact") # Can't get persons from teams since their email is not listed in team.persons_list itop_persons = ItopapiPerson.find_all() @@ -176,7 +176,7 @@ def sync_servers(servers, centreon_hosts): ####################### # Synchronize Servers # ####################### - print "Synchronizing Itop servers..." + print "Synchronizing Itop servers / Centreon hosts..." centreon_hosts = run_clapi_list_command("HOST") itop_servers = ItopapiServer.find_all() sync_servers(itop_servers, centreon_hosts) @@ -184,7 +184,7 @@ def sync_servers(servers, centreon_hosts): ############################### # Synchronize VirtualMachines # ############################### - print "Synchronizing Itop VMs..." + print "Synchronizing Itop VMs / Centreon hosts..." itop_vms = ItopapiVirtualMachine.find_all() sync_servers(itop_vms, centreon_hosts) From bfb2609ed72f5f55cbd0f72a445f421ab7f88e2f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 9 Jan 2016 17:53:59 +0100 Subject: [PATCH 039/104] Identified what "agent" is in an incident --- itopapi/model/incident.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index f696a92..fd25b16 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -20,6 +20,7 @@ class ItopapiIncident(ItopapiPrototype): 'save': ['title', 'description', 'ref', 'start_date', 'end_date', 'close_date', 'last_update'], 'foreign_keys': [ {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'agent_id', 'name': 'agent_name', 'table': 'Person'}, {'id': 'team_id', 'name': 'team_name', 'table': 'Team'}, ], 'list_types': { @@ -63,7 +64,7 @@ def __init__(self, data=None): # Incident's organization name self.organization_name = None - # TODO what is it? Must be related to some foreign key + # Foreign key to a Person self.agent_id = None self.agent_name = None From 26229e5e3be7ff894ef435221fbb3f8953751856 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 9 Jan 2016 21:28:42 +0100 Subject: [PATCH 040/104] Added owerSource --- itopapi/model/__init__.py | 5 +- itopapi/model/powerSource.py | 127 +++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 itopapi/model/powerSource.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 5815391..b7addac 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -5,7 +5,7 @@ """ __version__ = '1.0' -__authors__ = ['Guillaume Philippon '] +__authors__ = ['Guillaume Philippon ', 'Julien Nauroy '] from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod from itopapi.model.rack import ItopapiRack @@ -13,6 +13,7 @@ from itopapi.model.osFamily import ItopapiOSFamily from itopapi.model.osVersion import ItopapiOSVersion from itopapi.model.osLicence import ItopapiOSLicence +from itopapi.model.powerSource import ItopapiPowerSource from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.physicalInterface import ItopapiPhysicalInterface @@ -33,4 +34,4 @@ from itopapi.model.dbserver import ItopapiDBServer # TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, -# Tablet, TapeLibrary, SANSwitchNAS, PDU, PowerSource, DatabaseSchema, OtherSoftware +# Tablet, TapeLibrary, SANSwitchNAS, PDU, DatabaseSchema, OtherSoftware diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py new file mode 100644 index 0000000..49b5750 --- /dev/null +++ b/itopapi/model/powerSource.py @@ -0,0 +1,127 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiPowerSource is a abstraction of PowerSource representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiPowerSource(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'PowerSource', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'serialnumber', 'asset_number', + 'move2production', 'purchase_date', 'end_of_warranty', 'description'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, + {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, + {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of PowerSource with the given key or criteria """ + return ItopapiPrototype.find(ItopapiPowerSource, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiPowerSource, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of PowerSource """ + return ItopapiPrototype.find_all(ItopapiPowerSource) + + """ + ItopapiPowerSource is an object that represents a PowerSource from iTop + """ + def __init__(self, data=None): + super(ItopapiPowerSource, self).__init__(data) + + # PowerSource's organization id. Call find_organization to get the full information or just + # use org_id_friendlyname and organization_name + self.org_id = None + # PowerSource's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # PowerSource's organization name + self.organization_name = None + # PowerSource's status. Values within [implementation, obsolete, production, stock] + self.status = None + # PowerSource's business criticity. Values within [high, medium, low] + self.business_criticity = None + # PowerSource's location id. Call find_location to get the full information or just use + # location_id_friendlyname and location_name + self.location_id = None + # PowerSource's location id's friendly name. Not sure the difference with location_name + self.location_id_friendlyname = None + # PowerSource's location name + self.location_name = None + self.brand_id = None + self.brand_id_friendlyname = None + self.brand_name = None + self.model_id = None + self.model_id_friendlyname = None + self.model_name = None + # Serial number + self.serialnumber = None + # Asset number + self.asset_number = None + # Server's move to production date + self.move2production = None + # Server's purchase date + self.purchase_date = None + # Server's end of warranty date + self.end_of_warranty = None + self.description = None + ################################## + # Lists # + ################################## + self.documents_list = {} + self.softwares_list = {} + self.services_list = {} + self.applicationsolution_list = {} + self.contacts_list = {} + self.tickets_list = {} + self.providercontracts_list = {} + self.pdus_list = {} + + def find_organization(self): + """ + Retrieve the ItopapiOrganization corresponding to this server + """ + if self.org_id is not None: + ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None + + def find_location(self): + """ + Retrieve the ItopapiLocation related to this instance + """ + if self.location_id is not None: + ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return None + + def find_brand(self): + """ + Retrieve the ItopapiBrand corresponding to this instance + """ + if self.brand_id is not None: + ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) + return None + + def find_model(self): + """ + Retrieve the ItopapiModel corresponding to this instance + """ + if self.model_id is not None: + ItopapiPrototype.get_itop_class('Model').find(self.model_id) + return None From f820553221312971176f69d5b1bee81625ef4937 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 9 Jan 2016 21:30:45 +0100 Subject: [PATCH 041/104] Forgot a return statement in many places --- itopapi/model/applicationSolution.py | 2 +- itopapi/model/deliveryModel.py | 2 +- itopapi/model/enclosure.py | 11 +++++------ itopapi/model/incident.py | 2 +- itopapi/model/location.py | 2 +- itopapi/model/model.py | 2 +- itopapi/model/osLicence.py | 4 ++-- itopapi/model/osVersion.py | 2 +- itopapi/model/othersoftware.py | 2 +- itopapi/model/person.py | 4 ++-- itopapi/model/powerSource.py | 8 ++++---- itopapi/model/rack.py | 4 ++-- itopapi/model/server.py | 18 +++++++++--------- itopapi/model/service.py | 2 +- itopapi/model/subnet.py | 2 +- itopapi/model/team.py | 2 +- itopapi/model/virtualMachine.py | 8 ++++---- itopapi/model/vlan.py | 2 +- itopapi/model/webApplication.py | 4 ++-- itopapi/model/webServer.py | 2 +- 20 files changed, 42 insertions(+), 43 deletions(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index a7f5860..8dfb6b9 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -82,5 +82,5 @@ def find_organization(self): Retrieve the parent ItopapiOrganization """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None \ No newline at end of file diff --git a/itopapi/model/deliveryModel.py b/itopapi/model/deliveryModel.py index 43acfc6..374353b 100644 --- a/itopapi/model/deliveryModel.py +++ b/itopapi/model/deliveryModel.py @@ -61,5 +61,5 @@ def find_organization(self): Retrieve the parent ItopapiOrganization """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None \ No newline at end of file diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 989592c..241d569 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -95,7 +95,7 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_location(self): @@ -103,7 +103,7 @@ def find_location(self): Retrieve the ItopapiLocation related to this instance """ if self.location_id is not None: - ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return ItopapiPrototype.get_itop_class('Location').find(self.location_id) return None def find_rack(self): @@ -111,7 +111,7 @@ def find_rack(self): Retrieve the ItopapiRack corresponding to this server """ if self.rack_id is not None: - ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) + return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None def find_brand(self): @@ -119,7 +119,7 @@ def find_brand(self): Retrieve the ItopapiBrand corresponding to this instance """ if self.brand_id is not None: - ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) + return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) return None def find_model(self): @@ -127,6 +127,5 @@ def find_model(self): Retrieve the ItopapiModel corresponding to this instance """ if self.model_id is not None: - ItopapiPrototype.get_itop_class('Model').find(self.model_id) - raise ItopapiUnimplementedMethod() + return ItopapiPrototype.get_itop_class('Model').find(self.model_id) return None diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index fd25b16..600a837 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -86,6 +86,6 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None diff --git a/itopapi/model/location.py b/itopapi/model/location.py index 398d110..7594326 100644 --- a/itopapi/model/location.py +++ b/itopapi/model/location.py @@ -66,5 +66,5 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None diff --git a/itopapi/model/model.py b/itopapi/model/model.py index afd7899..860810f 100644 --- a/itopapi/model/model.py +++ b/itopapi/model/model.py @@ -57,5 +57,5 @@ def find_brand(self): Retrieve the ItopapiBrand corresponding to this server """ if self.brand_id is not None: - ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) + return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) return None \ No newline at end of file diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py index 7b66ffc..0907eaf 100644 --- a/itopapi/model/osLicence.py +++ b/itopapi/model/osLicence.py @@ -71,7 +71,7 @@ def find_os_version(self): Retrieve the ItopapiOSVersion corresponding to this server """ if self.osversion_id is not None: - ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) return None def find_organization(self): @@ -79,5 +79,5 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None diff --git a/itopapi/model/osVersion.py b/itopapi/model/osVersion.py index 790f576..58d1995 100644 --- a/itopapi/model/osVersion.py +++ b/itopapi/model/osVersion.py @@ -52,5 +52,5 @@ def find_os_family(self): Retrieve the ItopapiOSFamily corresponding to this server """ if self.osfamily_id is not None: - ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) return None diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index 2404ecd..fe4f9b4 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -94,5 +94,5 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None diff --git a/itopapi/model/person.py b/itopapi/model/person.py index 97aa44d..8327bf5 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -94,7 +94,7 @@ def find_location(self): Retrieve the ItopapiLocation related to this instance """ if self.location_id is not None: - ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return ItopapiPrototype.get_itop_class('Location').find(self.location_id) return None def find_organization(self): @@ -102,5 +102,5 @@ def find_organization(self): Retrieve the parent ItopapiOrganization """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py index 49b5750..10a89ea 100644 --- a/itopapi/model/powerSource.py +++ b/itopapi/model/powerSource.py @@ -99,7 +99,7 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_location(self): @@ -107,7 +107,7 @@ def find_location(self): Retrieve the ItopapiLocation related to this instance """ if self.location_id is not None: - ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return ItopapiPrototype.get_itop_class('Location').find(self.location_id) return None def find_brand(self): @@ -115,7 +115,7 @@ def find_brand(self): Retrieve the ItopapiBrand corresponding to this instance """ if self.brand_id is not None: - ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) + return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) return None def find_model(self): @@ -123,5 +123,5 @@ def find_model(self): Retrieve the ItopapiModel corresponding to this instance """ if self.model_id is not None: - ItopapiPrototype.get_itop_class('Model').find(self.model_id) + return ItopapiPrototype.get_itop_class('Model').find(self.model_id) return None diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index f0c2f9b..83ca970 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -136,7 +136,7 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_location(self): @@ -144,5 +144,5 @@ def find_location(self): Retrieve the ItopapiLocation related to this instance """ if self.location_id is not None: - ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return ItopapiPrototype.get_itop_class('Location').find(self.location_id) return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 1ea8a45..70b3459 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -237,7 +237,7 @@ def find_rack(self): Retrieve the ItopapiRack corresponding to this server """ if self.rack_id is not None: - ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) + return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None def find_organization(self): @@ -245,7 +245,7 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_location(self): @@ -253,7 +253,7 @@ def find_location(self): Retrieve the ItopapiLocation related to this instance """ if self.location_id is not None: - ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return ItopapiPrototype.get_itop_class('Location').find(self.location_id) return None def find_enclosure(self): @@ -261,7 +261,7 @@ def find_enclosure(self): Retrieve the ItopapiEnclosure corresponding to this server """ if self.enclosure_id is not None: - ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) + return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None def find_brand(self): @@ -269,7 +269,7 @@ def find_brand(self): Retrieve the ItopapiBrand corresponding to this server """ if self.brand_id is not None: - ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) + return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) return None def find_model(self): @@ -277,7 +277,7 @@ def find_model(self): Retrieve the ItopapiModel corresponding to this server """ if self.model_id is not None: - ItopapiPrototype.get_itop_class('Model').find(self.model_id) + return ItopapiPrototype.get_itop_class('Model').find(self.model_id) return None def find_os_family(self): @@ -285,7 +285,7 @@ def find_os_family(self): Retrieve the ItopapiOSFamily corresponding to this server """ if self.osfamily_id is not None: - ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) return None def find_os_version(self): @@ -293,7 +293,7 @@ def find_os_version(self): Retrieve the ItopapiOSVersion corresponding to this server """ if self.osversion_id is not None: - ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) return None def find_os_licence(self): @@ -301,7 +301,7 @@ def find_os_licence(self): Retrieve the ItopapiOSLicence corresponding to this server """ if self.oslicence_id is not None: - ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) return None def find_power_a(self): diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 3ba246f..3a9ea79 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -72,5 +72,5 @@ def find_organization(self): Retrieve the ItopapiOrganization corresponding to this server """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None diff --git a/itopapi/model/subnet.py b/itopapi/model/subnet.py index 403192b..5cbcc44 100644 --- a/itopapi/model/subnet.py +++ b/itopapi/model/subnet.py @@ -67,5 +67,5 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None \ No newline at end of file diff --git a/itopapi/model/team.py b/itopapi/model/team.py index 641bbc7..b007b23 100644 --- a/itopapi/model/team.py +++ b/itopapi/model/team.py @@ -74,5 +74,5 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index f0d5d17..b308b81 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -172,7 +172,7 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_os_family(self): @@ -180,7 +180,7 @@ def find_os_family(self): Retrieve the ItopapiOSFamily corresponding to this VirtualMachine """ if self.osfamily_id is not None: - ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) return None def find_os_version(self): @@ -188,7 +188,7 @@ def find_os_version(self): Retrieve the ItopapiOSVersion corresponding to this server """ if self.osversion_id is not None: - ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) return None def find_os_licence(self): @@ -196,5 +196,5 @@ def find_os_licence(self): Retrieve the ItopapiOSLicence corresponding to this server """ if self.oslicence_id is not None: - ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) + return ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) return None \ No newline at end of file diff --git a/itopapi/model/vlan.py b/itopapi/model/vlan.py index 325dabe..3db6916 100644 --- a/itopapi/model/vlan.py +++ b/itopapi/model/vlan.py @@ -65,5 +65,5 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None \ No newline at end of file diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 9ee2e6b..dd75cba 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -121,7 +121,7 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_web_server(self): @@ -129,5 +129,5 @@ def find_web_server(self): Retrieve the ItopapiWebServer corresponding to this WebApplication """ if self.webserver_id is not None: - ItopapiPrototype.get_itop_class('WebServer').find(self.webserver_id) + return ItopapiPrototype.get_itop_class('WebServer').find(self.webserver_id) return None diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index fce117a..f2401eb 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -168,7 +168,7 @@ def find_organization(self): Retrieve the ItopapiOrganization related to this instance """ if self.org_id is not None: - ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) return None def find_system(self): From 4fbed194e97595eeb776ccbce575332a315497cc Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 9 Jan 2016 21:31:58 +0100 Subject: [PATCH 042/104] Now that the PowerSource is defined, the method can be implemented and TODO removed --- itopapi/model/server.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 70b3459..36c6d5e 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -309,8 +309,7 @@ def find_power_a(self): Retrieve the ItopapiPowerA corresponding to this server """ if self.powerA_id is not None: - # TODO define ItopapiPowerA return ItopapiOPowerA.find(self.powerA_id) - raise ItopapiUnimplementedMethod() + return ItopapiPrototype.get_itop_class('PowerSource').find(self.powerA_id) return None def find_power_b(self): @@ -318,6 +317,5 @@ def find_power_b(self): Retrieve the ItopapiPowerB corresponding to this server """ if self.powerB_id is not None: - # TODO define ItopapiPowerB return ItopapiOPowerB.find(self.powerB_id) - raise ItopapiUnimplementedMethod() + return ItopapiPrototype.get_itop_class('PowerSource').find(self.powerB_id) return None From d492290aefa9c42815e6537bcf2de227ec95e832 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 9 Jan 2016 21:33:47 +0100 Subject: [PATCH 043/104] More explicit TODO --- itopapi/model/webServer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index f2401eb..d28cecf 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -176,7 +176,7 @@ def find_system(self): Retrieve the System (Server or VirtualMachine) corresponding to this WebServer """ if self.system_id is not None: - # TODO + # TODO define System raise ItopapiUnimplementedMethod() return None @@ -185,7 +185,7 @@ def find_software(self): Retrieve the Software corresponding to this WebServer """ if self.software_id is not None: - # TODO + # TODO define Software raise ItopapiUnimplementedMethod() return None @@ -194,6 +194,6 @@ def find_software_licence(self): Retrieve the Software Licence corresponding to this WebServer """ if self.software_licence_id is not None: - # TODO + # TODO define SoftwareLicense raise ItopapiUnimplementedMethod() return None From 73c4bb23712dab27ba5f4f968f8a4ce9521ca52d Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sun, 10 Jan 2016 14:32:20 +0100 Subject: [PATCH 044/104] useless semicolon --- itop2centreon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itop2centreon.py b/itop2centreon.py index 15bb745..c520e8d 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -11,7 +11,7 @@ from itopapi import ItopapiController, ItopapiConfig, UnsupportedImportFormat from itopcli import load_configuration_cli, ItopcliConfig, NeedMoreArgs from itopapi.model import * -import subprocess; +import subprocess def csv_to_dict(csv): From 13aa92d9978aab782e688887b26c9107aab81505 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Wed, 13 Jan 2016 23:14:08 +0100 Subject: [PATCH 045/104] First attempt at connecting VCenter with iTop. To be continued soon. --- itop-cli.cfg.example | 12 ++- itop2centreon.py | 1 + itopapi/itopapiconfig.py | 29 +++++++ itopapi/model/prototype.py | 1 - itopapi/model/virtualMachine.py | 2 - vcenter2itop.py | 138 ++++++++++++++++++++++++++++++++ 6 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 vcenter2itop.py diff --git a/itop-cli.cfg.example b/itop-cli.cfg.example index 9340315..cc8b88f 100644 --- a/itop-cli.cfg.example +++ b/itop-cli.cfg.example @@ -26,4 +26,14 @@ username: admin # Centreon CLAPI password password: pass # Centreon CLAPI executable -clapi_path: /usr/bin/centreon \ No newline at end of file +clapi_path: /usr/bin/centreon + +[vcenter] +# VCenter host +host: localhost +# VCenter port. HTTPS (443) is the default +port: 443 +# User allowed to log in to the VCenter +username: admin +# Associated password (strongly discouraged ; prefer leaving blank and entering it when promped) +password: \ No newline at end of file diff --git a/itop2centreon.py b/itop2centreon.py index c520e8d..de6a3a5 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -198,6 +198,7 @@ def sync_servers(servers, centreon_hosts): print u"deleting host {0} as is is not defined in itop".format(host['name'].format('utf-8')) run_clapi_action_command('HOST', 'DEL', [host['name']]) + return 0 if __name__ == "__main__": diff --git a/itopapi/itopapiconfig.py b/itopapi/itopapiconfig.py index 8f1ee37..8601226 100644 --- a/itopapi/itopapiconfig.py +++ b/itopapi/itopapiconfig.py @@ -37,6 +37,13 @@ class ItopapiConfig(object): centreon_username = None centreon_password = None centreon_clapi_path = None + """ + VCenter variables + """ + vcenter_host = None + vcenter_port = None + vcenter_username = None + vcenter_password = None @staticmethod def read_config(config_file): @@ -109,3 +116,25 @@ def read_config(config_file): ItopapiConfig.centreon_clapi_path = config_parser.get('centreon', 'clapi_path') except ConfigParser.NoOptionError: pass + + try: + ItopapiConfig.vcenter_host = config_parser.get('vcenter', 'host') + except ConfigParser.NoOptionError: + pass + try: + ItopapiConfig.vcenter_port = config_parser.get('vcenter', 'port') + except ConfigParser.NoOptionError: + pass + try: + ItopapiConfig.vcenter_username = config_parser.get('vcenter', 'username') + except ConfigParser.NoOptionError: + pass + try: + ItopapiConfig.vcenter_password = config_parser.get('vcenter', 'password') + except ConfigParser.NoOptionError: + pass + try: + unsecure = config_parser.get('vcenter', 'unsecure') + ItopapiConfig.vcenter_unsecure = (unsecure.lower() == "true" or unsecure == "1") + except ConfigParser.NoOptionError: + pass diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index dad474f..824c282 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -274,7 +274,6 @@ def __process_lists(self): def get_itop_class(itop_class): """ Associate the string passed as an argument to the corresponding Itop class - Maybe move it to ItopapiPrototype someday :param itop_class: iTop class """ itop_class = itop_class.lower() diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index b308b81..326c943 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -91,8 +91,6 @@ def __init__(self, data=None): self.cpu = None self.ram = None - # Rack units - self.nb_u = None ################################## # Properties/Date # diff --git a/vcenter2itop.py b/vcenter2itop.py new file mode 100644 index 0000000..50c0b5e --- /dev/null +++ b/vcenter2itop.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +vcenter2itop is a basic CLI interface to export vcenter data into itop. +uses pyvmomi +""" + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + +from itopapi import ItopapiController, ItopapiConfig, UnsupportedImportFormat +from itopcli import load_configuration_cli, ItopcliConfig, NeedMoreArgs +from itopapi.model import * +from pyVim import connect +from pyVmomi import vmodl +from pyVmomi import vim +import ssl +import getpass +import atexit + +def create_itop_vm(virtual_machine): + # Retrieve the relevant information from the virtual_machine + config = virtual_machine.config + guest = virtual_machine.guest + # Create the ItopVirtualMachine instance + vm = ItopapiVirtualMachine() + # TODO check all values + vm.name = config.name + vm.managementip = guest.ipAddress + # TODO vm.status => implementation, obsolete, production, stock depending on ??? + # TODO OS Licence + # TODO use instanceUuid in description? + vm.cpu = config.hardware.numCPU * (config.hardware.numCPU if config.hardware.numCPU else 1) + vm.ram = config.hardware.memoryMB + # TODO get or create guest.guestFamily (windowsGuest, linuxGuest or None) and guest.guestFullName + #print guest.guestFullName + # TODO 'move2production', 'description' + + return vm + + +def main(): + """ + Main function + """ + + ###################################### + # Load Itop & pyvmomi configuration # + ###################################### + try: + load_configuration_cli() + except NeedMoreArgs as e: + print "Error: {}".format(e.message) + exit(1) + + if ItopapiConfig.vcenter_password is None or ItopapiConfig.vcenter_password == "": + ItopapiConfig.vcenter_password = getpass.getpass() + + #################### + # Some value check # + #################### + if ItopapiConfig.username is None\ + or ItopapiConfig.password is None: + print "Error: Itop Username/Password missing" + exit(1) + if ItopapiConfig.vcenter_username is None\ + or ItopapiConfig.vcenter_password is None\ + or ItopapiConfig.vcenter_host is None\ + or ItopapiConfig.vcenter_port is None: + print "Error: VCenter Host/Port/Username/Password missing" + exit(1) + + controller = ItopapiController() + + ##################### + # Connection # + ##################### + ssl_context = None + if ItopapiConfig.vcenter_unsecure: + ssl_context = ssl._create_unverified_context() + vcenter_content = None + + try: + service_instance = connect.SmartConnect(sslContext=ssl_context, + host=ItopapiConfig.vcenter_host, + user=ItopapiConfig.vcenter_username, + pwd=ItopapiConfig.vcenter_password, + port=ItopapiConfig.vcenter_port) + + atexit.register(connect.Disconnect, service_instance) + + vcenter_content = service_instance.RetrieveContent() + + except vmodl.MethodFault as error: + print("Caught vmodl fault : " + error.msg) + return -1 + + # TODO physical and storage servers, if possible + # TODO in the configuration, have the choice between add,update,delete to define the synchronization level + + ##################### + # Synchronize VMS # + ##################### + print "Synchronizing VCenter VMs with Itop..." + # Retrieve existing Itop VMs + itop_vms = dict((vm.name, vm) for vm in ItopapiVirtualMachine.find_all()) + + # First get the OS families and versions + itop_os_families = ItopapiOSFamily.find_all() + itop_os_versions = ItopapiOSVersion.find_all() + # TODO create OS families and versions if not exist and update VMs + # Get data from VCenter + container = vcenter_content.rootFolder # starting point to look into + view_type = [vim.VirtualMachine] # object types to look for + recursive = True # whether we should look into it recursively + container_view = vcenter_content.viewManager.CreateContainerView( + container, view_type, recursive) + + children = container_view.view + for child in children: + vm_name = child.config.name + itop_vm = itop_vms.get(vm_name) + if itop_vm is not None: + # TODO Update VM + 2+2 + else: + # Create the VM + vm = create_itop_vm(child) + # TODO does not save? + vm.save() + print "Added VM %s" % vm_name + + return 0 + + +if __name__ == "__main__": + main() From 37bd1f237eec651be84fec4b3c20037d5850b499 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 13:52:17 +0100 Subject: [PATCH 046/104] Forgot to add the unsecure parameter to the example configuration file. --- itop-cli.cfg.example | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/itop-cli.cfg.example b/itop-cli.cfg.example index cc8b88f..f675d2b 100644 --- a/itop-cli.cfg.example +++ b/itop-cli.cfg.example @@ -36,4 +36,6 @@ port: 443 # User allowed to log in to the VCenter username: admin # Associated password (strongly discouraged ; prefer leaving blank and entering it when promped) -password: \ No newline at end of file +password: +# Allow unsecure HTTPS connections (e.g. with a self-signed certificate). Thanks PEP 466. +unsecure = 0 From 76c5e40fd2b26afc27c2f5bfbb287fbeddc55937 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 16:57:43 +0100 Subject: [PATCH 047/104] Started adding support for sync modes --- itop-cli.cfg.example | 2 ++ itopapi/itopapiconfig.py | 8 ++++++++ vcenter2itop.py | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/itop-cli.cfg.example b/itop-cli.cfg.example index f675d2b..1141f76 100644 --- a/itop-cli.cfg.example +++ b/itop-cli.cfg.example @@ -39,3 +39,5 @@ username: admin password: # Allow unsecure HTTPS connections (e.g. with a self-signed certificate). Thanks PEP 466. unsecure = 0 +# Synchronization modes for VM. The list can only contain add (add VMs not found in VCenter), update and delete +vm_sync_mode = ['add', 'update', 'delete'] \ No newline at end of file diff --git a/itopapi/itopapiconfig.py b/itopapi/itopapiconfig.py index 8601226..1fb17b4 100644 --- a/itopapi/itopapiconfig.py +++ b/itopapi/itopapiconfig.py @@ -8,6 +8,7 @@ __authors__ = ['Julien Nauroy '] import ConfigParser +import json class ItopapiConfig(object): @@ -44,6 +45,7 @@ class ItopapiConfig(object): vcenter_port = None vcenter_username = None vcenter_password = None + vcenter_vm_sync_mode = None @staticmethod def read_config(config_file): @@ -138,3 +140,9 @@ def read_config(config_file): ItopapiConfig.vcenter_unsecure = (unsecure.lower() == "true" or unsecure == "1") except ConfigParser.NoOptionError: pass + try: + print config_parser.get('vcenter', 'vm_sync_mode') + vm_sync_mode = json.loads(config_parser.get('vcenter', 'vm_sync_mode')) + ItopapiConfig.vcenter_vm_sync_mode = vm_sync_mode + except ConfigParser.NoOptionError: + pass diff --git a/vcenter2itop.py b/vcenter2itop.py index 50c0b5e..6ad681f 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -57,6 +57,7 @@ def main(): if ItopapiConfig.vcenter_password is None or ItopapiConfig.vcenter_password == "": ItopapiConfig.vcenter_password = getpass.getpass() + #################### # Some value check # #################### @@ -64,6 +65,7 @@ def main(): or ItopapiConfig.password is None: print "Error: Itop Username/Password missing" exit(1) + if ItopapiConfig.vcenter_username is None\ or ItopapiConfig.vcenter_password is None\ or ItopapiConfig.vcenter_host is None\ @@ -71,6 +73,11 @@ def main(): print "Error: VCenter Host/Port/Username/Password missing" exit(1) + for m in ItopapiConfig.vcenter_vm_sync_mode: + if m not in ["add", "update", "delete"]: + print "Error: unsupported vm sync mode {}".format(m) + exit(1) + controller = ItopapiController() ##################### From 94757c010944743a0e2c9c80ca555ce138790890 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 20:28:18 +0100 Subject: [PATCH 048/104] forgot to remove the debug print --- itop-cli.cfg.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itop-cli.cfg.example b/itop-cli.cfg.example index 1141f76..51f3e50 100644 --- a/itop-cli.cfg.example +++ b/itop-cli.cfg.example @@ -40,4 +40,4 @@ password: # Allow unsecure HTTPS connections (e.g. with a self-signed certificate). Thanks PEP 466. unsecure = 0 # Synchronization modes for VM. The list can only contain add (add VMs not found in VCenter), update and delete -vm_sync_mode = ['add', 'update', 'delete'] \ No newline at end of file +vm_sync_mode = ["add", "update", "delete"] From 331be9c2aac209d94b85019d073b1f3f29a856a8 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 20:28:43 +0100 Subject: [PATCH 049/104] forgot to remove the debug print --- itopapi/itopapiconfig.py | 1 - 1 file changed, 1 deletion(-) diff --git a/itopapi/itopapiconfig.py b/itopapi/itopapiconfig.py index 1fb17b4..7a03bf2 100644 --- a/itopapi/itopapiconfig.py +++ b/itopapi/itopapiconfig.py @@ -141,7 +141,6 @@ def read_config(config_file): except ConfigParser.NoOptionError: pass try: - print config_parser.get('vcenter', 'vm_sync_mode') vm_sync_mode = json.loads(config_parser.get('vcenter', 'vm_sync_mode')) ItopapiConfig.vcenter_vm_sync_mode = vm_sync_mode except ConfigParser.NoOptionError: From 0ac6705bd9521501cfb8c5df1c97d4609982cb22 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 21:02:35 +0100 Subject: [PATCH 050/104] working on it --- vcenter2itop.py | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index 6ad681f..fa9333a 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -19,12 +19,18 @@ import getpass import atexit -def create_itop_vm(virtual_machine): + +def create_itop_vm(virtual_machine, organization): # Retrieve the relevant information from the virtual_machine config = virtual_machine.config guest = virtual_machine.guest # Create the ItopVirtualMachine instance vm = ItopapiVirtualMachine() + # Set the organization + vm.org_id = organization.instance_id + vm.org_id_friendlyname = organization.friendlyname + vm.organization_name = organization.name + # Set other fields # TODO check all values vm.name = config.name vm.managementip = guest.ipAddress @@ -54,10 +60,6 @@ def main(): print "Error: {}".format(e.message) exit(1) - if ItopapiConfig.vcenter_password is None or ItopapiConfig.vcenter_password == "": - ItopapiConfig.vcenter_password = getpass.getpass() - - #################### # Some value check # #################### @@ -67,16 +69,29 @@ def main(): exit(1) if ItopapiConfig.vcenter_username is None\ - or ItopapiConfig.vcenter_password is None\ or ItopapiConfig.vcenter_host is None\ or ItopapiConfig.vcenter_port is None: - print "Error: VCenter Host/Port/Username/Password missing" + print "Error: VCenter Host/Port/Username missing" exit(1) for m in ItopapiConfig.vcenter_vm_sync_mode: if m not in ["add", "update", "delete"]: print "Error: unsupported vm sync mode {}".format(m) exit(1) + if ItopapiConfig.organization is None or ItopapiConfig.organization == "" \ + and "add" in ItopapiConfig.vcenter_vm_sync_mode: + print "Error: Default organization missing" + exit(1) + # Retrieve the default organization if need be + organization = None + if "add" in ItopapiConfig.vcenter_vm_sync_mode: + find_organization = ItopapiOrganization.find_by_name(ItopapiConfig.organization) + if find_organization is None: + print "Error: Default organization \"{}\"not found".format(ItopapiConfig.vcenter_vm_sync_mode) + exit(1) + else: + # Only one result + organization = find_organization[0] controller = ItopapiController() @@ -89,6 +104,8 @@ def main(): vcenter_content = None try: + if ItopapiConfig.vcenter_password is None or ItopapiConfig.vcenter_password == "": + ItopapiConfig.vcenter_password = getpass.getpass() service_instance = connect.SmartConnect(sslContext=ssl_context, host=ItopapiConfig.vcenter_host, user=ItopapiConfig.vcenter_username, @@ -129,14 +146,18 @@ def main(): vm_name = child.config.name itop_vm = itop_vms.get(vm_name) if itop_vm is not None: - # TODO Update VM - 2+2 - else: + if "update" in ItopapiConfig.vcenter_vm_sync_mode: + # TODO Update VM + 2+2 + elif "add" in ItopapiConfig.vcenter_vm_sync_mode: # Create the VM - vm = create_itop_vm(child) + vm = create_itop_vm(child, organization) # TODO does not save? vm.save() print "Added VM %s" % vm_name + if "delete" in ItopapiConfig.vcenter_vm_sync_mode: + # TODO + 2+2 return 0 From f093e3ffd6f82c0cec8c8121ff331986e7066746 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 21:21:08 +0100 Subject: [PATCH 051/104] find_by_name now returns a singleton and not a list with one instance as it should always have --- itopapi/controller/ItopapiController.py | 2 +- itopapi/model/prototype.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/itopapi/controller/ItopapiController.py b/itopapi/controller/ItopapiController.py index 4ec98e3..ab414b6 100644 --- a/itopapi/controller/ItopapiController.py +++ b/itopapi/controller/ItopapiController.py @@ -116,7 +116,7 @@ def load_one(self, itop_class, id_instance): else: instance = model.find_by_name(id_instance) if instance is not None: - self.data.extend(instance) + self.data.append(instance) def delete(self): """ diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index dad474f..911af3d 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -112,7 +112,11 @@ def find_by_name(itop_class, name): :param name: string :return: Itopapi* """ - return ItopapiPrototype.find(itop_class, {'name': name}) + found = ItopapiPrototype.find(itop_class, {'name': name}) + # find_by_name can have only one result. In this case, return an object, not a list. + if found is not None: + return found[0] + return None @staticmethod def find(itop_class, key): From 50300b2d4226951b042d755ad829c17dc45986db Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 22:08:27 +0100 Subject: [PATCH 052/104] Added model for a server Farm --- itopapi/model/__init__.py | 1 + itopapi/model/farm.py | 82 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 itopapi/model/farm.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index b7addac..4c6a118 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -17,6 +17,7 @@ from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.physicalInterface import ItopapiPhysicalInterface +from itopapi.model.farm import ItopapiFarm from itopapi.model.virtualMachine import ItopapiVirtualMachine from itopapi.model.webServer import ItopapiWebServer from itopapi.model.webApplication import ItopapiWebApplication diff --git a/itopapi/model/farm.py b/itopapi/model/farm.py new file mode 100644 index 0000000..c46cad2 --- /dev/null +++ b/itopapi/model/farm.py @@ -0,0 +1,82 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiFarm is a abstraction of a virtual servers farm representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiFarm(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Farm', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Farm with the given key or criteria """ + return ItopapiPrototype.find(ItopapiFarm, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiFarm, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Farm """ + return ItopapiPrototype.find_all(ItopapiFarm) + + """ + ItopapiFarm is an object that represents a Farm from iTop + """ + def __init__(self, data=None): + super(ItopapiFarm, self).__init__(data) + # Farm's organization id. Call find_organization to get the full information or just use + # org_id_friendlyname and organization_name + self.org_id = None + # Farm's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Farm's organization name + self.organization_name = None + # Farm's status. Values within [inactive, active] + self.status = None + # Farm's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Farm's move to production date + self.move2production = None + # Farm's description, as a free text + self.description = None + ################################## + # Lists # + ################################## + self.documents_list = None + self.softwares_list = None + self.applicationsolution_list = None + self.tickets_list = None + self.services_list = None + self.logicalvolumes_list = None + self.hypervisor_list = None + self.virtualmachine_list = None + + + def find_organization(self): + """ + Retrieve the parent ItopapiOrganization + """ + if self.org_id is not None: + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None \ No newline at end of file From d591768aaca3dd246c5bbdfcf480c02f1472eaf5 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Thu, 14 Jan 2016 22:47:07 +0100 Subject: [PATCH 053/104] Still working on it --- vcenter2itop.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index fa9333a..1dcbfb6 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -85,13 +85,10 @@ def main(): # Retrieve the default organization if need be organization = None if "add" in ItopapiConfig.vcenter_vm_sync_mode: - find_organization = ItopapiOrganization.find_by_name(ItopapiConfig.organization) - if find_organization is None: + organization = ItopapiOrganization.find_by_name(ItopapiConfig.organization) + if organization is None: print "Error: Default organization \"{}\"not found".format(ItopapiConfig.vcenter_vm_sync_mode) exit(1) - else: - # Only one result - organization = find_organization[0] controller = ItopapiController() @@ -120,8 +117,20 @@ def main(): print("Caught vmodl fault : " + error.msg) return -1 - # TODO physical and storage servers, if possible - # TODO in the configuration, have the choice between add,update,delete to define the synchronization level + ####################### + # Synchronize Hosts # + ####################### + print "Synchronizing VCenter Hosts with Itop Farms..." + # Retrieve existing Itop Farms + itop_farms = dict((farm.name, farm) for farm in ItopapiFarm.find_all()) + # Get data from VCenter + container_view = vcenter_content.viewManager.CreateContainerView( + vcenter_content.rootFolder, [vim.ClusterComputeResource], True) # TODO HostSystem ? + children = container_view.view + for child in children: + # TODO + print child + exit(666) ##################### # Synchronize VMS # @@ -135,29 +144,31 @@ def main(): itop_os_versions = ItopapiOSVersion.find_all() # TODO create OS families and versions if not exist and update VMs # Get data from VCenter - container = vcenter_content.rootFolder # starting point to look into - view_type = [vim.VirtualMachine] # object types to look for - recursive = True # whether we should look into it recursively container_view = vcenter_content.viewManager.CreateContainerView( - container, view_type, recursive) + vcenter_content.rootFolder, [vim.VirtualMachine], True) + # vm_names will be used for deleting vms + vm_names = {} children = container_view.view for child in children: vm_name = child.config.name + vm_names.append(vm_name) itop_vm = itop_vms.get(vm_name) if itop_vm is not None: if "update" in ItopapiConfig.vcenter_vm_sync_mode: # TODO Update VM - 2+2 + print "Updated VM %s" % vm.name elif "add" in ItopapiConfig.vcenter_vm_sync_mode: # Create the VM + # TODO does not save because the cluster is not defined. vm = create_itop_vm(child, organization) - # TODO does not save? vm.save() print "Added VM %s" % vm_name if "delete" in ItopapiConfig.vcenter_vm_sync_mode: - # TODO - 2+2 + for vm in itop_vms: + if vm.name not in vm_names: + vm.delete() + print "Deleted VM %s" % vm.name return 0 From 7c8ecb2fced6a7f0dba1417c1a05f7a68b0521d1 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 16 Jan 2016 16:53:26 +0100 Subject: [PATCH 054/104] Worked a lot on vcenter2itop. Not finished yet though. --- itopapi/model/prototype.py | 1 + vcenter2itop.py | 110 +++++++++++++++++++++++++++++++------ 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 3bf3034..3454fe5 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -203,6 +203,7 @@ def save(self): if (result['code'] == '0') and (self.instance_id is None): objects = result['objects'] self.instance_id = objects[objects.keys()[0]].id + self.friendlyname = objects[objects.keys()[0]].friendlyname return result diff --git a/vcenter2itop.py b/vcenter2itop.py index 1dcbfb6..7b179c6 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -18,6 +18,64 @@ import ssl import getpass import atexit +import sys + + +# TODO I don't like this. Is there a more pythonic way? +itop_os_families = None +itop_os_versions = None +# TODO by default consider virtual host is a farm but it could also be an hypervisor +itop_farms = None + + +# Retrieve the os family or create it if it doesn't exist +def get_os_family(os_family_name): + if os_family_name is None or os_family_name == "": + os_family_name = "Unknown" + + global itop_os_families + os_family = itop_os_families.get(os_family_name) + if os_family is None: + os_family = ItopapiOSFamily() + os_family.name = os_family_name + os_family.save() + itop_os_families[os_family_name] = os_family + return os_family + + +# Retrieve the os version or create it if it doesn't exist +def get_os_version(os_family_id, os_version_name): + if os_version_name is None or os_version_name == "": + os_version_name = "Unknown" + + global itop_os_versions + os_version = itop_os_versions.get((os_family_id, os_version_name)) + if os_version is None: + os_version = ItopapiOSVersion() + os_version.name = os_version_name + os_version.osfamily_id = os_family_id + os_version.save() + itop_os_families[(os_family_id, os_version_name)] = os_version + return os_version + + +# Retrieve the virtualhost (Farm) or create it if it doesn't exist +def get_virtualhost(virtualhost_name, organization): + if virtualhost_name is None or virtualhost_name == "": + virtualhost_name = "Unknown" + + global itop_farms + farm = itop_farms.get(virtualhost_name) + if farm is None: + farm = ItopapiFarm() + farm.name = virtualhost_name + # Set the organization + farm.org_id = organization.instance_id + farm.org_id_friendlyname = organization.friendlyname + farm.organization_name = organization.name + farm.save() + itop_farms[virtualhost_name] = farm + return farm def create_itop_vm(virtual_machine, organization): @@ -30,18 +88,31 @@ def create_itop_vm(virtual_machine, organization): vm.org_id = organization.instance_id vm.org_id_friendlyname = organization.friendlyname vm.organization_name = organization.name + # Set the OS family + os_family = get_os_family(guest.guestFamily) + vm.osfamily_id = os_family.instance_id + vm.osfamily_id_friendlyname = os_family.friendlyname + vm.osfamily_name = os_family.name + # Set the OS version + os_version = get_os_version(vm.osfamily_id, guest.guestFullName) + vm.osversion_id = os_version.instance_id + vm.osversion_id_friendlyname = os_version.friendlyname + vm.osversion_name = os_version.name + # Set the virtual host (Farm) + virtualhost = get_virtualhost(None, organization) # TODO use virtual_machine.runtime.host.config.name + vm.virtualhost_id = virtualhost.instance_id + vm.virtualhost_id_friendlyname = virtualhost.friendlyname + vm.virtualhost_name = virtualhost.name + # Set other fields # TODO check all values vm.name = config.name vm.managementip = guest.ipAddress # TODO vm.status => implementation, obsolete, production, stock depending on ??? - # TODO OS Licence # TODO use instanceUuid in description? + # TODO 'move2production', 'description' vm.cpu = config.hardware.numCPU * (config.hardware.numCPU if config.hardware.numCPU else 1) vm.ram = config.hardware.memoryMB - # TODO get or create guest.guestFamily (windowsGuest, linuxGuest or None) and guest.guestFullName - #print guest.guestFullName - # TODO 'move2production', 'description' return vm @@ -92,9 +163,14 @@ def main(): controller = ItopapiController() - ##################### - # Connection # - ##################### + # First get the OS families and versions + global itop_os_families, itop_os_versions + itop_os_families = dict((os_family.name, os_family) for os_family in ItopapiOSFamily.find_all()) + itop_os_versions = dict(((os_version.osfamily_id, os_version.name), os_version) for os_version in ItopapiOSVersion.find_all()) + + ############################### + # Connection to VCenter # + ############################### ssl_context = None if ItopapiConfig.vcenter_unsecure: ssl_context = ssl._create_unverified_context() @@ -122,6 +198,7 @@ def main(): ####################### print "Synchronizing VCenter Hosts with Itop Farms..." # Retrieve existing Itop Farms + global itop_farms itop_farms = dict((farm.name, farm) for farm in ItopapiFarm.find_all()) # Get data from VCenter container_view = vcenter_content.viewManager.CreateContainerView( @@ -130,7 +207,6 @@ def main(): for child in children: # TODO print child - exit(666) ##################### # Synchronize VMS # @@ -139,31 +215,33 @@ def main(): # Retrieve existing Itop VMs itop_vms = dict((vm.name, vm) for vm in ItopapiVirtualMachine.find_all()) - # First get the OS families and versions - itop_os_families = ItopapiOSFamily.find_all() - itop_os_versions = ItopapiOSVersion.find_all() # TODO create OS families and versions if not exist and update VMs # Get data from VCenter container_view = vcenter_content.viewManager.CreateContainerView( vcenter_content.rootFolder, [vim.VirtualMachine], True) # vm_names will be used for deleting vms - vm_names = {} + vm_names = set() children = container_view.view for child in children: + # Do not take templates into consideration + if child.config.template: + continue + vm_name = child.config.name - vm_names.append(vm_name) + vm_names.add(vm_name) itop_vm = itop_vms.get(vm_name) if itop_vm is not None: if "update" in ItopapiConfig.vcenter_vm_sync_mode: # TODO Update VM - print "Updated VM %s" % vm.name + print "Updated VM %s" % vm_name elif "add" in ItopapiConfig.vcenter_vm_sync_mode: # Create the VM # TODO does not save because the cluster is not defined. vm = create_itop_vm(child, organization) - vm.save() - print "Added VM %s" % vm_name + if vm is not None: + vm.save() + print "Added VM %s" % vm_name if "delete" in ItopapiConfig.vcenter_vm_sync_mode: for vm in itop_vms: if vm.name not in vm_names: From 25a69365dda43200b677d65aa23ce03fded15cab Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 16 Jan 2016 20:53:29 +0100 Subject: [PATCH 055/104] Added model for Hypervisor --- itopapi/model/__init__.py | 1 + itopapi/model/hypervisor.py | 92 +++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 itopapi/model/hypervisor.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 4c6a118..9ce0964 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -17,6 +17,7 @@ from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.physicalInterface import ItopapiPhysicalInterface +from itopapi.model.hypervisor import ItopapiHypervisor from itopapi.model.farm import ItopapiFarm from itopapi.model.virtualMachine import ItopapiVirtualMachine from itopapi.model.webServer import ItopapiWebServer diff --git a/itopapi/model/hypervisor.py b/itopapi/model/hypervisor.py new file mode 100644 index 0000000..17212a8 --- /dev/null +++ b/itopapi/model/hypervisor.py @@ -0,0 +1,92 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiHypervisor is a abstraction of a virtual servers Hypervisor representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiHypervisor(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Hypervisor', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], + 'foreign_keys': [ + {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + {'id': 'server_id', 'name': 'server_name', 'table': 'Server'}, + {'id': 'farm_id', 'name': 'farm_name', 'table': 'Farm'}, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Hypervisor with the given key or criteria """ + return ItopapiPrototype.find(ItopapiHypervisor, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiHypervisor, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Hypervisor """ + return ItopapiPrototype.find_all(ItopapiHypervisor) + + """ + ItopapiHypervisor is an object that represents a Hypervisor from iTop + """ + def __init__(self, data=None): + super(ItopapiHypervisor, self).__init__(data) + # Hypervisor's organization id. Call find_organization to get the full information or just use + # org_id_friendlyname and organization_name + self.org_id = None + # Hypervisor's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Hypervisor's organization name + self.organization_name = None + # Hypervisor's status. Values within [inactive, active] + self.status = None + # Hypervisor's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Hypervisor's move to production date + self.move2production = None + # Hypervisor's description, as a free text + self.description = None + # Physical server the hypervisor is running onto + self.server_id = None + self.server_id_friendlyname = None + self.server_name = None + # Farm the hypervisor belongs to + self.farm_id = None + self.farm_id_friendlyname = None + self.farm_name = None + + # Lists + self.tickets_list = None + self.providercontracts_list = None + self.virtualmachine_list = None + self.services_list = None + self.applicationsolution_list = None + self.softwares_list = None + self.documents_list = None + self.contacts_list = None + self.logicalvolumes_list = None + + + def find_organization(self): + """ + Retrieve the parent ItopapiOrganization + """ + if self.org_id is not None: + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None From e8a57e7377a906f987e309e40bd679b25ab4a336 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 16 Jan 2016 21:00:37 +0100 Subject: [PATCH 056/104] Now vms can also be linked to hypervisors by default, not only farms --- vcenter2itop.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index 7b179c6..cf46d40 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -24,8 +24,8 @@ # TODO I don't like this. Is there a more pythonic way? itop_os_families = None itop_os_versions = None -# TODO by default consider virtual host is a farm but it could also be an hypervisor itop_farms = None +itop_hypervisors = None # Retrieve the os family or create it if it doesn't exist @@ -59,22 +59,28 @@ def get_os_version(os_family_id, os_version_name): return os_version -# Retrieve the virtualhost (Farm) or create it if it doesn't exist +# Retrieve the virtualhost (Hypervisor or Farm) or create it if it doesn't exist def get_virtualhost(virtualhost_name, organization): if virtualhost_name is None or virtualhost_name == "": virtualhost_name = "Unknown" - global itop_farms + global itop_farms, itop_hypervisors farm = itop_farms.get(virtualhost_name) - if farm is None: - farm = ItopapiFarm() - farm.name = virtualhost_name - # Set the organization - farm.org_id = organization.instance_id - farm.org_id_friendlyname = organization.friendlyname - farm.organization_name = organization.name - farm.save() - itop_farms[virtualhost_name] = farm + if farm is not None: + return farm + hypervisor = itop_hypervisors.get(virtualhost_name) + if hypervisor is not None: + return hypervisor + # By default, create a farm and not an hypervisor. + # Maybe add a configuration option somewhere + farm = ItopapiFarm() + farm.name = virtualhost_name + # Set the organization + farm.org_id = organization.instance_id + farm.org_id_friendlyname = organization.friendlyname + farm.organization_name = organization.name + farm.save() + itop_farms[virtualhost_name] = farm return farm @@ -98,7 +104,7 @@ def create_itop_vm(virtual_machine, organization): vm.osversion_id = os_version.instance_id vm.osversion_id_friendlyname = os_version.friendlyname vm.osversion_name = os_version.name - # Set the virtual host (Farm) + # Set the virtual host (Hypervisor or Farm) virtualhost = get_virtualhost(None, organization) # TODO use virtual_machine.runtime.host.config.name vm.virtualhost_id = virtualhost.instance_id vm.virtualhost_id_friendlyname = virtualhost.friendlyname @@ -198,8 +204,9 @@ def main(): ####################### print "Synchronizing VCenter Hosts with Itop Farms..." # Retrieve existing Itop Farms - global itop_farms + global itop_farms, itop_hypervisors itop_farms = dict((farm.name, farm) for farm in ItopapiFarm.find_all()) + itop_hypervisors = dict((hyervisor.name, hyervisor) for hyervisor in ItopapiHypervisor.find_all()) # Get data from VCenter container_view = vcenter_content.viewManager.CreateContainerView( vcenter_content.rootFolder, [vim.ClusterComputeResource], True) # TODO HostSystem ? From 1a1711dace554e680576d9f0a92209ef86c65282 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Mon, 18 Jan 2016 21:48:08 +0100 Subject: [PATCH 057/104] Nearly working with cluster and vm sync. vm not referencing the farm correctly into itop yet. --- itop-cli.cfg.example | 8 +- itopapi/itopapiconfig.py | 14 +++- vcenter2itop.py | 177 ++++++++++++++++++++++++++++++++++----- 3 files changed, 173 insertions(+), 26 deletions(-) diff --git a/itop-cli.cfg.example b/itop-cli.cfg.example index 51f3e50..2f7ce82 100644 --- a/itop-cli.cfg.example +++ b/itop-cli.cfg.example @@ -39,5 +39,9 @@ username: admin password: # Allow unsecure HTTPS connections (e.g. with a self-signed certificate). Thanks PEP 466. unsecure = 0 -# Synchronization modes for VM. The list can only contain add (add VMs not found in VCenter), update and delete -vm_sync_mode = ["add", "update", "delete"] +# Synchronization modes for Clusters (iTop Farms). The list can only contain add (add Cluster not found in iTop), update and delete +cluster_sync_mode = ["add", "update"] +# Synchronization modes for Hosts (iTop Servers). The list can only contain add (add Hosts not found in iTop), update and delete +host_sync_mode = ["add", "update"] +# Synchronization modes for VMs. The list can only contain add (add VMs not found in iTop), update and delete +vm_sync_mode = ["add", "update"] diff --git a/itopapi/itopapiconfig.py b/itopapi/itopapiconfig.py index 7a03bf2..315bf2f 100644 --- a/itopapi/itopapiconfig.py +++ b/itopapi/itopapiconfig.py @@ -45,7 +45,9 @@ class ItopapiConfig(object): vcenter_port = None vcenter_username = None vcenter_password = None - vcenter_vm_sync_mode = None + vcenter_cluster_sync_mode = [] + vcenter_host_sync_mode = [] + vcenter_vm_sync_mode = [] @staticmethod def read_config(config_file): @@ -140,6 +142,16 @@ def read_config(config_file): ItopapiConfig.vcenter_unsecure = (unsecure.lower() == "true" or unsecure == "1") except ConfigParser.NoOptionError: pass + try: + host_cluster_mode = json.loads(config_parser.get('vcenter', 'cluster_sync_mode')) + ItopapiConfig.vcenter_cluster_sync_mode = host_cluster_mode + except ConfigParser.NoOptionError: + pass + try: + host_sync_mode = json.loads(config_parser.get('vcenter', 'host_sync_mode')) + ItopapiConfig.vcenter_host_sync_mode = host_sync_mode + except ConfigParser.NoOptionError: + pass try: vm_sync_mode = json.loads(config_parser.get('vcenter', 'vm_sync_mode')) ItopapiConfig.vcenter_vm_sync_mode = vm_sync_mode diff --git a/vcenter2itop.py b/vcenter2itop.py index cf46d40..71a21b9 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -26,7 +26,8 @@ itop_os_versions = None itop_farms = None itop_hypervisors = None - +# Link between a Host in VCenter and a Farm in iTop +host_to_farm = {} # Retrieve the os family or create it if it doesn't exist def get_os_family(os_family_name): @@ -84,11 +85,78 @@ def get_virtualhost(virtualhost_name, organization): return farm +def create_itop_farm(cluster, organization): + # Retrieve the relevant information from the cluster + + # Create the ItopapiFarm instance + farm = ItopapiFarm() + # Set the organization + farm.org_id = organization.instance_id + farm.org_id_friendlyname = organization.friendlyname + farm.organization_name = organization.name + # TODO where to get the ESXi version installed? + # Set other fields + farm.name = cluster.name + # farm.status = "production" + return farm + + +def create_itop_server(host, organization): + # Retrieve the relevant information from the host + config = host.summary.config + hardware = host.hardware + + # Create the ItopapiServer + server = ItopapiServer() + # Set the organization + server.org_id = organization.instance_id + server.org_id_friendlyname = organization.friendlyname + server.organization_name = organization.name + # Set the OS family + os_family = get_os_family("VMWare ESXi") + server.osfamily_id = os_family.instance_id + server.osfamily_id_friendlyname = os_family.friendlyname + server.osfamily_name = os_family.name + # TODO where to get the ESXi version installed? + # Set other fields + server.name = host.name + server.cpu = hardware.cpuInfo.numCpuCores # or numCpuThreads + server.ram = hardware.memorySize / 1048576 + # TODO summary.hardware.vendor and summary.hardware.model for brand and model + # server.status = "production" + return server + + +def create_itop_hypervisor(server): + global host_to_farm + # Create the ItopapiHypervisor + hypervisor = ItopapiHypervisor() + # Set the organization. Same at the server's one + hypervisor.org_id = server.org_id + hypervisor.org_id_friendlyname = server.friendlyname + hypervisor.organization_name = server.name + # Set the server + hypervisor.server_id = server.instance_id + hypervisor.server_id_friendlyname = server.friendlyname + hypervisor.server_name = server.name + # Set the farm if possible + farm = host_to_farm.get(server.name) + if farm is not None: + hypervisor.farm_id = farm.instance_id + hypervisor.farm_id_friendlyname = farm.friendlyname + hypervisor.farm_name = farm.name + # Set other fields + hypervisor.name = server.name + + return hypervisor + + def create_itop_vm(virtual_machine, organization): # Retrieve the relevant information from the virtual_machine config = virtual_machine.config guest = virtual_machine.guest - # Create the ItopVirtualMachine instance + + # Create the ItopapiVirtualMachine instance vm = ItopapiVirtualMachine() # Set the organization vm.org_id = organization.instance_id @@ -105,14 +173,15 @@ def create_itop_vm(virtual_machine, organization): vm.osversion_id_friendlyname = os_version.friendlyname vm.osversion_name = os_version.name # Set the virtual host (Hypervisor or Farm) - virtualhost = get_virtualhost(None, organization) # TODO use virtual_machine.runtime.host.config.name + host_name = virtual_machine.runtime.host.name + virtualhost = get_virtualhost(host_name, organization) vm.virtualhost_id = virtualhost.instance_id vm.virtualhost_id_friendlyname = virtualhost.friendlyname vm.virtualhost_name = virtualhost.name # Set other fields # TODO check all values - vm.name = config.name + vm.name = virtual_machine.name vm.managementip = guest.ipAddress # TODO vm.status => implementation, obsolete, production, stock depending on ??? # TODO use instanceUuid in description? @@ -128,6 +197,8 @@ def main(): Main function """ + global itop_farms, itop_hypervisors, host_to_farm + ###################################### # Load Itop & pyvmomi configuration # ###################################### @@ -199,43 +270,103 @@ def main(): print("Caught vmodl fault : " + error.msg) return -1 + ######################## + # Get data from Itop # + ######################## + print "Retrieving existing data from iTop..." + # Retrieve existing Itop VMs + itop_farms = dict((farm.name, farm) for farm in ItopapiFarm.find_all()) + itop_hypervisors = dict((hypervisor.name, hypervisor) for hypervisor in ItopapiHypervisor.find_all()) + itop_vms = dict((vm.name, vm) for vm in ItopapiVirtualMachine.find_all()) + itop_servers = dict((server.name, server) for server in ItopapiServer.find_all()) + + ########################## + # Synchronize Clusters # + ########################## + print "Synchronizing VCenter Clusters with Itop Farms..." + # cluster_names will be used for deleting itop farms + cluster_names = set() + + # Get data from VCenter + # vim.ResourcePool, vim.ComputeResource, vim.ClusterComputeResource, vim. + container_view = vcenter_content.viewManager.CreateContainerView( + vcenter_content.rootFolder, [vim.ClusterComputeResource], True) + children = container_view.view + for child in children: + cluster_name = child.name + cluster_names.add(cluster_name) + itop_farm = itop_farms.get(cluster_name) + if itop_farm is not None: + if "update" in ItopapiConfig.vcenter_cluster_sync_mode: + # TODO Update cluster + print "Updated cluster %s" % cluster_name + elif "add" in ItopapiConfig.vcenter_cluster_sync_mode: + # Create the Farm + itop_farm = create_itop_farm(child, organization) + if itop_farm is not None: + itop_farm.save() + print "Added cluster %s" % cluster_name + # Fill the host_to_farm dict with this cluster's hosts + for host in child.host: + host_to_farm[host.name] = itop_farm + if "delete" in ItopapiConfig.vcenter_cluster_sync_mode: + for farm_name in itop_farms.keys(): + if farm_name not in cluster_names: + itop_farms[farm_name].delete() + itop_farms.pop(farm_name) + print "Deleted cluster %s" % farm_name + ####################### # Synchronize Hosts # ####################### - print "Synchronizing VCenter Hosts with Itop Farms..." - # Retrieve existing Itop Farms - global itop_farms, itop_hypervisors - itop_farms = dict((farm.name, farm) for farm in ItopapiFarm.find_all()) - itop_hypervisors = dict((hyervisor.name, hyervisor) for hyervisor in ItopapiHypervisor.find_all()) + print "Synchronizing VCenter Hosts with Itop Servers..." + # host_names will be used for deleting itop servers + host_names = set() + # Get data from VCenter container_view = vcenter_content.viewManager.CreateContainerView( - vcenter_content.rootFolder, [vim.ClusterComputeResource], True) # TODO HostSystem ? + vcenter_content.rootFolder, [vim.HostSystem], True) children = container_view.view for child in children: - # TODO - print child + host_name = child.name + host_names.add(host_name) + itop_server = itop_servers.get(host_name) + if itop_server is not None: + if "update" in ItopapiConfig.vcenter_host_sync_mode: + # TODO Update server + print "Updated server %s" % host_name + elif "add" in ItopapiConfig.vcenter_host_sync_mode: + # Create the Server and Hyervisor + server = create_itop_server(child, organization) + if server is not None: + server.save() + hypervisor = create_itop_hypervisor(server) + hypervisor.save() + print "Added server %s" % host_name + if "delete" in ItopapiConfig.vcenter_host_sync_mode: + for server_name in itop_servers.keys(): + if server_name not in host_names: + itop_servers[server_name].delete() + itop_servers.pop(server_name) + print "Deleted server %s" % server_name ##################### # Synchronize VMS # ##################### print "Synchronizing VCenter VMs with Itop..." - # Retrieve existing Itop VMs - itop_vms = dict((vm.name, vm) for vm in ItopapiVirtualMachine.find_all()) + # vm_names will be used for deleting itop vms + vm_names = set() - # TODO create OS families and versions if not exist and update VMs # Get data from VCenter container_view = vcenter_content.viewManager.CreateContainerView( vcenter_content.rootFolder, [vim.VirtualMachine], True) - - # vm_names will be used for deleting vms - vm_names = set() children = container_view.view for child in children: # Do not take templates into consideration if child.config.template: continue - vm_name = child.config.name + vm_name = child.name vm_names.add(vm_name) itop_vm = itop_vms.get(vm_name) if itop_vm is not None: @@ -250,10 +381,10 @@ def main(): vm.save() print "Added VM %s" % vm_name if "delete" in ItopapiConfig.vcenter_vm_sync_mode: - for vm in itop_vms: - if vm.name not in vm_names: - vm.delete() - print "Deleted VM %s" % vm.name + for vm_name in itop_vms.keys(): + if vm_name not in vm_names: + itop_vms[vm_name].delete() + print "Deleted VM %s" % vm_name return 0 From 1026c9fb74497915529409dd21db210316f5e9cd Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 23 Jan 2016 20:54:04 +0100 Subject: [PATCH 058/104] Now update also works well + refactoring. --- vcenter2itop.py | 298 ++++++++++++++++++++++++++++++------------------ 1 file changed, 184 insertions(+), 114 deletions(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index 71a21b9..fe11f58 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -21,7 +21,7 @@ import sys -# TODO I don't like this. Is there a more pythonic way? +# Global variables called here and there itop_os_families = None itop_os_versions = None itop_farms = None @@ -29,6 +29,7 @@ # Link between a Host in VCenter and a Farm in iTop host_to_farm = {} + # Retrieve the os family or create it if it doesn't exist def get_os_family(os_family_name): if os_family_name is None or os_family_name == "": @@ -85,111 +86,138 @@ def get_virtualhost(virtualhost_name, organization): return farm -def create_itop_farm(cluster, organization): +# Fill data of a VCenter's Cluster into an ItopapiFarm instance +# Return true if anything changed, else return false +def get_farm_params(itop_farm, vcenter_cluster, organization): # Retrieve the relevant information from the cluster - # Create the ItopapiFarm instance - farm = ItopapiFarm() + # Recall if there was a change in the params + has_changed = False # Set the organization - farm.org_id = organization.instance_id - farm.org_id_friendlyname = organization.friendlyname - farm.organization_name = organization.name - # TODO where to get the ESXi version installed? + if itop_farm.org_id != organization.instance_id: + has_changed = True + itop_farm.org_id = organization.instance_id + itop_farm.org_id_friendlyname = organization.friendlyname + itop_farm.organization_name = organization.name # Set other fields - farm.name = cluster.name - # farm.status = "production" - return farm + if itop_farm.name != vcenter_cluster.name: + has_changed = True + itop_farm.name = vcenter_cluster.name + # farm.status = "production" + return has_changed -def create_itop_server(host, organization): +# Fill data of a VCenter's Host into an ItopapiServer instance +# Return true if anything changed, else return false +def get_server_params(itop_server, vcenter_host, organization): # Retrieve the relevant information from the host - config = host.summary.config - hardware = host.hardware + config = vcenter_host.summary.config + hardware = vcenter_host.hardware - # Create the ItopapiServer - server = ItopapiServer() + # Recall if there was a change in the params + has_changed = False # Set the organization - server.org_id = organization.instance_id - server.org_id_friendlyname = organization.friendlyname - server.organization_name = organization.name + if itop_server.org_id != organization.instance_id: + has_changed = True + itop_server.org_id = organization.instance_id + itop_server.org_id_friendlyname = organization.friendlyname + itop_server.organization_name = organization.name # Set the OS family os_family = get_os_family("VMWare ESXi") - server.osfamily_id = os_family.instance_id - server.osfamily_id_friendlyname = os_family.friendlyname - server.osfamily_name = os_family.name + if itop_server.osfamily_id != os_family.instance_id: + has_changed = True + itop_server.osfamily_id = os_family.instance_id + itop_server.osfamily_id_friendlyname = os_family.friendlyname + itop_server.osfamily_name = os_family.name # TODO where to get the ESXi version installed? # Set other fields - server.name = host.name - server.cpu = hardware.cpuInfo.numCpuCores # or numCpuThreads - server.ram = hardware.memorySize / 1048576 - # TODO summary.hardware.vendor and summary.hardware.model for brand and model - # server.status = "production" - return server - - -def create_itop_hypervisor(server): + if itop_server.name != vcenter_host.name \ + or int(itop_server.cpu) !=int( hardware.cpuInfo.numCpuCores) \ + or int(itop_server.ram) != int(hardware.memorySize / 1048576): + has_changed = True + itop_server.name = vcenter_host.name + itop_server.cpu = int(hardware.cpuInfo.numCpuCores) # or numCpuThreads + itop_server.ram = int(hardware.memorySize / 1048576) + # TODO summary.hardware.vendor and summary.hardware.model for brand and model + # server.status = "production" + return has_changed + + +# Set params of an ItoapiHypervisor using data from the ItopapiServer. +# By convention, the hypervisor will have the same name. +def get_hypervisor_params(itop_hypervisor, itop_server): global host_to_farm - # Create the ItopapiHypervisor - hypervisor = ItopapiHypervisor() # Set the organization. Same at the server's one - hypervisor.org_id = server.org_id - hypervisor.org_id_friendlyname = server.friendlyname - hypervisor.organization_name = server.name + itop_hypervisor.org_id = itop_server.org_id + itop_hypervisor.org_id_friendlyname = itop_server.friendlyname + itop_hypervisor.organization_name = itop_server.name # Set the server - hypervisor.server_id = server.instance_id - hypervisor.server_id_friendlyname = server.friendlyname - hypervisor.server_name = server.name + itop_hypervisor.server_id = itop_server.instance_id + itop_hypervisor.server_id_friendlyname = itop_server.friendlyname + itop_hypervisor.server_name = itop_server.name # Set the farm if possible - farm = host_to_farm.get(server.name) + farm = host_to_farm.get(itop_server.name) if farm is not None: - hypervisor.farm_id = farm.instance_id - hypervisor.farm_id_friendlyname = farm.friendlyname - hypervisor.farm_name = farm.name + itop_hypervisor.farm_id = farm.instance_id + itop_hypervisor.farm_id_friendlyname = farm.friendlyname + itop_hypervisor.farm_name = farm.name # Set other fields - hypervisor.name = server.name + itop_hypervisor.name = itop_server.name - return hypervisor + return itop_hypervisor -def create_itop_vm(virtual_machine, organization): +# Fill data of a VCenter's VirtualMachine into an ItopapiVirtualMachine instance +# Return true if anything changed, else return false +def get_vm_params(itop_vm, vcenter_vm, organization): # Retrieve the relevant information from the virtual_machine - config = virtual_machine.config - guest = virtual_machine.guest + config = vcenter_vm.config + guest = vcenter_vm.guest + os_family = get_os_family(guest.guestFamily) + os_version = get_os_version(itop_vm.osfamily_id, guest.guestFullName) + host_name = vcenter_vm.runtime.host.name + virtualhost = get_virtualhost(host_name, organization) - # Create the ItopapiVirtualMachine instance - vm = ItopapiVirtualMachine() + # Recall if there was a change in the params + has_changed = itop_vm.org_id != organization.instance_id \ + or itop_vm.osfamily_id != os_family.instance_id \ + or itop_vm.osversion_id != os_version.instance_id \ + or itop_vm.virtualhost_id != virtualhost.instance_id # Set the organization - vm.org_id = organization.instance_id - vm.org_id_friendlyname = organization.friendlyname - vm.organization_name = organization.name + itop_vm.org_id = organization.instance_id + itop_vm.org_id_friendlyname = organization.friendlyname + itop_vm.organization_name = organization.name # Set the OS family - os_family = get_os_family(guest.guestFamily) - vm.osfamily_id = os_family.instance_id - vm.osfamily_id_friendlyname = os_family.friendlyname - vm.osfamily_name = os_family.name + itop_vm.osfamily_id = os_family.instance_id + itop_vm.osfamily_id_friendlyname = os_family.friendlyname + itop_vm.osfamily_name = os_family.name # Set the OS version - os_version = get_os_version(vm.osfamily_id, guest.guestFullName) - vm.osversion_id = os_version.instance_id - vm.osversion_id_friendlyname = os_version.friendlyname - vm.osversion_name = os_version.name + itop_vm.osversion_id = os_version.instance_id + itop_vm.osversion_id_friendlyname = os_version.friendlyname + itop_vm.osversion_name = os_version.name # Set the virtual host (Hypervisor or Farm) - host_name = virtual_machine.runtime.host.name - virtualhost = get_virtualhost(host_name, organization) - vm.virtualhost_id = virtualhost.instance_id - vm.virtualhost_id_friendlyname = virtualhost.friendlyname - vm.virtualhost_name = virtualhost.name + itop_vm.virtualhost_id = virtualhost.instance_id + itop_vm.virtualhost_id_friendlyname = virtualhost.friendlyname + itop_vm.virtualhost_name = virtualhost.name # Set other fields - # TODO check all values - vm.name = virtual_machine.name - vm.managementip = guest.ipAddress - # TODO vm.status => implementation, obsolete, production, stock depending on ??? - # TODO use instanceUuid in description? - # TODO 'move2production', 'description' - vm.cpu = config.hardware.numCPU * (config.hardware.numCPU if config.hardware.numCPU else 1) - vm.ram = config.hardware.memoryMB + config_cpu = int(config.hardware.numCPU * (config.hardware.numCPU if config.hardware.numCPU else 1)) + ip_address = guest.ipAddress if guest.ipAddress is not None else "" + + if itop_vm.name != vcenter_vm.name \ + or itop_vm.managementip != ip_address \ + or int(itop_vm.cpu) != config_cpu \ + or int(itop_vm.ram) != int(config.hardware.memoryMB): + has_changed = True + itop_vm.name = vcenter_vm.name + itop_vm.managementip = ip_address + # TODO vm.status => implementation, obsolete, production, stock depending on ??? + # TODO use instanceUuid in description? + # TODO 'move2production', 'description' + itop_vm.cpu = config_cpu + itop_vm.ram = config.hardware.memoryMB - return vm + return has_changed def main(): @@ -291,30 +319,43 @@ def main(): # vim.ResourcePool, vim.ComputeResource, vim.ClusterComputeResource, vim. container_view = vcenter_content.viewManager.CreateContainerView( vcenter_content.rootFolder, [vim.ClusterComputeResource], True) - children = container_view.view - for child in children: - cluster_name = child.name + for vcenter_cluster in container_view.view: + cluster_name = vcenter_cluster.name cluster_names.add(cluster_name) itop_farm = itop_farms.get(cluster_name) if itop_farm is not None: if "update" in ItopapiConfig.vcenter_cluster_sync_mode: - # TODO Update cluster - print "Updated cluster %s" % cluster_name + has_changed = get_farm_params(itop_farm, vcenter_cluster, organization) + if has_changed: + ret = itop_farm.save() + if ret['code'] == 0: + print "Updated cluster %s" % cluster_name + else: + print "ERROR: cluster %s could not be updated. Check the return code below." % cluster_name + print ret elif "add" in ItopapiConfig.vcenter_cluster_sync_mode: - # Create the Farm - itop_farm = create_itop_farm(child, organization) - if itop_farm is not None: - itop_farm.save() + itop_farm = ItopapiFarm() + get_farm_params(itop_farm, vcenter_cluster, organization) + ret = itop_farm.save() + if ret['code'] == 0: print "Added cluster %s" % cluster_name + else: + print "ERROR: cluster %s could not be added. Check the return code below." % cluster_name + print ret + # Fill the host_to_farm dict with this cluster's hosts - for host in child.host: + for host in vcenter_cluster.host: host_to_farm[host.name] = itop_farm if "delete" in ItopapiConfig.vcenter_cluster_sync_mode: for farm_name in itop_farms.keys(): if farm_name not in cluster_names: - itop_farms[farm_name].delete() + ret = itop_farms[farm_name].delete() itop_farms.pop(farm_name) - print "Deleted cluster %s" % farm_name + if ret['code'] == 0: + print "Deleted cluster %s" % farm_name + else: + print "ERROR: cluster %s could not be deleted. Check the return code below." % farm_name + print ret ####################### # Synchronize Hosts # @@ -326,29 +367,47 @@ def main(): # Get data from VCenter container_view = vcenter_content.viewManager.CreateContainerView( vcenter_content.rootFolder, [vim.HostSystem], True) - children = container_view.view - for child in children: - host_name = child.name + for vcenter_host in container_view.view: + host_name = vcenter_host.name host_names.add(host_name) itop_server = itop_servers.get(host_name) if itop_server is not None: if "update" in ItopapiConfig.vcenter_host_sync_mode: - # TODO Update server - print "Updated server %s" % host_name + has_changed = get_server_params(itop_server, vcenter_host, organization) + if has_changed: + ret = itop_server.save() + if ret['code'] == 0: + print "Updated server %s" % host_name + else: + print "ERROR: server %s could not be updated. Check the return code below." % host_name + print ret elif "add" in ItopapiConfig.vcenter_host_sync_mode: - # Create the Server and Hyervisor - server = create_itop_server(child, organization) - if server is not None: - server.save() - hypervisor = create_itop_hypervisor(server) - hypervisor.save() - print "Added server %s" % host_name + # Create the Server and Hypervisor + itop_server = ItopapiServer() + get_server_params(itop_server, vcenter_host, organization) + ret = itop_server.save() + if ret['code'] == 0: + itop_hypervisor = ItopapiHypervisor() + get_hypervisor_params(itop_hypervisor, itop_server) + ret = itop_hypervisor.save() + if ret['code'] == 0: + print "Added server %s" % host_name + else: + print "ERROR: hypervisor %s could not be created. Check the return code below." % host_name + else: + print "ERROR: server %s could not be created. Check the return code below." % host_name + print ret if "delete" in ItopapiConfig.vcenter_host_sync_mode: for server_name in itop_servers.keys(): if server_name not in host_names: - itop_servers[server_name].delete() + ret = itop_servers[server_name].delete() itop_servers.pop(server_name) - print "Deleted server %s" % server_name + if ret['code'] == 0: + print "Deleted server %s" % server_name + else: + print "ERROR: server %s could not be deleted. Check the return code below." % server_name + print ret + ##################### # Synchronize VMS # @@ -360,31 +419,42 @@ def main(): # Get data from VCenter container_view = vcenter_content.viewManager.CreateContainerView( vcenter_content.rootFolder, [vim.VirtualMachine], True) - children = container_view.view - for child in children: + for vcenter_vm in container_view.view: # Do not take templates into consideration - if child.config.template: + if vcenter_vm.config.template: continue - vm_name = child.name + vm_name = vcenter_vm.name vm_names.add(vm_name) itop_vm = itop_vms.get(vm_name) if itop_vm is not None: if "update" in ItopapiConfig.vcenter_vm_sync_mode: - # TODO Update VM - print "Updated VM %s" % vm_name + has_changed = get_vm_params(itop_vm, vcenter_vm, organization) + if has_changed: + ret = itop_vm.save() + if ret['code'] == 0: + print "Updated VM %s" % vm_name + else: + print "ERROR: VM %s could not be updated. Check the return code below." % vm_name + print ret elif "add" in ItopapiConfig.vcenter_vm_sync_mode: - # Create the VM - # TODO does not save because the cluster is not defined. - vm = create_itop_vm(child, organization) - if vm is not None: - vm.save() + itop_vm = ItopapiVirtualMachine() + get_vm_params(itop_vm, vcenter_vm, organization) + ret = itop_vm.save() + if ret['code'] == 0: print "Added VM %s" % vm_name + else: + print "ERROR: VM %s could not be created. Check the return code below." % vm_name + print ret if "delete" in ItopapiConfig.vcenter_vm_sync_mode: for vm_name in itop_vms.keys(): if vm_name not in vm_names: - itop_vms[vm_name].delete() - print "Deleted VM %s" % vm_name + ret = itop_vms[vm_name].delete() + if ret['code'] == 0: + print "Deleted VM %s" % vm_name + else: + print "ERROR: VM %s could not be deleted. Check the return code below." % vm_name + print ret return 0 From 36d44406cf424903b4a9076fbbb3b74ca619a58f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sun, 24 Jan 2016 23:22:33 +0100 Subject: [PATCH 059/104] Now syncing OS and vendor --- vcenter2itop.py | 84 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index fe11f58..e1a2b0e 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -26,6 +26,8 @@ itop_os_versions = None itop_farms = None itop_hypervisors = None +itop_brands = None +itop_models = None # Link between a Host in VCenter and a Farm in iTop host_to_farm = {} @@ -46,21 +48,60 @@ def get_os_family(os_family_name): # Retrieve the os version or create it if it doesn't exist -def get_os_version(os_family_id, os_version_name): +def get_os_version(os_family, os_version_name): if os_version_name is None or os_version_name == "": os_version_name = "Unknown" global itop_os_versions - os_version = itop_os_versions.get((os_family_id, os_version_name)) + os_version = itop_os_versions.get((os_family.instance_id, os_version_name)) if os_version is None: os_version = ItopapiOSVersion() os_version.name = os_version_name - os_version.osfamily_id = os_family_id - os_version.save() - itop_os_families[(os_family_id, os_version_name)] = os_version + os_version.osfamily_id = os_family.instance_id + os_version.osfamily_name = os_family.name + os_version.osfamily_id_friendlyname = os_family.friendlyname + ret = os_version.save() + if ret['code'] != 0: + print ret + exit(0) + itop_os_versions[(os_family.instance_id, os_version.name)] = os_version return os_version +# Retrieve the brand or create it if it doesn't exist +def get_brand(brand_name): + if brand_name is None or brand_name == "": + brand_name = "Unknown" + + global itop_brands + itop_brand = itop_brands.get(brand_name) + if itop_brand is None: + itop_brand = ItopapiBrand() + itop_brand.name = brand_name + itop_brand.save() + itop_brands[brand_name] = itop_brand + return itop_brand + + +# Retrieve the model or create it if it doesn't exist +def get_model(brand, model_name, model_type): + if model_name is None or model_name == "": + model_name = "Unknown" + + global itop_models + itop_model = itop_models.get((brand.instance_id, model_name)) + if itop_model is None: + itop_model = ItopapiModel() + itop_model.name = model_name + itop_model.type = model_type + itop_model.brand_id = brand.instance_id + itop_model.brand_id_friendlyname = brand.friendlyname + itop_model.brand_name = brand.name + print itop_model.save() + itop_models[(brand.instance_id, model_name)] = itop_model + return itop_model + + # Retrieve the virtualhost (Hypervisor or Farm) or create it if it doesn't exist def get_virtualhost(virtualhost_name, organization): if virtualhost_name is None or virtualhost_name == "": @@ -111,7 +152,8 @@ def get_farm_params(itop_farm, vcenter_cluster, organization): # Return true if anything changed, else return false def get_server_params(itop_server, vcenter_host, organization): # Retrieve the relevant information from the host - config = vcenter_host.summary.config + summary = vcenter_host.summary + # config = summary.config hardware = vcenter_host.hardware # Recall if there was a change in the params @@ -129,6 +171,20 @@ def get_server_params(itop_server, vcenter_host, organization): itop_server.osfamily_id = os_family.instance_id itop_server.osfamily_id_friendlyname = os_family.friendlyname itop_server.osfamily_name = os_family.name + # Set the brand + itop_brand = get_brand(summary.hardware.vendor) + if itop_server.brand_id != itop_brand.instance_id: + has_changed = True + itop_server.brand_id = itop_brand.instance_id + itop_server.brand_id_friendlyname = itop_brand.friendlyname + itop_server.brand_name = itop_brand.name + # Set the model + itop_model = get_model(itop_brand, summary.hardware.model, "Server") + if itop_server.model_id != itop_model.instance_id: + has_changed = True + itop_server.model_id = itop_model.instance_id + itop_server.model_id_friendlyname = itop_model.friendlyname + itop_server.model_name = itop_model.name # TODO where to get the ESXi version installed? # Set other fields if itop_server.name != vcenter_host.name \ @@ -138,7 +194,6 @@ def get_server_params(itop_server, vcenter_host, organization): itop_server.name = vcenter_host.name itop_server.cpu = int(hardware.cpuInfo.numCpuCores) # or numCpuThreads itop_server.ram = int(hardware.memorySize / 1048576) - # TODO summary.hardware.vendor and summary.hardware.model for brand and model # server.status = "production" return has_changed @@ -174,7 +229,7 @@ def get_vm_params(itop_vm, vcenter_vm, organization): config = vcenter_vm.config guest = vcenter_vm.guest os_family = get_os_family(guest.guestFamily) - os_version = get_os_version(itop_vm.osfamily_id, guest.guestFullName) + os_version = get_os_version(os_family, guest.guestFullName) host_name = vcenter_vm.runtime.host.name virtualhost = get_virtualhost(host_name, organization) @@ -225,7 +280,7 @@ def main(): Main function """ - global itop_farms, itop_hypervisors, host_to_farm + global itop_farms, itop_hypervisors, host_to_farm, itop_brands, itop_models, itop_os_families, itop_os_versions ###################################### # Load Itop & pyvmomi configuration # @@ -266,13 +321,6 @@ def main(): print "Error: Default organization \"{}\"not found".format(ItopapiConfig.vcenter_vm_sync_mode) exit(1) - controller = ItopapiController() - - # First get the OS families and versions - global itop_os_families, itop_os_versions - itop_os_families = dict((os_family.name, os_family) for os_family in ItopapiOSFamily.find_all()) - itop_os_versions = dict(((os_version.osfamily_id, os_version.name), os_version) for os_version in ItopapiOSVersion.find_all()) - ############################### # Connection to VCenter # ############################### @@ -307,6 +355,10 @@ def main(): itop_hypervisors = dict((hypervisor.name, hypervisor) for hypervisor in ItopapiHypervisor.find_all()) itop_vms = dict((vm.name, vm) for vm in ItopapiVirtualMachine.find_all()) itop_servers = dict((server.name, server) for server in ItopapiServer.find_all()) + itop_os_families = dict((os_family.name, os_family) for os_family in ItopapiOSFamily.find_all()) + itop_os_versions = dict(((os_version.osfamily_id, os_version.name), os_version) for os_version in ItopapiOSVersion.find_all()) + itop_brands = dict((brand.name, brand) for brand in ItopapiBrand.find_all()) + itop_models = dict(((model.brand_id, model.name), model) for model in ItopapiModel.find({"type": "Server"})) ########################## # Synchronize Clusters # From 9316146c151a724f3d579b45603e52c8747e5cc6 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Mon, 25 Jan 2016 22:47:46 +0100 Subject: [PATCH 060/104] Nearly done. Now using the description field as a placeholder for extended data --- vcenter2itop.py | 93 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index e1a2b0e..1c552f5 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -18,7 +18,34 @@ import ssl import getpass import atexit -import sys +import json + +# TODO a bug remains when creating a new OS Version ?!? + + +# Helper function to cleanup everything the script is supposed to add +# Do not use it in a mixed configuration +def cleanup(): + for x in ItopapiVirtualMachine.find_all(): + x.delete() + for x in ItopapiHypervisor.find_all(): + x.delete() + for x in ItopapiServer.find_all(): + x.delete() + for x in ItopapiModel.find_all(): + x.delete() + for x in ItopapiBrand.find_all(): + x.delete() + for x in ItopapiOSVersion.find_all(): + x.delete() + for x in ItopapiOSFamily.find_all(): + x.delete() + exit(0) + + +# Helper function to get read of None values +def xstr(s): + return u'' if s is None else (s if type(s) is unicode else unicode(s, "utf-8")) # Global variables called here and there @@ -34,7 +61,7 @@ # Retrieve the os family or create it if it doesn't exist def get_os_family(os_family_name): - if os_family_name is None or os_family_name == "": + if xstr(os_family_name) == "": os_family_name = "Unknown" global itop_os_families @@ -49,7 +76,7 @@ def get_os_family(os_family_name): # Retrieve the os version or create it if it doesn't exist def get_os_version(os_family, os_version_name): - if os_version_name is None or os_version_name == "": + if xstr(os_version_name) == "": os_version_name = "Unknown" global itop_os_versions @@ -61,16 +88,13 @@ def get_os_version(os_family, os_version_name): os_version.osfamily_name = os_family.name os_version.osfamily_id_friendlyname = os_family.friendlyname ret = os_version.save() - if ret['code'] != 0: - print ret - exit(0) itop_os_versions[(os_family.instance_id, os_version.name)] = os_version return os_version # Retrieve the brand or create it if it doesn't exist def get_brand(brand_name): - if brand_name is None or brand_name == "": + if xstr(brand_name) == "": brand_name = "Unknown" global itop_brands @@ -85,7 +109,7 @@ def get_brand(brand_name): # Retrieve the model or create it if it doesn't exist def get_model(brand, model_name, model_type): - if model_name is None or model_name == "": + if xstr(model_name) == "": model_name = "Unknown" global itop_models @@ -97,14 +121,14 @@ def get_model(brand, model_name, model_type): itop_model.brand_id = brand.instance_id itop_model.brand_id_friendlyname = brand.friendlyname itop_model.brand_name = brand.name - print itop_model.save() + itop_model.save() itop_models[(brand.instance_id, model_name)] = itop_model return itop_model # Retrieve the virtualhost (Hypervisor or Farm) or create it if it doesn't exist def get_virtualhost(virtualhost_name, organization): - if virtualhost_name is None or virtualhost_name == "": + if xstr(virtualhost_name) == "": virtualhost_name = "Unknown" global itop_farms, itop_hypervisors @@ -155,9 +179,15 @@ def get_server_params(itop_server, vcenter_host, organization): summary = vcenter_host.summary # config = summary.config hardware = vcenter_host.hardware + product = vcenter_host.config.product # Recall if there was a change in the params has_changed = False + # Set the management IP + management_ip = xstr(summary.managementServerIp) + if itop_server.managementip != management_ip: + has_changed = True + itop_server.managementip = management_ip # Set the organization if itop_server.org_id != organization.instance_id: has_changed = True @@ -165,12 +195,19 @@ def get_server_params(itop_server, vcenter_host, organization): itop_server.org_id_friendlyname = organization.friendlyname itop_server.organization_name = organization.name # Set the OS family - os_family = get_os_family("VMWare ESXi") + os_family = get_os_family(product.name) if itop_server.osfamily_id != os_family.instance_id: has_changed = True itop_server.osfamily_id = os_family.instance_id itop_server.osfamily_id_friendlyname = os_family.friendlyname itop_server.osfamily_name = os_family.name + # Set the OS version + os_version = get_os_version(os_family, product.fullName) + if itop_server.osversion_id != os_version.instance_id: + has_changed = True + itop_server.osversion_id = os_version.instance_id + itop_server.osversion_id_friendlyname = os_version.friendlyname + itop_server.osversion_name = os_version.name # Set the brand itop_brand = get_brand(summary.hardware.vendor) if itop_server.brand_id != itop_brand.instance_id: @@ -187,14 +224,15 @@ def get_server_params(itop_server, vcenter_host, organization): itop_server.model_name = itop_model.name # TODO where to get the ESXi version installed? # Set other fields + cpu_count = int(hardware.cpuInfo.numCpuCores * hardware.cpuInfo.numCpuPackages) if itop_server.name != vcenter_host.name \ - or int(itop_server.cpu) !=int( hardware.cpuInfo.numCpuCores) \ + or int(itop_server.cpu) != cpu_count \ or int(itop_server.ram) != int(hardware.memorySize / 1048576): has_changed = True itop_server.name = vcenter_host.name - itop_server.cpu = int(hardware.cpuInfo.numCpuCores) # or numCpuThreads + itop_server.cpu = cpu_count itop_server.ram = int(hardware.memorySize / 1048576) - # server.status = "production" + return has_changed @@ -256,8 +294,8 @@ def get_vm_params(itop_vm, vcenter_vm, organization): itop_vm.virtualhost_name = virtualhost.name # Set other fields - config_cpu = int(config.hardware.numCPU * (config.hardware.numCPU if config.hardware.numCPU else 1)) - ip_address = guest.ipAddress if guest.ipAddress is not None else "" + config_cpu = int(config.hardware.numCPU) + ip_address = xstr(guest.ipAddress) if itop_vm.name != vcenter_vm.name \ or itop_vm.managementip != ip_address \ @@ -266,12 +304,26 @@ def get_vm_params(itop_vm, vcenter_vm, organization): has_changed = True itop_vm.name = vcenter_vm.name itop_vm.managementip = ip_address - # TODO vm.status => implementation, obsolete, production, stock depending on ??? - # TODO use instanceUuid in description? - # TODO 'move2production', 'description' itop_vm.cpu = config_cpu itop_vm.ram = config.hardware.memoryMB + # Set extra values as a JSON array inside the description field + current_desc = {} + try: + current_desc = json.loads(xstr(itop_vm.description)) + except ValueError as e: + pass + vcenter_hostname = xstr(vcenter_vm.guest.hostName) + if xstr(current_desc.get("hostname")) != vcenter_hostname: + has_changed = True + current_desc['hostname'] = vcenter_hostname + vcenter_annotation = xstr(vcenter_vm.config.annotation) + if xstr(current_desc.get("annotation")) != vcenter_annotation: + has_changed = True + current_desc['annotation'] = vcenter_annotation + + itop_vm.description = json.dumps(current_desc) + return has_changed @@ -327,10 +379,11 @@ def main(): ssl_context = None if ItopapiConfig.vcenter_unsecure: ssl_context = ssl._create_unverified_context() + vcenter_content = None try: - if ItopapiConfig.vcenter_password is None or ItopapiConfig.vcenter_password == "": + if xstr(ItopapiConfig.vcenter_password) == "": ItopapiConfig.vcenter_password = getpass.getpass() service_instance = connect.SmartConnect(sslContext=ssl_context, host=ItopapiConfig.vcenter_host, From 9f9636ac82ccd09f4f0c9d4b84def9d605565e8a Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 29 Jan 2016 21:38:12 +0100 Subject: [PATCH 061/104] Synchronization from VCenter to iTop is fully operational. Tested with 2 cluster, 12 hosts and 300 VMs on a real-world cluster. --- vcenter2itop.py | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index 1c552f5..f0648ab 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -2,8 +2,8 @@ # -*- coding: utf8 -*-fr # pylint: disable=invalid-name """ -vcenter2itop is a basic CLI interface to export vcenter data into itop. -uses pyvmomi +vcenter2itop is a basic CLI interface to export vcenter data into iTop. +requires pyVmomi """ __version__ = '1.0' @@ -20,27 +20,32 @@ import atexit import json -# TODO a bug remains when creating a new OS Version ?!? - # Helper function to cleanup everything the script is supposed to add # Do not use it in a mixed configuration def cleanup(): + print "Deleting all virtual machines" for x in ItopapiVirtualMachine.find_all(): x.delete() + print "Deleting all hypervisors" for x in ItopapiHypervisor.find_all(): x.delete() + print "Deleting all servers" for x in ItopapiServer.find_all(): x.delete() + print "Deleting all models" for x in ItopapiModel.find_all(): x.delete() + print "Deleting all brands" for x in ItopapiBrand.find_all(): x.delete() + print "Deleting all OS versions" for x in ItopapiOSVersion.find_all(): x.delete() + print "Deleting all OS families" for x in ItopapiOSFamily.find_all(): x.delete() - exit(0) + print "All done" # Helper function to get read of None values @@ -89,6 +94,7 @@ def get_os_version(os_family, os_version_name): os_version.osfamily_id_friendlyname = os_family.friendlyname ret = os_version.save() itop_os_versions[(os_family.instance_id, os_version.name)] = os_version + # print "Added new OS version %s" % os_version_name return os_version @@ -102,8 +108,9 @@ def get_brand(brand_name): if itop_brand is None: itop_brand = ItopapiBrand() itop_brand.name = brand_name - itop_brand.save() + ret = itop_brand.save() itop_brands[brand_name] = itop_brand + # print "Added new brand %s" % brand_name return itop_brand @@ -132,12 +139,19 @@ def get_virtualhost(virtualhost_name, organization): virtualhost_name = "Unknown" global itop_farms, itop_hypervisors + # Check if the virtualhost is a farm (shouldn't be directly) farm = itop_farms.get(virtualhost_name) if farm is not None: return farm + # Check if the virtualhost is an hypervisor hypervisor = itop_hypervisors.get(virtualhost_name) if hypervisor is not None: - return hypervisor + # If the hypervisor is within a farm, then return the farm + farm = itop_farms.get(hypervisor.farm_name) + if farm is not None: + return farm + else: + return hypervisor # By default, create a farm and not an hypervisor. # Maybe add a configuration option somewhere farm = ItopapiFarm() @@ -222,7 +236,6 @@ def get_server_params(itop_server, vcenter_host, organization): itop_server.model_id = itop_model.instance_id itop_server.model_id_friendlyname = itop_model.friendlyname itop_server.model_name = itop_model.name - # TODO where to get the ESXi version installed? # Set other fields cpu_count = int(hardware.cpuInfo.numCpuCores * hardware.cpuInfo.numCpuPackages) if itop_server.name != vcenter_host.name \ @@ -266,8 +279,10 @@ def get_vm_params(itop_vm, vcenter_vm, organization): # Retrieve the relevant information from the virtual_machine config = vcenter_vm.config guest = vcenter_vm.guest - os_family = get_os_family(guest.guestFamily) - os_version = get_os_version(os_family, guest.guestFullName) + + summary_config = vcenter_vm.summary.config + os_family = get_os_family(summary_config.guestId) + os_version = get_os_version(os_family, summary_config.guestFullName) host_name = vcenter_vm.runtime.host.name virtualhost = get_virtualhost(host_name, organization) @@ -381,7 +396,6 @@ def main(): ssl_context = ssl._create_unverified_context() vcenter_content = None - try: if xstr(ItopapiConfig.vcenter_password) == "": ItopapiConfig.vcenter_password = getpass.getpass() @@ -390,15 +404,14 @@ def main(): user=ItopapiConfig.vcenter_username, pwd=ItopapiConfig.vcenter_password, port=ItopapiConfig.vcenter_port) - atexit.register(connect.Disconnect, service_instance) - vcenter_content = service_instance.RetrieveContent() - except vmodl.MethodFault as error: print("Caught vmodl fault : " + error.msg) return -1 + # cleanup() + ######################## # Get data from Itop # ######################## @@ -492,10 +505,12 @@ def main(): get_server_params(itop_server, vcenter_host, organization) ret = itop_server.save() if ret['code'] == 0: + itop_servers[itop_server.name] = itop_server itop_hypervisor = ItopapiHypervisor() get_hypervisor_params(itop_hypervisor, itop_server) ret = itop_hypervisor.save() if ret['code'] == 0: + itop_hypervisors[itop_hypervisor.name] = itop_hypervisor print "Added server %s" % host_name else: print "ERROR: hypervisor %s could not be created. Check the return code below." % host_name @@ -547,6 +562,7 @@ def main(): get_vm_params(itop_vm, vcenter_vm, organization) ret = itop_vm.save() if ret['code'] == 0: + itop_vms[itop_vm.name] = itop_vm print "Added VM %s" % vm_name else: print "ERROR: VM %s could not be created. Check the return code below." % vm_name From cc9524a7ce32c84cd8a98b953b08429c8f5be773 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 29 Jan 2016 22:04:15 +0100 Subject: [PATCH 062/104] updated license authors --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index a967bbc..6478fb4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015, Guillaume Philippon +Copyright (c) 2015-2016, Guillaume Philippon and Julien Nauroy Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: From 708f0e35e551b98ed148447efb6b28169dcd7c88 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 29 Jan 2016 22:04:45 +0100 Subject: [PATCH 063/104] minor typo --- vcenter2itop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcenter2itop.py b/vcenter2itop.py index f0648ab..f8e2b4f 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -7,7 +7,7 @@ """ __version__ = '1.0' -__authors__ = ['Julien Nauroy '] +__authors__ = ['Julien Nauroy '] from itopapi import ItopapiController, ItopapiConfig, UnsupportedImportFormat from itopcli import load_configuration_cli, ItopcliConfig, NeedMoreArgs From 8cf9b47ca017a1986f89372f42440754608085e0 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 29 Jan 2016 22:08:21 +0100 Subject: [PATCH 064/104] renamed itop-cli.cfg to python-itop-api.cfg to better reflect it's generic to multiple command-line tools. --- .gitignore | 2 +- MANIFEST.in | 2 +- itopcli/itopcliconfig.py | 2 +- itop-cli.cfg.example => python-itop-api.cfg.example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename itop-cli.cfg.example => python-itop-api.cfg.example (94%) diff --git a/.gitignore b/.gitignore index 621b73b..fb37c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .idea *.pyc -itop-cli.cfg +python-itop-api.cfg MANIFEST dist build diff --git a/MANIFEST.in b/MANIFEST.in index 26797ed..15abecf 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1 @@ -include itop-cli.cfg.example \ No newline at end of file +include python-itop-api.cfg.example \ No newline at end of file diff --git a/itopcli/itopcliconfig.py b/itopcli/itopcliconfig.py index ca2776d..26d4720 100644 --- a/itopcli/itopcliconfig.py +++ b/itopcli/itopcliconfig.py @@ -61,7 +61,7 @@ def load_configuration_cli(): # CLI specific argument # ######################### cli_group = parser.add_argument_group('cli') - cli_group.add_argument('--config', dest='config_file', default='./itop-cli.cfg', + cli_group.add_argument('--config', dest='config_file', default='./python-itop-api.cfg', help='configuration file CLI must use' ' (default = %(default)s)') cli_group.add_argument('--classes', dest='classes', nargs='*', metavar='ITOP-CLASS', diff --git a/itop-cli.cfg.example b/python-itop-api.cfg.example similarity index 94% rename from itop-cli.cfg.example rename to python-itop-api.cfg.example index 2f7ce82..d3db7b8 100644 --- a/itop-cli.cfg.example +++ b/python-itop-api.cfg.example @@ -1,4 +1,4 @@ -# This is an example configuration file. copy or rename it to 'itop-cli.cfg' and edit the values. +# This is an example configuration file. copy or rename it to 'python-itop-api.cfg' and edit the values. # At least hostname, username and password will have to be changed. # Make sure to leave 'form' as an allowed login type within Itop's configuration. [main] From 8750f26ab4e10444201a3d99657a48b749196847 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 29 Jan 2016 22:08:43 +0100 Subject: [PATCH 065/104] updated the setup scrit --- setup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index ddd68ef..3e7b887 100644 --- a/setup.py +++ b/setup.py @@ -8,11 +8,11 @@ setup(name='python-itop-api', version='1.0', - description='Set of python script to interact with iTop', - author='Guillaume Philippon', - author_email='guillaume.philippon@lal.in2p3.fr', + description='Set of python scripts to interact with iTop', + author='Guillaume Philippon, Julien Nauroy', + author_email='guillaume.philippon@lal.in2p3.fr, julien.nauroy@u-psud.fr', url='https://github.com/guillaume-philippon/python-itop-api', license='FreeBSD License', - data_files=[('/usr/share/itop-cli', ['itop-cli.cfg.example'])], - scripts=["itop-cli"], + data_files=[('/usr/share/itop-cli', ['python-itop-api.cfg.example'])], + scripts=["itop-cli", "vcenter2itop", "itop2centreon"], packages=find_packages()) From 60eab29635ec50eda63bc7733c56681a87803836 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 29 Jan 2016 22:14:13 +0100 Subject: [PATCH 066/104] Started updating the README file in order to include the two new scripts : itop2centreon and vcenter2itop --- README.md | 96 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 82355b4..162145b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # python-itop-api -API python pour iTop via l'interface REST +Python API to interface iTop to various other tools. +Three command-line scripts are currently provided: itop-cli, vcenter2itop and itop2centreon ## itop-cli -itop-cli is a CLI (command line interface) to iTop REST interface. We can use it to list the content -of iTop classes with the command +itop-cli is a generic CLI (command line interface) to the iTop REST interface. +You can use it to list the contents of iTop classes with the command user@machine> itop-cli --classes server rack @@ -11,40 +12,61 @@ You can also search some specific instance with option --find user@machine> itop-cli --classes server --find host.domain.com -You can have a look of more option with command --help +You can have a look at the options with the --help command user@machine> itop-cli --help - usage: itop-cli [-h] [--hostname HOSTNAME] [--username USERNAME] - [--password PASSWORD] [--config CONFIG_FILE] - [--classes [ITOP-CLASS [ITOP-CLASS ...]]] - [--find INSTANCE [INSTANCE ...]] [--delete INSTANCE INSTANCE] - [--organization ORGANIZATION] [--import URI] [--format FORMAT] - - python CLI for iTop REST api - - optional arguments: - -h, --help show this help message and exit - - itop: - --hostname HOSTNAME hostname of iTop server - --username USERNAME username for iTop authentication - --password PASSWORD password for iTop authentication - - cli: - --config CONFIG_FILE configuration file CLI must use (default = ./itop- - cli.cfg) - --classes [ITOP-CLASS [ITOP-CLASS ...]] - iTop classes to use - --find INSTANCE [INSTANCE ...] - Find and display information about a given class - instance givenits name or ID - --delete INSTANCE INSTANCE - Delete an instance given its class name and instance - ID - --organization ORGANIZATION - iTop organization to use - - import: - --import URI URI of file to import - --format FORMAT Format of file you want import + usage: itop-cli [-h] [--hostname HOSTNAME] [--username USERNAME] + [--password PASSWORD] [--organization ORGANIZATION-NAME] + [--virtualhost VIRTUAL-HOSTNAME] [--config CONFIG_FILE] + [--classes [ITOP-CLASS [ITOP-CLASS ...]]] + [--find INSTANCE [INSTANCE ...]] [--delete] [--import-uri URI] + [--import-stdin] [--format FORMAT] [--save] + [--prevent-duplicates] + + python CLI for iTop REST api + + optional arguments: + -h, --help show this help message and exit + + itop: + --hostname HOSTNAME hostname of iTop server + --username USERNAME username for iTop authentication + --password PASSWORD password for iTop authentication + --organization ORGANIZATION-NAME + iTop organization to use + --virtualhost VIRTUAL-HOSTNAME + Itop's virtual host name for VMs + + cli: + --config CONFIG_FILE configuration file CLI must use (default = ./itop- + cli.cfg) + --classes [ITOP-CLASS [ITOP-CLASS ...]] + iTop classes to use + --find INSTANCE [INSTANCE ...] + Find and display information about a given class + instance givenits name or ID + --delete Delete all instances previously loaded + --save Save the instances loaded through import + --prevent-duplicates Check if objects with the same name already exist + before savingand don't save in this case + + import: + --import-uri URI URI of file to import + --import-stdin import data from STDIN + --format FORMAT Format of file you want import + + +## vcenter2itop +vcenter2itop focuses on extracting data from a VMWare VCenter cluster and importing it into iTop. +It synchronises Farms, Servers, Hypervisors and VirtualMachines present in a VCenter as well as Brands, Models, OS Families and Versions. +It has a dependency on the pyVmomi module. + +All parameters are set into the common python-itop-api.cfg script. vcenter2itop is then simply runs this way: + + user@machine> vcenter2itop + +# itop2centreon +itop2centreon is an attempt at synchronizing iTop with the Centreon monitoring system through its CLAPI (command-line API) interface. +For now, it synchronizes the list of machines (Servers and VMs) and contacts. +It can serve as a kickstart script for your own synchronization mechanism. From 40a1384aa4be33845a60fcc256bd32b0535c9c46 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 29 Jan 2016 22:16:10 +0100 Subject: [PATCH 067/104] Updated authors --- itop2centreon.py | 2 +- itopapi/model/prototype.py | 2 +- itopapi/model/rack.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/itop2centreon.py b/itop2centreon.py index de6a3a5..343c5b0 100644 --- a/itop2centreon.py +++ b/itop2centreon.py @@ -6,7 +6,7 @@ """ __version__ = '1.0' -__authors__ = ['Julien Nauroy '] +__authors__ = ['Julien Nauroy '] from itopapi import ItopapiController, ItopapiConfig, UnsupportedImportFormat from itopcli import load_configuration_cli, ItopcliConfig, NeedMoreArgs diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 3454fe5..6398b2f 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -9,7 +9,7 @@ from itopapi.itopapiconfig import ItopapiConfig __version__ = '1.0' -__authors__ = ['Guillaume Philippon '] +__authors__ = ['Guillaume Philippon ', 'Julien Nauroy '] class UnknownItopClass(Exception): diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index 83ca970..feda439 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -7,7 +7,7 @@ from itopapi.model.prototype import ItopapiPrototype __version__ = '1.0' -__authors__ = ['Guillaume Philippon '] +__authors__ = ['Guillaume Philippon ', 'Julien Nauroy '] class ItopapiRack(ItopapiPrototype): From 3c03151ee0c6ea7a375cfd06cc2d2d39395084ef Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 11:57:00 +0100 Subject: [PATCH 068/104] english --- itopapi/model/applicationSolution.py | 2 +- itopapi/model/dbserver.py | 2 +- itopapi/model/deliveryModel.py | 2 +- itopapi/model/organization.py | 2 +- itopapi/model/othersoftware.py | 2 +- itopapi/model/rack.py | 2 +- itopapi/model/server.py | 2 +- itopapi/model/team.py | 2 +- itopapi/model/webApplication.py | 2 +- itopapi/model/webServer.py | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index 8dfb6b9..b98564c 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -42,7 +42,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiApplicationSolution) """ - ItopapiApplicationSolution is a object that represents an Application Solution from iTop + ItopapiApplicationSolution is an object that represents an Application Solution from iTop """ def __init__(self, data=None): super(ItopapiApplicationSolution, self).__init__(data) diff --git a/itopapi/model/dbserver.py b/itopapi/model/dbserver.py index 5622044..473e547 100644 --- a/itopapi/model/dbserver.py +++ b/itopapi/model/dbserver.py @@ -13,7 +13,7 @@ class ItopapiDBServer(ItopapiOtherSoftware): """ - ItopapiDBServer is a object that represents a DBServer from iTop + ItopapiDBServer is an object that represents a DBServer from iTop It has the same attributes as ItopapiOtherSoftware """ diff --git a/itopapi/model/deliveryModel.py b/itopapi/model/deliveryModel.py index 374353b..731b4e7 100644 --- a/itopapi/model/deliveryModel.py +++ b/itopapi/model/deliveryModel.py @@ -40,7 +40,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiDeliveryModel) """ - ItopapiDeliveryModel is a object that represents an Application Solution from iTop + ItopapiDeliveryModel is an object that represents an Application Solution from iTop """ def __init__(self, data=None): super(ItopapiDeliveryModel, self).__init__(data) diff --git a/itopapi/model/organization.py b/itopapi/model/organization.py index dada9c9..b77127b 100644 --- a/itopapi/model/organization.py +++ b/itopapi/model/organization.py @@ -39,7 +39,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiOrganization) """ - ItopapiOrganization is a object that represents an Application Solution from iTop + ItopapiOrganization is an object that represents an Application Solution from iTop """ def __init__(self, data=None): super(ItopapiOrganization, self).__init__(data) diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index fe4f9b4..2c3181c 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -13,7 +13,7 @@ class ItopapiOtherSoftware(ItopapiPrototype): """ - ItopapiOtherSoftware is a object that represents a OtherSoftware from iTop + ItopapiOtherSoftware is an object that represents a OtherSoftware from iTop """ """ Configuration specific to itop """ diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index feda439..b483671 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -12,7 +12,7 @@ class ItopapiRack(ItopapiPrototype): """ - ItopapiRack is a object that represents a Rack from iTop + ItopapiRack is an object that represents a Rack from iTop """ """ Configuration specific to itop """ diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 36c6d5e..bf9b808 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -12,7 +12,7 @@ class ItopapiServer(ItopapiPrototype): """ - ItopapiServers is a object that represents a Servers from iTop + ItopapiServers is an object that represents a Servers from iTop """ # Configuration specific to itop diff --git a/itopapi/model/team.py b/itopapi/model/team.py index b007b23..c04b9a1 100644 --- a/itopapi/model/team.py +++ b/itopapi/model/team.py @@ -12,7 +12,7 @@ class ItopapiTeam(ItopapiPrototype): """ - ItopapiTeam is a object that represents a Team from iTop + ItopapiTeam is an object that represents a Team from iTop """ """ Configuration specific to itop """ diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index dd75cba..25b8b38 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -13,7 +13,7 @@ class ItopapiWebApplication(ItopapiPrototype): """ - ItopapiWebApplication is a object that represents a WebApplication from iTop + ItopapiWebApplication is an object that represents a WebApplication from iTop """ # Configuration specific to itop diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index d28cecf..7c00afe 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -13,7 +13,7 @@ class ItopapiWebServer(ItopapiPrototype): """ - ItopapiWebServer is a object that represents a WebServer from iTop + ItopapiWebServer is an object that represents a WebServer from iTop """ # Configuration specific to itop From 8f8ee367530d33ee2142c1f31a23be67a7031fda Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 15:44:26 +0100 Subject: [PATCH 069/104] Added a new HasOrganization feature (mixin) and updated the data model accordingly --- itopapi/model/applicationSolution.py | 25 ++++-------- itopapi/model/deliveryModel.py | 16 ++------ itopapi/model/enclosure.py | 22 ++--------- itopapi/model/farm.py | 23 ++--------- itopapi/model/features/__init__.py | 11 ++++++ itopapi/model/features/hasOrganization.py | 45 +++++++++++++++++++++ itopapi/model/features/hasOrganization2.py | 46 ++++++++++++++++++++++ itopapi/model/hypervisor.py | 21 ++-------- itopapi/model/incident.py | 22 ++--------- itopapi/model/location.py | 23 ++--------- itopapi/model/osLicence.py | 22 ++--------- itopapi/model/othersoftware.py | 21 ++-------- itopapi/model/person.py | 20 ++-------- itopapi/model/powerSource.py | 20 ++-------- itopapi/model/prototype.py | 1 + itopapi/model/rack.py | 20 ++-------- itopapi/model/server.py | 20 ++-------- itopapi/model/service.py | 17 ++------ itopapi/model/subnet.py | 23 ++--------- itopapi/model/team.py | 20 ++-------- itopapi/model/virtualMachine.py | 20 ++-------- itopapi/model/vlan.py | 20 ++-------- itopapi/model/webApplication.py | 21 ++-------- itopapi/model/webServer.py | 15 ------- vcenter2itop.py | 42 ++++++++------------ 25 files changed, 187 insertions(+), 369 deletions(-) create mode 100644 itopapi/model/features/__init__.py create mode 100644 itopapi/model/features/hasOrganization.py create mode 100644 itopapi/model/features/hasOrganization2.py diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index b98564c..ef887b6 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -5,12 +5,17 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization + __version__ = '1.0' __authors__ = ['Julien Nauroy '] -""" TODO not completed and tested yet, created as a dependency of TiopapiRack """ -class ItopapiApplicationSolution(ItopapiPrototype): + +class ItopapiApplicationSolution(ItopapiPrototype, HasOrganization): + """ + TODO not completed and tested yet, created as a dependency of TiopapiRack. Probably missing redundancy + """ # Configuration specific to itop itop = { @@ -19,6 +24,7 @@ class ItopapiApplicationSolution(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ + HasOrganization.foreign_key, {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, ], 'list_types': { @@ -49,13 +55,6 @@ def __init__(self, data=None): ################################## # Properties # ################################## - # Application Solution's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # Application Solution's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Application Solution's organization name - self.organization_name = None # Application Solution's status. Values within [inactive, active] self.status = None # Application Solution's business criticity. Values within [high, medium, low] @@ -76,11 +75,3 @@ def __init__(self, data=None): self.services_list = None self.contacts_list = None self.providercontracts_list = None - - def find_organization(self): - """ - Retrieve the parent ItopapiOrganization - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None \ No newline at end of file diff --git a/itopapi/model/deliveryModel.py b/itopapi/model/deliveryModel.py index 731b4e7..6f08085 100644 --- a/itopapi/model/deliveryModel.py +++ b/itopapi/model/deliveryModel.py @@ -5,11 +5,12 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiDeliveryModel(ItopapiPrototype): +class ItopapiDeliveryModel(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -18,7 +19,7 @@ class ItopapiDeliveryModel(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'description'], 'foreign_keys': [ - {'id': 'organization_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -46,20 +47,9 @@ def __init__(self, data=None): super(ItopapiDeliveryModel, self).__init__(data) self.description = None - self.org_id = None - self.organization_name = None - self.org_id_friendlyname = None ################################## # Lists # ################################## self.customers_list = [] self.contacts_list = [] - - def find_organization(self): - """ - Retrieve the parent ItopapiOrganization - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None \ No newline at end of file diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 241d569..dd28304 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiEnclosure(ItopapiPrototype): +class ItopapiEnclosure(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -20,12 +21,12 @@ class ItopapiEnclosure(ItopapiPrototype): 'save': ['name', 'status', 'business_criticity', 'nb_u', 'serialnumber', 'asset_number', 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, - ] + ], } @staticmethod def find(key): @@ -45,13 +46,6 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiEnclosure, self).__init__(data) - # Enclosure's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # Enclosure's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Enclosure's organization name - self.organization_name = None # Enclosure's status. Values within [implementation, obsolete, production, stock] self.status = None # Enclosure's business criticity. Values within [high, medium, low] @@ -90,14 +84,6 @@ def __init__(self, data=None): self.end_of_warranty = None self.description = None - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this server - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - def find_location(self): """ Retrieve the ItopapiLocation related to this instance diff --git a/itopapi/model/farm.py b/itopapi/model/farm.py index c46cad2..b13f0af 100644 --- a/itopapi/model/farm.py +++ b/itopapi/model/farm.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiFarm(ItopapiPrototype): +class ItopapiFarm(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -19,7 +20,7 @@ class ItopapiFarm(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -45,13 +46,6 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiFarm, self).__init__(data) - # Farm's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # Farm's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Farm's organization name - self.organization_name = None # Farm's status. Values within [inactive, active] self.status = None # Farm's business criticity. Values within [high, medium, low] @@ -70,13 +64,4 @@ def __init__(self, data=None): self.services_list = None self.logicalvolumes_list = None self.hypervisor_list = None - self.virtualmachine_list = None - - - def find_organization(self): - """ - Retrieve the parent ItopapiOrganization - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None \ No newline at end of file + self.virtualmachine_list = None \ No newline at end of file diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py new file mode 100644 index 0000000..8161dc6 --- /dev/null +++ b/itopapi/model/features/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf8 -*-fr + +""" +Import all class needed +""" + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasOrganization2 import HasOrganization2 diff --git a/itopapi/model/features/hasOrganization.py b/itopapi/model/features/hasOrganization.py new file mode 100644 index 0000000..c79fce6 --- /dev/null +++ b/itopapi/model/features/hasOrganization.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasOrganization is a mixin representing the organization attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasOrganization(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'} + + def __init__(self): + super(HasOrganization, self).__init__() + # Object's organization id. Call find_organization to get the full information or just use + # org_id_friendlyname and organization_name + self.org_id = None + # Object's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Object's organization name + self.organization_name = None + + def find_organization(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.org_id is not None: + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None + + def set_organization(self, organization): + """ + Set the ItopapiOrganization parameters + """ + self.org_id = organization.instance_id + self.org_id_friendlyname = organization.friendlyname + self.organization_name = organization.name diff --git a/itopapi/model/features/hasOrganization2.py b/itopapi/model/features/hasOrganization2.py new file mode 100644 index 0000000..9bc15bf --- /dev/null +++ b/itopapi/model/features/hasOrganization2.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasOrganization2 is a mixin representing the organization attached to some of the objects. +It is only used by ItopaiVLAN which has org_name instead of organization_name +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasOrganization2(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'org_id', 'name': 'org_name', 'table': 'Organization'} + + def __init__(self): + super(HasOrganization2, self).__init__() + # Object's organization id. Call find_organization to get the full information or just use + # org_id_friendlyname and organization_name + self.org_id = None + # Object's organization friendly name. Not sure the difference with organization_name + self.org_id_friendlyname = None + # Object's organization name + self.org_name = None + + def find_organization(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.org_id is not None: + return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) + return None + + def set_organization(self, organization): + """ + Set the ItopapiOrganization parameters + """ + self.org_id = organization.instance_id + self.org_id_friendlyname = organization.friendlyname + self.org_name = organization.name diff --git a/itopapi/model/hypervisor.py b/itopapi/model/hypervisor.py index 17212a8..8184293 100644 --- a/itopapi/model/hypervisor.py +++ b/itopapi/model/hypervisor.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiHypervisor(ItopapiPrototype): +class ItopapiHypervisor(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -19,7 +20,7 @@ class ItopapiHypervisor(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'server_id', 'name': 'server_name', 'table': 'Server'}, {'id': 'farm_id', 'name': 'farm_name', 'table': 'Farm'}, ], @@ -47,13 +48,6 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiHypervisor, self).__init__(data) - # Hypervisor's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # Hypervisor's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Hypervisor's organization name - self.organization_name = None # Hypervisor's status. Values within [inactive, active] self.status = None # Hypervisor's business criticity. Values within [high, medium, low] @@ -81,12 +75,3 @@ def __init__(self, data=None): self.documents_list = None self.contacts_list = None self.logicalvolumes_list = None - - - def find_organization(self): - """ - Retrieve the parent ItopapiOrganization - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index 600a837..a9a8436 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiIncident(ItopapiPrototype): +class ItopapiIncident(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -19,7 +20,7 @@ class ItopapiIncident(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['title', 'description', 'ref', 'start_date', 'end_date', 'close_date', 'last_update'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'agent_id', 'name': 'agent_name', 'table': 'Person'}, {'id': 'team_id', 'name': 'team_name', 'table': 'Team'}, ], @@ -56,13 +57,6 @@ def __init__(self, data=None): self.end_date = None self.close_date = None self.last_update = None - # Incident's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # Incident's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Incident's organization name - self.organization_name = None # Foreign key to a Person self.agent_id = None @@ -79,13 +73,3 @@ def __init__(self, data=None): self.contacts_list = None self.workers_list = None self.private_log = None - - - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this server - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - diff --git a/itopapi/model/location.py b/itopapi/model/location.py index 7594326..1a17c35 100644 --- a/itopapi/model/location.py +++ b/itopapi/model/location.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiLocation(ItopapiPrototype): +class ItopapiLocation(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -19,8 +20,8 @@ class ItopapiLocation(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'status', 'address', 'postal_code', 'city', 'country'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, - ] + HasOrganization.foreign_key, + ], } @staticmethod @@ -44,13 +45,6 @@ def __init__(self, data=None): super(ItopapiLocation, self).__init__(data) # Location's status. Values within [inactive, active] self.status = None - # Location's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # Location's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Location's organization name - self.organization_name = None # Location's street address. Generally multiline self.address = None self.postal_code = None @@ -59,12 +53,3 @@ def __init__(self, data=None): # Lists self.person_list = {} self.physicaldevice_list = {} - - - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this server - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py index 0907eaf..72eb6eb 100644 --- a/itopapi/model/osLicence.py +++ b/itopapi/model/osLicence.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOSLicence(ItopapiPrototype): +class ItopapiOSLicence(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -19,9 +20,9 @@ class ItopapiOSLicence(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'usage_limit', 'description', 'perpetual', 'start_date', 'end_date', 'licence_key'], 'foreign_keys': [ + HasOrganization.foreign_key, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, - ] + ], } @staticmethod @@ -46,13 +47,6 @@ def __init__(self, data=None): self.osversion_id = None self.osversion_id_friendlyname = None self.osversion_name = None - # OSLicence's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # OSLicence's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # OSLicence's organization name - self.organization_name = None # Number of concurrent users or licences self.usage_limit = None self.description = None @@ -73,11 +67,3 @@ def find_os_version(self): if self.osversion_id is not None: return ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) return None - - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this server - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index 2c3181c..c814688 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -3,15 +3,15 @@ """ ItopapiOtherSoftware is a abstraction of OtherSoftware representation on iTop """ -# TODO represent the hierarchy of software classes: PC Software, Middleware, DB server, Web Server, Other Software from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOtherSoftware(ItopapiPrototype): +class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization): """ ItopapiOtherSoftware is an object that represents a OtherSoftware from iTop """ @@ -23,7 +23,7 @@ class ItopapiOtherSoftware(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, ], @@ -52,13 +52,6 @@ def __init__(self, data=None): ################################## # Properties # ################################## - # OtherSoftware's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # OtherSoftware's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # OtherSoftware's organization name - self.organization_name = None # OtherSoftware's software (good job!) self.software_id = None self.software_id_friendlyname = None @@ -88,11 +81,3 @@ def __init__(self, data=None): self.contacts_list = {} self.providercontracts_list = {} self.applicationsolution_list = {} - - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None diff --git a/itopapi/model/person.py b/itopapi/model/person.py index 8327bf5..edae7d6 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -6,12 +6,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPerson(ItopapiPrototype): +class ItopapiPerson(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -21,8 +22,8 @@ class ItopapiPerson(ItopapiPrototype): 'save': ['contact_id', 'contact_name', 'function', 'first_name', 'name', 'email', 'mobile_phone', 'phone', 'notify', 'employee_number', 'status'], 'foreign_keys': [ + HasOrganization.foreign_key, {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, {'id': 'manager_id', 'name': 'manager_name', 'table': 'Person'}, ], 'list_types': { @@ -62,16 +63,9 @@ def __init__(self, data=None): self.location_id_friendlyname = None # Person's location name self.location_name = None - # Person's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # Person's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None self.manager_id = None, self.manager_id_friendlyname = None, self.manager_name = None, - # Person's organization name - self.organization_name = None self.function = None self.first_name = None self.email = None @@ -96,11 +90,3 @@ def find_location(self): if self.location_id is not None: return ItopapiPrototype.get_itop_class('Location').find(self.location_id) return None - - def find_organization(self): - """ - Retrieve the parent ItopapiOrganization - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py index 10a89ea..6e75e3a 100644 --- a/itopapi/model/powerSource.py +++ b/itopapi/model/powerSource.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPowerSource(ItopapiPrototype): +class ItopapiPowerSource(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -20,7 +21,7 @@ class ItopapiPowerSource(ItopapiPrototype): 'save': ['name', 'status', 'business_criticity', 'serialnumber', 'asset_number', 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, @@ -47,13 +48,6 @@ def find_all(): def __init__(self, data=None): super(ItopapiPowerSource, self).__init__(data) - # PowerSource's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # PowerSource's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # PowerSource's organization name - self.organization_name = None # PowerSource's status. Values within [implementation, obsolete, production, stock] self.status = None # PowerSource's business criticity. Values within [high, medium, low] @@ -94,14 +88,6 @@ def __init__(self, data=None): self.providercontracts_list = {} self.pdus_list = {} - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this server - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - def find_location(self): """ Retrieve the ItopapiLocation related to this instance diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 6398b2f..f0c1d46 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -35,6 +35,7 @@ class ItopapiPrototype(object): itop = {'name': '', 'save': [], 'foreign_keys': [], 'list_types': {}} def __init__(self, data=None): + super(ItopapiPrototype, self).__init__() self.instance_id = None # Every instance should have an unique ID self.name = None diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index b483671..ca793df 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Guillaume Philippon ', 'Julien Nauroy '] -class ItopapiRack(ItopapiPrototype): +class ItopapiRack(ItopapiPrototype, HasOrganization): """ ItopapiRack is an object that represents a Rack from iTop """ @@ -23,7 +24,7 @@ class ItopapiRack(ItopapiPrototype): 'save': ['name', 'status', 'business_criticity', 'nb_u', 'serialnumber', 'asset_number', 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, ], 'list_types': { @@ -51,13 +52,6 @@ def __init__(self, data=None): ################################## # Properties # ################################## - # Rack's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # Rack's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Rack's organization name - self.organization_name = None # Rack's status. Values within [implementation, obsolete, production, stock] self.status = None # Rack's business criticity. Values within [high, medium, low] @@ -131,14 +125,6 @@ def __init__(self, data=None): self.softwares_list = None self.logicalvolumes_list = None - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - def find_location(self): """ Retrieve the ItopapiLocation related to this instance diff --git a/itopapi/model/server.py b/itopapi/model/server.py index bf9b808..20a1f32 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype): +class ItopapiServer(ItopapiPrototype, HasOrganization): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -24,7 +25,7 @@ class ItopapiServer(ItopapiPrototype): 'cpu', 'ram', 'nb_u', 'serialnumber', 'asset_number', 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, @@ -62,13 +63,6 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # Server's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # Server's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Server's organization name - self.organization_name = None # Server's status. Values within [implementation, obsolete, production, stock] self.status = None # Server's business criticity. Values within [high, medium, low] @@ -240,14 +234,6 @@ def find_rack(self): return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this server - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - def find_location(self): """ Retrieve the ItopapiLocation related to this instance diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 3a9ea79..01ce3fd 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiService(ItopapiPrototype): +class ItopapiService(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -19,8 +20,8 @@ class ItopapiService(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'description', 'status'], 'foreign_keys': [ + HasOrganization.foreign_key, {'id': 'servicefamily_id', 'name': 'servicefamily_name', 'table': 'ServiceFamily'}, - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, ], 'list_types': { 'functionalcis_list': 'functionalci_id_finalclass_recall', @@ -47,10 +48,6 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiService, self).__init__(data) - # Note: the Organization is called "Provider" for Services - self.org_id = None - self.org_id_friendlyname = None - self.organization_name = None # Service Family self.servicefamily_id = None self.servicefamily_id_friendlyname = None @@ -66,11 +63,3 @@ def __init__(self, data=None): self.customercontracts_list = None self.providercontracts_list = None self.functionalcis_list = None - - def find_organization(self): - """ - Retrieve the ItopapiOrganization corresponding to this server - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None diff --git a/itopapi/model/subnet.py b/itopapi/model/subnet.py index 5cbcc44..4f9a967 100644 --- a/itopapi/model/subnet.py +++ b/itopapi/model/subnet.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiSubnet(ItopapiPrototype): +class ItopapiSubnet(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -19,7 +20,7 @@ class ItopapiSubnet(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['ip', 'ip_mask', 'subnet_name', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, ], 'list_types': {'vlans_list': 'VLAN'}, } @@ -49,23 +50,7 @@ def __init__(self, data=None): self.ip_mask = None # Subnet name self.subnet_name = None - # Subnet's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # Subnet's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Subnet's organization name - self.org_name = None # Subnet's description self.description = None # VLANs associated with this Subnet - self.vlans_list = None - - - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None \ No newline at end of file + self.vlans_list = None \ No newline at end of file diff --git a/itopapi/model/team.py b/itopapi/model/team.py index c04b9a1..f823792 100644 --- a/itopapi/model/team.py +++ b/itopapi/model/team.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiTeam(ItopapiPrototype): +class ItopapiTeam(ItopapiPrototype, HasOrganization): """ ItopapiTeam is an object that represents a Team from iTop """ @@ -22,7 +23,7 @@ class ItopapiTeam(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['status', 'phone', 'notify', 'name', 'function', 'email'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, ], 'list_types': { 'persons_list': 'Person', @@ -50,13 +51,6 @@ def __init__(self, data=None): ################################## # Properties # ################################## - # Team's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # Team's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # Team's organization name - self.organization_name = None self.status = None self.phone = None self.notify = None @@ -68,11 +62,3 @@ def __init__(self, data=None): self.cis_list = None self.tickets_list = None self.persons_list = None - - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 326c943..258e531 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiVirtualMachine(ItopapiPrototype): +class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization): # Configuration specific to itop itop = { @@ -20,8 +21,8 @@ class ItopapiVirtualMachine(ItopapiPrototype): 'managementip', 'oslicence_id', 'cpu', 'ram', 'move2production', 'description'], 'foreign_keys': [ + HasOrganization.foreign_key, {'id': 'virtualhost_id', 'name': 'virtualhost_name', 'table': 'VirtualHost'}, - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, @@ -54,13 +55,6 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # VirtualMachine's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # VirtualMachine's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # VirtualMachine's organization name - self.organization_name = None # VirtualMachine's status. Values within [implementation, obsolete, production, stock] self.status = None # VirtualMachine's business criticity. Values within [high, medium, low] @@ -165,14 +159,6 @@ def load_from_json_quattor(self, json_quattor): """ pass - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - def find_os_family(self): """ Retrieve the ItopapiOSFamily corresponding to this VirtualMachine diff --git a/itopapi/model/vlan.py b/itopapi/model/vlan.py index 3db6916..0d25a43 100644 --- a/itopapi/model/vlan.py +++ b/itopapi/model/vlan.py @@ -6,12 +6,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOrganization2 import HasOrganization2 __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiVLAN(ItopapiPrototype): +class ItopapiVLAN(ItopapiPrototype, HasOrganization2): # Configuration specific to itop itop = { @@ -20,7 +21,7 @@ class ItopapiVLAN(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['vlan_tag', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization2.foreign_key ], 'list_types': {'physicalinterfaces_list': 'PhysicalInterface', 'subnets_list': 'Subnet'}, } @@ -46,24 +47,9 @@ def __init__(self, data=None): super(ItopapiVLAN, self).__init__(data) # VLAN tag, replaces the "name" value for other classes self.vlan_tag = None - # VLAN's organization id. Call find_organization to get the full information or just use - # org_id_friendlyname and organization_name - self.org_id = None - # VLAN's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # VLAN's organization name - self.org_name = None # VLAN's description self.description = None # Interfaces self.physicalinterfaces_list = None # subnets self.subnets_list = None - - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None \ No newline at end of file diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 25b8b38..e2938d2 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -5,13 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod -from itopapi.model.rack import ItopapiRack +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiWebApplication(ItopapiPrototype): +class ItopapiWebApplication(ItopapiPrototype, HasOrganization): """ ItopapiWebApplication is an object that represents a WebApplication from iTop """ @@ -24,7 +24,7 @@ class ItopapiWebApplication(ItopapiPrototype): 'save': ['name', 'url', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'webserver_id', 'name': 'webserver_name', 'table': 'WebServer'}, ], 'list_types': { @@ -53,13 +53,6 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # WebApplication's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # WebApplication's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # WebApplication's organization name - self.organization_name = None # WebServer hosting the application self.webserver_id = None self.webserver_id_friendlyname = None @@ -116,14 +109,6 @@ def load_from_json_quattor(self, json_quattor): """ pass - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - def find_web_server(self): """ Retrieve the ItopapiWebServer corresponding to this WebApplication diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 7c00afe..38be7c1 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -53,13 +53,6 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # WebServer's organization id. Call find_organization to get the full information or just - # use org_id_friendlyname and organization_name - self.org_id = None - # WebServer's organization friendly name. Not sure the difference with organization_name - self.org_id_friendlyname = None - # WebServer's organization name - self.organization_name = None # WebServer's status. Values within [implementation, obsolete, production, stock] self.status = None # WebServer's business criticity. Values within [high, medium, low] @@ -163,14 +156,6 @@ def load_from_json_quattor(self, json_quattor): """ pass - def find_organization(self): - """ - Retrieve the ItopapiOrganization related to this instance - """ - if self.org_id is not None: - return ItopapiPrototype.get_itop_class('Organization').find(self.org_id) - return None - def find_system(self): """ Retrieve the System (Server or VirtualMachine) corresponding to this WebServer diff --git a/vcenter2itop.py b/vcenter2itop.py index f8e2b4f..1c47e2b 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -140,29 +140,27 @@ def get_virtualhost(virtualhost_name, organization): global itop_farms, itop_hypervisors # Check if the virtualhost is a farm (shouldn't be directly) - farm = itop_farms.get(virtualhost_name) - if farm is not None: - return farm + itop_farm = itop_farms.get(virtualhost_name) + if itop_farm is not None: + return itop_farm # Check if the virtualhost is an hypervisor hypervisor = itop_hypervisors.get(virtualhost_name) if hypervisor is not None: # If the hypervisor is within a farm, then return the farm - farm = itop_farms.get(hypervisor.farm_name) - if farm is not None: - return farm + itop_farm = itop_farms.get(hypervisor.farm_name) + if itop_farm is not None: + return itop_farm else: return hypervisor # By default, create a farm and not an hypervisor. # Maybe add a configuration option somewhere - farm = ItopapiFarm() - farm.name = virtualhost_name + itop_farm = ItopapiFarm() + itop_farm.name = virtualhost_name # Set the organization - farm.org_id = organization.instance_id - farm.org_id_friendlyname = organization.friendlyname - farm.organization_name = organization.name - farm.save() - itop_farms[virtualhost_name] = farm - return farm + itop_farm.set_organization(organization) + itop_farm.save() + itop_farms[virtualhost_name] = itop_farm + return itop_farm # Fill data of a VCenter's Cluster into an ItopapiFarm instance @@ -175,9 +173,7 @@ def get_farm_params(itop_farm, vcenter_cluster, organization): # Set the organization if itop_farm.org_id != organization.instance_id: has_changed = True - itop_farm.org_id = organization.instance_id - itop_farm.org_id_friendlyname = organization.friendlyname - itop_farm.organization_name = organization.name + itop_farm.set_organization(organization) # Set other fields if itop_farm.name != vcenter_cluster.name: has_changed = True @@ -205,9 +201,7 @@ def get_server_params(itop_server, vcenter_host, organization): # Set the organization if itop_server.org_id != organization.instance_id: has_changed = True - itop_server.org_id = organization.instance_id - itop_server.org_id_friendlyname = organization.friendlyname - itop_server.organization_name = organization.name + itop_server.set_organization(organization) # Set the OS family os_family = get_os_family(product.name) if itop_server.osfamily_id != os_family.instance_id: @@ -255,8 +249,8 @@ def get_hypervisor_params(itop_hypervisor, itop_server): global host_to_farm # Set the organization. Same at the server's one itop_hypervisor.org_id = itop_server.org_id - itop_hypervisor.org_id_friendlyname = itop_server.friendlyname - itop_hypervisor.organization_name = itop_server.name + itop_hypervisor.org_id_friendlyname = itop_server.org_id_friendlyname + itop_hypervisor.organization_name = itop_server.organization_name # Set the server itop_hypervisor.server_id = itop_server.instance_id itop_hypervisor.server_id_friendlyname = itop_server.friendlyname @@ -292,9 +286,7 @@ def get_vm_params(itop_vm, vcenter_vm, organization): or itop_vm.osversion_id != os_version.instance_id \ or itop_vm.virtualhost_id != virtualhost.instance_id # Set the organization - itop_vm.org_id = organization.instance_id - itop_vm.org_id_friendlyname = organization.friendlyname - itop_vm.organization_name = organization.name + itop_vm.set_organization(organization) # Set the OS family itop_vm.osfamily_id = os_family.instance_id itop_vm.osfamily_id_friendlyname = os_family.friendlyname From 7c6ce1c9dbf4de0e57b3b52f010291a79bc57b37 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 15:45:21 +0100 Subject: [PATCH 070/104] english --- itopapi/model/applicationSolution.py | 2 +- itopapi/model/brand.py | 2 +- itopapi/model/dbserver.py | 2 +- itopapi/model/deliveryModel.py | 2 +- itopapi/model/enclosure.py | 2 +- itopapi/model/farm.py | 2 +- itopapi/model/hypervisor.py | 2 +- itopapi/model/incident.py | 2 +- itopapi/model/location.py | 2 +- itopapi/model/model.py | 2 +- itopapi/model/organization.py | 2 +- itopapi/model/osFamily.py | 2 +- itopapi/model/osLicence.py | 2 +- itopapi/model/osVersion.py | 2 +- itopapi/model/othersoftware.py | 2 +- itopapi/model/person.py | 2 +- itopapi/model/physicalInterface.py | 2 +- itopapi/model/powerSource.py | 2 +- itopapi/model/rack.py | 2 +- itopapi/model/server.py | 2 +- itopapi/model/service.py | 2 +- itopapi/model/subnet.py | 2 +- itopapi/model/team.py | 2 +- itopapi/model/virtualMachine.py | 2 +- itopapi/model/vlan.py | 2 +- itopapi/model/webApplication.py | 2 +- itopapi/model/webServer.py | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index ef887b6..81d77b3 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=invalid-name """ -ItopapiApplicationSolution is a abstraction of Application Solution representation on iTop +ItopapiApplicationSolution is an abstraction of Application Solution representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/brand.py b/itopapi/model/brand.py index af1f9b5..d3bc386 100644 --- a/itopapi/model/brand.py +++ b/itopapi/model/brand.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiBrand is a abstraction of Brand representation on iTop +ItopapiBrand is an abstraction of Brand representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/dbserver.py b/itopapi/model/dbserver.py index 473e547..6759792 100644 --- a/itopapi/model/dbserver.py +++ b/itopapi/model/dbserver.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes, invalid-name """ -ItopapiDBServer is a abstraction of DBServer representation on iTop +ItopapiDBServer is an abstraction of DBServer representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/deliveryModel.py b/itopapi/model/deliveryModel.py index 6f08085..38356c4 100644 --- a/itopapi/model/deliveryModel.py +++ b/itopapi/model/deliveryModel.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=invalid-name """ -ItopapiDeliveryModel is a abstraction of Organization representation on iTop +ItopapiDeliveryModel is an abstraction of Organization representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index dd28304..9a8a2d3 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiEnclosure is a abstraction of Rack representation on iTop +ItopapiEnclosure is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/farm.py b/itopapi/model/farm.py index b13f0af..6a5b1c5 100644 --- a/itopapi/model/farm.py +++ b/itopapi/model/farm.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiFarm is a abstraction of a virtual servers farm representation on iTop +ItopapiFarm is an abstraction of a virtual servers farm representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/hypervisor.py b/itopapi/model/hypervisor.py index 8184293..d4ecdb8 100644 --- a/itopapi/model/hypervisor.py +++ b/itopapi/model/hypervisor.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiHypervisor is a abstraction of a virtual servers Hypervisor representation on iTop +ItopapiHypervisor is an abstraction of a virtual servers Hypervisor representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index a9a8436..986f16e 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiIncident is a abstraction of a Incident representation on iTop +ItopapiIncident is an abstraction of a Incident representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/location.py b/itopapi/model/location.py index 1a17c35..3d420f2 100644 --- a/itopapi/model/location.py +++ b/itopapi/model/location.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiLocation is a abstraction of a Location representation on iTop +ItopapiLocation is an abstraction of a Location representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/model.py b/itopapi/model/model.py index 860810f..3b6cf04 100644 --- a/itopapi/model/model.py +++ b/itopapi/model/model.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiModel is a abstraction of Model representation on iTop +ItopapiModel is an abstraction of Model representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/organization.py b/itopapi/model/organization.py index b77127b..12a2587 100644 --- a/itopapi/model/organization.py +++ b/itopapi/model/organization.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=invalid-name """ -ItopapiOrganization is a abstraction of Organization representation on iTop +ItopapiOrganization is an abstraction of Organization representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/osFamily.py b/itopapi/model/osFamily.py index 76ac065..a7533d5 100644 --- a/itopapi/model/osFamily.py +++ b/itopapi/model/osFamily.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiOSFamily is a abstraction of Rack representation on iTop +ItopapiOSFamily is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py index 72eb6eb..daebe32 100644 --- a/itopapi/model/osLicence.py +++ b/itopapi/model/osLicence.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiOSLicence is a abstraction of Rack representation on iTop +ItopapiOSLicence is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/osVersion.py b/itopapi/model/osVersion.py index 58d1995..839181e 100644 --- a/itopapi/model/osVersion.py +++ b/itopapi/model/osVersion.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiOSVersion is a abstraction of Rack representation on iTop +ItopapiOSVersion is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index c814688..8cfc0af 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes, invalid-name """ -ItopapiOtherSoftware is a abstraction of OtherSoftware representation on iTop +ItopapiOtherSoftware is an abstraction of OtherSoftware representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/person.py b/itopapi/model/person.py index edae7d6..3e94e15 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiPerson is a abstraction of a Person representation on iTop +ItopapiPerson is an abstraction of a Person representation on iTop Note : Person has no finalclass and name. It complicates things... """ diff --git a/itopapi/model/physicalInterface.py b/itopapi/model/physicalInterface.py index 09ba42c..dbb93a6 100644 --- a/itopapi/model/physicalInterface.py +++ b/itopapi/model/physicalInterface.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiPhysicalInterface is a abstraction of PhysicalInterface representation on iTop +ItopapiPhysicalInterface is an abstraction of PhysicalInterface representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py index 6e75e3a..e15170c 100644 --- a/itopapi/model/powerSource.py +++ b/itopapi/model/powerSource.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiPowerSource is a abstraction of PowerSource representation on iTop +ItopapiPowerSource is an abstraction of PowerSource representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index ca793df..a61cfe3 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes, invalid-name """ -ItopapiRack is a abstraction of Rack representation on iTop +ItopapiRack is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 20a1f32..5cf3612 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements """ -ItopapiServers is a abstraction of Rack representation on iTop +ItopapiServers is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 01ce3fd..9129d5a 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiService is a abstraction of Service representation on iTop +ItopapiService is an abstraction of Service representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/subnet.py b/itopapi/model/subnet.py index 4f9a967..c04d3ee 100644 --- a/itopapi/model/subnet.py +++ b/itopapi/model/subnet.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiSubnet is a abstraction of Subnet representation on iTop +ItopapiSubnet is an abstraction of Subnet representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/team.py b/itopapi/model/team.py index f823792..3ea5de8 100644 --- a/itopapi/model/team.py +++ b/itopapi/model/team.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes, invalid-name """ -ItopapiTeam is a abstraction of Team representation on iTop +ItopapiTeam is an abstraction of Team representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 258e531..8bae311 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiVirtualMachine is a abstraction of VLAN representation on iTop +ItopapiVirtualMachine is an abstraction of VLAN representation on iTop """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod diff --git a/itopapi/model/vlan.py b/itopapi/model/vlan.py index 0d25a43..48c3bd8 100644 --- a/itopapi/model/vlan.py +++ b/itopapi/model/vlan.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiVLAN is a abstraction of VLAN representation on iTop +ItopapiVLAN is an abstraction of VLAN representation on iTop Note : VLAN has no finalclass and name. It complicates things... """ diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index e2938d2..769b5fa 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements """ -ItopapiWebApplication is a abstraction of Rack representation on iTop +ItopapiWebApplication is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 38be7c1..4c4011e 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements """ -ItopapiWebServer is a abstraction of Rack representation on iTop +ItopapiWebServer is an abstraction of Rack representation on iTop """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod From 8e13cc8c7866e9188baf2228dde27792c510b76f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 15:52:56 +0100 Subject: [PATCH 071/104] removed unused ItopapiUnimplementedMethod --- itopapi/model/server.py | 2 +- itopapi/model/virtualMachine.py | 2 +- itopapi/model/webApplication.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 5cf3612..0c6ff2d 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -4,7 +4,7 @@ ItopapiServers is an abstraction of Rack representation on iTop """ -from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 8bae311..906c838 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -4,7 +4,7 @@ ItopapiVirtualMachine is an abstraction of VLAN representation on iTop """ -from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 769b5fa..9581970 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -4,7 +4,7 @@ ItopapiWebApplication is an abstraction of Rack representation on iTop """ -from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' From f63a57b2f60018cf2e1acd0ff4a2f2d205c79d24 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 15:56:26 +0100 Subject: [PATCH 072/104] Removed unused load_from_json_quattor --- itopapi/model/server.py | 7 ------- itopapi/model/virtualMachine.py | 7 ------- itopapi/model/webApplication.py | 7 ------- itopapi/model/webServer.py | 7 ------- 4 files changed, 28 deletions(-) diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 0c6ff2d..9dd21a3 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -219,13 +219,6 @@ def __init__(self, data=None): # Server's services list self.services_list = {} - def load_from_json_quattor(self, json_quattor): - """ - Create a ItopapiServer description based on quattor s JSON output - :param json_quattor: json - """ - pass - def find_rack(self): """ Retrieve the ItopapiRack corresponding to this server diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 906c838..aaf0280 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -152,13 +152,6 @@ def __init__(self, data=None): # VirtualMachine's services list self.services_list = {} - def load_from_json_quattor(self, json_quattor): - """ - Create a ItopapiVirtualMachine description based on quattor s JSON output - :param json_quattor: json - """ - pass - def find_os_family(self): """ Retrieve the ItopapiOSFamily corresponding to this VirtualMachine diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 9581970..2b2fce6 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -102,13 +102,6 @@ def __init__(self, data=None): # WebApplication's services list self.services_list = {} - def load_from_json_quattor(self, json_quattor): - """ - Create a ItopapiWebApplication description based on quattor s JSON output - :param json_quattor: json - """ - pass - def find_web_server(self): """ Retrieve the ItopapiWebServer corresponding to this WebApplication diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 4c4011e..c14e044 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -149,13 +149,6 @@ def __init__(self, data=None): # WebServer's services list self.services_list = {} - def load_from_json_quattor(self, json_quattor): - """ - Create a ItopapiWebServer description based on quattor s JSON output - :param json_quattor: json - """ - pass - def find_system(self): """ Retrieve the System (Server or VirtualMachine) corresponding to this WebServer From e2cda786c5092eac5787841f585a1e2c391d133f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 15:58:36 +0100 Subject: [PATCH 073/104] Added blank space --- itopapi/model/features/hasOrganization.py | 1 + itopapi/model/features/hasOrganization2.py | 1 + 2 files changed, 2 insertions(+) diff --git a/itopapi/model/features/hasOrganization.py b/itopapi/model/features/hasOrganization.py index c79fce6..7bd3764 100644 --- a/itopapi/model/features/hasOrganization.py +++ b/itopapi/model/features/hasOrganization.py @@ -20,6 +20,7 @@ class HasOrganization(object): def __init__(self): super(HasOrganization, self).__init__() + # Object's organization id. Call find_organization to get the full information or just use # org_id_friendlyname and organization_name self.org_id = None diff --git a/itopapi/model/features/hasOrganization2.py b/itopapi/model/features/hasOrganization2.py index 9bc15bf..bb7ee65 100644 --- a/itopapi/model/features/hasOrganization2.py +++ b/itopapi/model/features/hasOrganization2.py @@ -21,6 +21,7 @@ class HasOrganization2(object): def __init__(self): super(HasOrganization2, self).__init__() + # Object's organization id. Call find_organization to get the full information or just use # org_id_friendlyname and organization_name self.org_id = None From 68855b68f896595296f48d053cef0123480eafee Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 16:09:09 +0100 Subject: [PATCH 074/104] added the HasLocation mixin and updated data model --- itopapi/model/enclosure.py | 22 +++---------- itopapi/model/features/hasLocation.py | 46 +++++++++++++++++++++++++++ itopapi/model/person.py | 20 ++---------- itopapi/model/powerSource.py | 20 ++---------- itopapi/model/rack.py | 20 ++---------- itopapi/model/server.py | 20 ++---------- 6 files changed, 63 insertions(+), 85 deletions(-) create mode 100644 itopapi/model/features/hasLocation.py diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 9a8a2d3..046380b 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiEnclosure(ItopapiPrototype, HasOrganization): +class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation): # Configuration specific to itop itop = { @@ -22,12 +23,13 @@ class ItopapiEnclosure(ItopapiPrototype, HasOrganization): 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, + HasLocation.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, ], } + @staticmethod def find(key): """ Retrieve one or more instance of Enclosure with the given key or criteria """ @@ -43,6 +45,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiEnclosure) """ + ItopapiEnclosure is an object that represents an Enclosure from iTop """ def __init__(self, data=None): super(ItopapiEnclosure, self).__init__(data) @@ -50,13 +53,6 @@ def __init__(self, data=None): self.status = None # Enclosure's business criticity. Values within [high, medium, low] self.business_criticity = None - # Enclosure's location id. Call find_location to get the full information or just use - # location_id_friendlyname and location_name - self.location_id = None - # Enclosure's location id's friendly name. Not sure the difference with location_name - self.location_id_friendlyname = None - # Enclosure's location name - self.location_name = None # Enclosure's rack id. Call findRack to get the full information or just use rack_id # friendlyname and rack_name self.rack_id = None @@ -84,14 +80,6 @@ def __init__(self, data=None): self.end_of_warranty = None self.description = None - def find_location(self): - """ - Retrieve the ItopapiLocation related to this instance - """ - if self.location_id is not None: - return ItopapiPrototype.get_itop_class('Location').find(self.location_id) - return None - def find_rack(self): """ Retrieve the ItopapiRack corresponding to this server diff --git a/itopapi/model/features/hasLocation.py b/itopapi/model/features/hasLocation.py new file mode 100644 index 0000000..8d1b11b --- /dev/null +++ b/itopapi/model/features/hasLocation.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasLocation is a mixin representing the location attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasLocation(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'location_id', 'name': 'location_name', 'table': 'Location'} + + def __init__(self): + super(HasLocation, self).__init__() + + # Object's location id. Call find_location to get the full information or just use + # location_id_friendlyname and location_name + self.location_id = None + # Object's location id's friendly name. Not sure the difference with location_name + self.location_id_friendlyname = None + # Object's location name + self.location_name = None + + def find_location(self): + """ + Retrieve the ItopapiLocation related to this instance + """ + if self.location_id is not None: + return ItopapiPrototype.get_itop_class('Location').find(self.location_id) + return None + + def set_location(self, location): + """ + Set the ItopapiOrganization parameters + """ + self.location_id = location.instance_id + self.location_id_friendlyname = location.friendlyname + self.location_name = location.name diff --git a/itopapi/model/person.py b/itopapi/model/person.py index 3e94e15..c201f34 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPerson(ItopapiPrototype, HasOrganization): +class ItopapiPerson(ItopapiPrototype, HasOrganization, HasLocation): # Configuration specific to itop itop = { @@ -23,7 +24,7 @@ class ItopapiPerson(ItopapiPrototype, HasOrganization): 'email', 'mobile_phone', 'phone', 'notify', 'employee_number', 'status'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, + HasLocation.foreign_key, {'id': 'manager_id', 'name': 'manager_name', 'table': 'Person'}, ], 'list_types': { @@ -56,13 +57,6 @@ def __init__(self, data=None): ################################## self.contact_id = None self.contact_name = None - # Person's location id. Call find_location to get the full information or just use - # location_id_friendlyname and location_name - self.location_id = None - # Person's location id's friendly name. Not sure the difference with location_name - self.location_id_friendlyname = None - # Person's location name - self.location_name = None self.manager_id = None, self.manager_id_friendlyname = None, self.manager_name = None, @@ -82,11 +76,3 @@ def __init__(self, data=None): self.tickets_list = None self.tickets_list = None self.tickets_list = None - - def find_location(self): - """ - Retrieve the ItopapiLocation related to this instance - """ - if self.location_id is not None: - return ItopapiPrototype.get_itop_class('Location').find(self.location_id) - return None diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py index e15170c..3e5cd99 100644 --- a/itopapi/model/powerSource.py +++ b/itopapi/model/powerSource.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPowerSource(ItopapiPrototype, HasOrganization): +class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation): # Configuration specific to itop itop = { @@ -22,7 +23,7 @@ class ItopapiPowerSource(ItopapiPrototype, HasOrganization): 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, + HasLocation.foreign_key, {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, ] @@ -52,13 +53,6 @@ def __init__(self, data=None): self.status = None # PowerSource's business criticity. Values within [high, medium, low] self.business_criticity = None - # PowerSource's location id. Call find_location to get the full information or just use - # location_id_friendlyname and location_name - self.location_id = None - # PowerSource's location id's friendly name. Not sure the difference with location_name - self.location_id_friendlyname = None - # PowerSource's location name - self.location_name = None self.brand_id = None self.brand_id_friendlyname = None self.brand_name = None @@ -88,14 +82,6 @@ def __init__(self, data=None): self.providercontracts_list = {} self.pdus_list = {} - def find_location(self): - """ - Retrieve the ItopapiLocation related to this instance - """ - if self.location_id is not None: - return ItopapiPrototype.get_itop_class('Location').find(self.location_id) - return None - def find_brand(self): """ Retrieve the ItopapiBrand corresponding to this instance diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index a61cfe3..a2e0ff8 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation __version__ = '1.0' __authors__ = ['Guillaume Philippon ', 'Julien Nauroy '] -class ItopapiRack(ItopapiPrototype, HasOrganization): +class ItopapiRack(ItopapiPrototype, HasOrganization, HasLocation): """ ItopapiRack is an object that represents a Rack from iTop """ @@ -25,7 +26,7 @@ class ItopapiRack(ItopapiPrototype, HasOrganization): 'serialnumber', 'asset_number', 'move2production', 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, + HasLocation.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -56,13 +57,6 @@ def __init__(self, data=None): self.status = None # Rack's business criticity. Values within [high, medium, low] self.business_criticity = None - # Rack's location id. Call find_location to get the full information or just use location_id - # _friendlyname and location_name - self.location_id = None - # Rack's location id's friendly name. Not sure the difference with location_name - self.location_id_friendlyname = None - # Rack's location name - self.location_name = None # Rack's height in "rack units" self.nb_u = None # Rack's serial number @@ -124,11 +118,3 @@ def __init__(self, data=None): self.applicationsolution_list = None self.softwares_list = None self.logicalvolumes_list = None - - def find_location(self): - """ - Retrieve the ItopapiLocation related to this instance - """ - if self.location_id is not None: - return ItopapiPrototype.get_itop_class('Location').find(self.location_id) - return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 9dd21a3..c582585 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization): +class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -26,7 +27,7 @@ class ItopapiServer(ItopapiPrototype, HasOrganization): 'purchase_date', 'end_of_warranty', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'location_id', 'name': 'location_name', 'table': 'Location'}, + HasLocation.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, @@ -67,13 +68,6 @@ def __init__(self, data=None): self.status = None # Server's business criticity. Values within [high, medium, low] self.business_criticity = None - # Server's location id. Call find_location to get the full information or just use - # location_id_friendlyname and location_name - self.location_id = None - # Server's location id's friendly name. Not sure the difference with location_name - self.location_id_friendlyname = None - # Server's location name - self.location_name = None # Server's rack id. Call findRack to get the full information or just use rack_id # friendlyname and rack_name self.rack_id = None @@ -227,14 +221,6 @@ def find_rack(self): return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None - def find_location(self): - """ - Retrieve the ItopapiLocation related to this instance - """ - if self.location_id is not None: - return ItopapiPrototype.get_itop_class('Location').find(self.location_id) - return None - def find_enclosure(self): """ Retrieve the ItopapiEnclosure corresponding to this server From 2542f8458f9f9fc1e41c9fb3d1bab258293dd25f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 16:19:59 +0100 Subject: [PATCH 075/104] added HasBrand mixin and updated data model --- itopapi/model/enclosure.py | 16 ++--------- itopapi/model/features/__init__.py | 2 ++ itopapi/model/features/hasBrand.py | 46 ++++++++++++++++++++++++++++++ itopapi/model/model.py | 20 ++++--------- itopapi/model/powerSource.py | 16 ++--------- itopapi/model/server.py | 16 ++--------- 6 files changed, 62 insertions(+), 54 deletions(-) create mode 100644 itopapi/model/features/hasBrand.py diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 046380b..c01ebca 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation): +class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation, HasBrand): # Configuration specific to itop itop = { @@ -24,8 +25,8 @@ class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation): 'foreign_keys': [ HasOrganization.foreign_key, HasLocation.foreign_key, + HasBrand.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, - {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, ], } @@ -60,9 +61,6 @@ def __init__(self, data=None): self.rack_id_friendlyname = None # Enclosure's rack name self.rack_name = None - self.brand_id = None - self.brand_id_friendlyname = None - self.brand_name = None self.model_id = None self.model_id_friendlyname = None self.model_name = None @@ -88,14 +86,6 @@ def find_rack(self): return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None - def find_brand(self): - """ - Retrieve the ItopapiBrand corresponding to this instance - """ - if self.brand_id is not None: - return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) - return None - def find_model(self): """ Retrieve the ItopapiModel corresponding to this instance diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 8161dc6..b424c8c 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -9,3 +9,5 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasOrganization2 import HasOrganization2 +from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand diff --git a/itopapi/model/features/hasBrand.py b/itopapi/model/features/hasBrand.py new file mode 100644 index 0000000..eb7f098 --- /dev/null +++ b/itopapi/model/features/hasBrand.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasBrand is a mixin representing the brand attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasBrand(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'location_id', 'name': 'location_name', 'table': 'Location'} + + def __init__(self): + super(HasBrand, self).__init__() + + # Object's brand id. Call find_brand to get the full information or just use + # brand_id_friendlyname and brand_name + self.brand_id = None + # Object's brand id's friendly name. Not sure the difference with brand_name + self.brand_id_friendlyname = None + # Object's brand name + self.brand_name = None + + def find_brand(self): + """ + Retrieve the ItopapiBrand related to this instance + """ + if self.brand_id is not None: + return ItopapiPrototype.get_itop_class('Brand').find(self.location_id) + return None + + def set_brand(self, brand): + """ + Set the ItopapiOrganization parameters + """ + self.brand_id = brand.instance_id + self.brand_id_friendlyname = brand.friendlyname + self.brand_name = brand.name diff --git a/itopapi/model/model.py b/itopapi/model/model.py index 3b6cf04..2c14c5b 100644 --- a/itopapi/model/model.py +++ b/itopapi/model/model.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasBrand import HasBrand __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiModel(ItopapiPrototype): +class ItopapiModel(ItopapiPrototype, HasBrand): # Configuration specific to itop itop = { @@ -19,7 +20,7 @@ class ItopapiModel(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'type'], 'foreign_keys': [ - {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, + HasBrand.foreign_key, ] } @@ -44,18 +45,7 @@ def __init__(self, data=None): super(ItopapiModel, self).__init__(data) # Physical devices using this brand self.physicaldevices_list = None - self.brand_id = None - self.brand_id_friendlyname = None - self.brand_name = None - # Type of item the Brand refers to. Values are within + # Type of item the Model refers to. Values are within # [DiskArray, Enclosure, IPPhone, MobilePhone, NAS, NetworkDevice, PC, PDU, Peripheral, Phone, # PowerSource, Printer, Rack, SANSwitch, Server, StorageSystem, Tablet, TapeLibrary] - self.type = None - - def find_brand(self): - """ - Retrieve the ItopapiBrand corresponding to this server - """ - if self.brand_id is not None: - return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) - return None \ No newline at end of file + self.type = None \ No newline at end of file diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py index 3e5cd99..048bdb3 100644 --- a/itopapi/model/powerSource.py +++ b/itopapi/model/powerSource.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation): +class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation, HasBrand): # Configuration specific to itop itop = { @@ -24,7 +25,7 @@ class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation): 'foreign_keys': [ HasOrganization.foreign_key, HasLocation.foreign_key, - {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, + HasBrand.foreign_key, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, ] } @@ -53,9 +54,6 @@ def __init__(self, data=None): self.status = None # PowerSource's business criticity. Values within [high, medium, low] self.business_criticity = None - self.brand_id = None - self.brand_id_friendlyname = None - self.brand_name = None self.model_id = None self.model_id_friendlyname = None self.model_name = None @@ -82,14 +80,6 @@ def __init__(self, data=None): self.providercontracts_list = {} self.pdus_list = {} - def find_brand(self): - """ - Retrieve the ItopapiBrand corresponding to this instance - """ - if self.brand_id is not None: - return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) - return None - def find_model(self): """ Retrieve the ItopapiModel corresponding to this instance diff --git a/itopapi/model/server.py b/itopapi/model/server.py index c582585..0a83fe0 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation): +class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -28,9 +29,9 @@ class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation): 'foreign_keys': [ HasOrganization.foreign_key, HasLocation.foreign_key, + HasBrand.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, - {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'}, {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, @@ -86,9 +87,6 @@ def __init__(self, data=None): ################################## # Properties/More Information # ################################## - self.brand_id = None - self.brand_id_friendlyname = None - self.brand_name = None self.model_id = None self.model_id_friendlyname = None @@ -229,14 +227,6 @@ def find_enclosure(self): return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None - def find_brand(self): - """ - Retrieve the ItopapiBrand corresponding to this server - """ - if self.brand_id is not None: - return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) - return None - def find_model(self): """ Retrieve the ItopapiModel corresponding to this server From f7ffdd156badf1692fb53950d12586b0f114998d Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 16:21:26 +0100 Subject: [PATCH 076/104] error in copy/paste --- itopapi/model/features/hasBrand.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/itopapi/model/features/hasBrand.py b/itopapi/model/features/hasBrand.py index eb7f098..48a60d9 100644 --- a/itopapi/model/features/hasBrand.py +++ b/itopapi/model/features/hasBrand.py @@ -16,7 +16,7 @@ class HasBrand(object): """ """ Configuration specific to itop """ - foreign_key = {'id': 'location_id', 'name': 'location_name', 'table': 'Location'} + foreign_key = {'id': 'brand_id', 'name': 'brand_name', 'table': 'Brand'} def __init__(self): super(HasBrand, self).__init__() @@ -34,7 +34,7 @@ def find_brand(self): Retrieve the ItopapiBrand related to this instance """ if self.brand_id is not None: - return ItopapiPrototype.get_itop_class('Brand').find(self.location_id) + return ItopapiPrototype.get_itop_class('Brand').find(self.brand_id) return None def set_brand(self, brand): From 51d0181124a012de55fad6dbeab44d6b82e29db1 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 16:30:34 +0100 Subject: [PATCH 077/104] Added HasModel mixin and updated data model. --- itopapi/model/enclosure.py | 16 ++--------- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasModel.py | 46 ++++++++++++++++++++++++++++++ itopapi/model/powerSource.py | 16 ++--------- itopapi/model/server.py | 13 ++------- vcenter2itop.py | 12 ++------ 6 files changed, 59 insertions(+), 45 deletions(-) create mode 100644 itopapi/model/features/hasModel.py diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index c01ebca..758d63c 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -8,12 +8,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation, HasBrand): +class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel): # Configuration specific to itop itop = { @@ -26,8 +27,8 @@ class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation, HasBrand) HasOrganization.foreign_key, HasLocation.foreign_key, HasBrand.foreign_key, + HasModel.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, - {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, ], } @@ -61,9 +62,6 @@ def __init__(self, data=None): self.rack_id_friendlyname = None # Enclosure's rack name self.rack_name = None - self.model_id = None - self.model_id_friendlyname = None - self.model_name = None # Rack units self.nb_u = None # Serial number @@ -85,11 +83,3 @@ def find_rack(self): if self.rack_id is not None: return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) return None - - def find_model(self): - """ - Retrieve the ItopapiModel corresponding to this instance - """ - if self.model_id is not None: - return ItopapiPrototype.get_itop_class('Model').find(self.model_id) - return None diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index b424c8c..58bc8b6 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -11,3 +11,4 @@ from itopapi.model.features.hasOrganization2 import HasOrganization2 from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel diff --git a/itopapi/model/features/hasModel.py b/itopapi/model/features/hasModel.py new file mode 100644 index 0000000..117b93f --- /dev/null +++ b/itopapi/model/features/hasModel.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasModel is a mixin representing the model attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasModel(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'model_id', 'name': 'model_name', 'table': 'Model'} + + def __init__(self): + super(HasModel, self).__init__() + + # Object's model id. Call find_model to get the full information or just use + # model_id_friendlyname and model_name + self.model_id = None + # Object's model id's friendly name. Not sure the difference with model_name + self.model_id_friendlyname = None + # Object's model name + self.model_name = None + + def find_model(self): + """ + Retrieve the ItopapiModel related to this instance + """ + if self.model_id is not None: + return ItopapiPrototype.get_itop_class('Model').find(self.location_id) + return None + + def set_model(self, model): + """ + Set the ItopapiOrganization parameters + """ + self.model_id = model.instance_id + self.model_id_friendlyname = model.friendlyname + self.model_name = model.name diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py index 048bdb3..38fed44 100644 --- a/itopapi/model/powerSource.py +++ b/itopapi/model/powerSource.py @@ -8,12 +8,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation, HasBrand): +class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel): # Configuration specific to itop itop = { @@ -26,7 +27,7 @@ class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation, HasBran HasOrganization.foreign_key, HasLocation.foreign_key, HasBrand.foreign_key, - {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, + HasModel.foreign_key, ] } @@ -54,9 +55,6 @@ def __init__(self, data=None): self.status = None # PowerSource's business criticity. Values within [high, medium, low] self.business_criticity = None - self.model_id = None - self.model_id_friendlyname = None - self.model_name = None # Serial number self.serialnumber = None # Asset number @@ -79,11 +77,3 @@ def __init__(self, data=None): self.tickets_list = {} self.providercontracts_list = {} self.pdus_list = {} - - def find_model(self): - """ - Retrieve the ItopapiModel corresponding to this instance - """ - if self.model_id is not None: - return ItopapiPrototype.get_itop_class('Model').find(self.model_id) - return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 0a83fe0..b687ba6 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -8,12 +8,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand): +class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -30,9 +31,9 @@ class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand): HasOrganization.foreign_key, HasLocation.foreign_key, HasBrand.foreign_key, + HasModel.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, - {'id': 'model_id', 'name': 'model_name', 'table': 'Model'}, {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, @@ -227,14 +228,6 @@ def find_enclosure(self): return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None - def find_model(self): - """ - Retrieve the ItopapiModel corresponding to this server - """ - if self.model_id is not None: - return ItopapiPrototype.get_itop_class('Model').find(self.model_id) - return None - def find_os_family(self): """ Retrieve the ItopapiOSFamily corresponding to this server diff --git a/vcenter2itop.py b/vcenter2itop.py index 1c47e2b..19b1440 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -125,9 +125,7 @@ def get_model(brand, model_name, model_type): itop_model = ItopapiModel() itop_model.name = model_name itop_model.type = model_type - itop_model.brand_id = brand.instance_id - itop_model.brand_id_friendlyname = brand.friendlyname - itop_model.brand_name = brand.name + itop_model.set_brand(brand) itop_model.save() itop_models[(brand.instance_id, model_name)] = itop_model return itop_model @@ -220,16 +218,12 @@ def get_server_params(itop_server, vcenter_host, organization): itop_brand = get_brand(summary.hardware.vendor) if itop_server.brand_id != itop_brand.instance_id: has_changed = True - itop_server.brand_id = itop_brand.instance_id - itop_server.brand_id_friendlyname = itop_brand.friendlyname - itop_server.brand_name = itop_brand.name + itop_server.set_brand(itop_brand) # Set the model itop_model = get_model(itop_brand, summary.hardware.model, "Server") if itop_server.model_id != itop_model.instance_id: has_changed = True - itop_server.model_id = itop_model.instance_id - itop_server.model_id_friendlyname = itop_model.friendlyname - itop_server.model_name = itop_model.name + itop_server.set_model(itop_model) # Set other fields cpu_count = int(hardware.cpuInfo.numCpuCores * hardware.cpuInfo.numCpuPackages) if itop_server.name != vcenter_host.name \ From 774dae58d89a65dac4accd9e89b02bd44a90f152 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 16:39:34 +0100 Subject: [PATCH 078/104] Added HasOSFamily mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasOSFamily.py | 46 +++++++++++++++++++++++++++ itopapi/model/osVersion.py | 20 +++--------- itopapi/model/server.py | 21 ++---------- itopapi/model/virtualMachine.py | 17 ++-------- vcenter2itop.py | 12 ++----- 6 files changed, 61 insertions(+), 56 deletions(-) create mode 100644 itopapi/model/features/hasOSFamily.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 58bc8b6..8c9cfc3 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -12,3 +12,4 @@ from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasOSFamily import HasOSFamily diff --git a/itopapi/model/features/hasOSFamily.py b/itopapi/model/features/hasOSFamily.py new file mode 100644 index 0000000..8e420ff --- /dev/null +++ b/itopapi/model/features/hasOSFamily.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasOSFamily is a mixin representing the osfamily attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasOSFamily(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'} + + def __init__(self): + super(HasOSFamily, self).__init__() + + # Object's osfamily id. Call find_osfamily to get the full information or just use + # osfamily_id_friendlyname and osfamily_name + self.osfamily_id = None + # Object's osfamily id's friendly name. Not sure the difference with osfamily_name + self.osfamily_id_friendlyname = None + # Object's osfamily name + self.osfamily_name = None + + def find_osfamily(self): + """ + Retrieve the ItopapiOSFamily related to this instance + """ + if self.osfamily_id is not None: + return ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) + return None + + def set_osfamily(self, osfamily): + """ + Set the ItopapiOrganization parameters + """ + self.osfamily_id = osfamily.instance_id + self.osfamily_id_friendlyname = osfamily.friendlyname + self.osfamily_name = osfamily.name diff --git a/itopapi/model/osVersion.py b/itopapi/model/osVersion.py index 839181e..2c8f6a6 100644 --- a/itopapi/model/osVersion.py +++ b/itopapi/model/osVersion.py @@ -1,16 +1,17 @@ # -*- coding: utf8 -*-fr """ -ItopapiOSVersion is an abstraction of Rack representation on iTop +ItopapiOSVersion is an abstraction of an OSVersion representation on iTop """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOSFamily import HasOSFamily __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOSVersion(ItopapiPrototype): +class ItopapiOSVersion(ItopapiPrototype, HasOSFamily): # Configuration specific to itop itop = { @@ -19,7 +20,7 @@ class ItopapiOSVersion(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name'], 'foreign_keys': [ - {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, + HasOSFamily.foreign_key, ] } @@ -42,15 +43,4 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiOSVersion, self).__init__(data) - # OSFamily this OSVersion is attached to - self.osfamily_id = None - self.osfamily_id_friendlyname = None - self.osfamily_name = None - - def find_os_family(self): - """ - Retrieve the ItopapiOSFamily corresponding to this server - """ - if self.osfamily_id is not None: - return ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) - return None + diff --git a/itopapi/model/server.py b/itopapi/model/server.py index b687ba6..02bb2de 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -9,12 +9,13 @@ from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasOSFamily import HasOSFamily __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel): +class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, HasOSFamily): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -32,9 +33,9 @@ class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, Ha HasLocation.foreign_key, HasBrand.foreign_key, HasModel.foreign_key, + HasOSFamily.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, - {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, @@ -89,14 +90,6 @@ def __init__(self, data=None): # Properties/More Information # ################################## - self.model_id = None - self.model_id_friendlyname = None - self.model_name = None - - self.osfamily_id = None - self.osfamily_id_friendlyname = None - self.osfamily_name = None - self.osversion_id = None self.osversion_id_friendlyname = None self.osversion_name = None @@ -228,14 +221,6 @@ def find_enclosure(self): return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None - def find_os_family(self): - """ - Retrieve the ItopapiOSFamily corresponding to this server - """ - if self.osfamily_id is not None: - return ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) - return None - def find_os_version(self): """ Retrieve the ItopapiOSVersion corresponding to this server diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index aaf0280..d4280ba 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasOSFamily import HasOSFamily __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization): +class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily): # Configuration specific to itop itop = { @@ -22,8 +23,8 @@ class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization): 'description'], 'foreign_keys': [ HasOrganization.foreign_key, + HasOSFamily.foreign_key, {'id': 'virtualhost_id', 'name': 'virtualhost_name', 'table': 'VirtualHost'}, - {'id': 'osfamily_id', 'name': 'osfamily_name', 'table': 'OSFamily'}, {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, ], @@ -69,10 +70,6 @@ def __init__(self, data=None): # Properties/More Information # ################################## - self.osfamily_id = None - self.osfamily_id_friendlyname = None - self.osfamily_name = None - self.osversion_id = None self.osversion_id_friendlyname = None self.osversion_name = None @@ -152,14 +149,6 @@ def __init__(self, data=None): # VirtualMachine's services list self.services_list = {} - def find_os_family(self): - """ - Retrieve the ItopapiOSFamily corresponding to this VirtualMachine - """ - if self.osfamily_id is not None: - return ItopapiPrototype.get_itop_class('OSFamily').find(self.osfamily_id) - return None - def find_os_version(self): """ Retrieve the ItopapiOSVersion corresponding to this server diff --git a/vcenter2itop.py b/vcenter2itop.py index 19b1440..bec2f32 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -89,9 +89,7 @@ def get_os_version(os_family, os_version_name): if os_version is None: os_version = ItopapiOSVersion() os_version.name = os_version_name - os_version.osfamily_id = os_family.instance_id - os_version.osfamily_name = os_family.name - os_version.osfamily_id_friendlyname = os_family.friendlyname + os_version.set_osfamily(os_family) ret = os_version.save() itop_os_versions[(os_family.instance_id, os_version.name)] = os_version # print "Added new OS version %s" % os_version_name @@ -204,9 +202,7 @@ def get_server_params(itop_server, vcenter_host, organization): os_family = get_os_family(product.name) if itop_server.osfamily_id != os_family.instance_id: has_changed = True - itop_server.osfamily_id = os_family.instance_id - itop_server.osfamily_id_friendlyname = os_family.friendlyname - itop_server.osfamily_name = os_family.name + itop_server.set_osfamily(os_family) # Set the OS version os_version = get_os_version(os_family, product.fullName) if itop_server.osversion_id != os_version.instance_id: @@ -282,9 +278,7 @@ def get_vm_params(itop_vm, vcenter_vm, organization): # Set the organization itop_vm.set_organization(organization) # Set the OS family - itop_vm.osfamily_id = os_family.instance_id - itop_vm.osfamily_id_friendlyname = os_family.friendlyname - itop_vm.osfamily_name = os_family.name + itop_vm.set_osfamily(os_family) # Set the OS version itop_vm.osversion_id = os_version.instance_id itop_vm.osversion_id_friendlyname = os_version.friendlyname From 11cfdf2a696d90ae655aa8c3bc6d869d806597d1 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 21:53:47 +0100 Subject: [PATCH 079/104] Added HasOSVersion mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasOSVersion.py | 46 ++++++++++++++++++++++++++ itopapi/model/osLicence.py | 16 ++------- itopapi/model/server.py | 17 ++-------- itopapi/model/virtualMachine.py | 17 ++-------- vcenter2itop.py | 8 ++--- 6 files changed, 58 insertions(+), 47 deletions(-) create mode 100644 itopapi/model/features/hasOSVersion.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 8c9cfc3..dfc0631 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -13,3 +13,4 @@ from itopapi.model.features.hasBrand import HasBrand from itopapi.model.features.hasModel import HasModel from itopapi.model.features.hasOSFamily import HasOSFamily +from itopapi.model.features.hasOSVersion import HasOSVersion diff --git a/itopapi/model/features/hasOSVersion.py b/itopapi/model/features/hasOSVersion.py new file mode 100644 index 0000000..4a2a642 --- /dev/null +++ b/itopapi/model/features/hasOSVersion.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasOSVersion is a mixin representing the osversion attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasOSVersion(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'} + + def __init__(self): + super(HasOSVersion, self).__init__() + + # Object's osversion id. Call find_osversion to get the full information or just use + # osversion_id_friendlyname and osversion_name + self.osversion_id = None + # Object's osversion id's friendly name. Not sure the difference with osversion_name + self.osversion_id_friendlyname = None + # Object's osversion name + self.osversion_name = None + + def find_osversion(self): + """ + Retrieve the ItopapiOSVersion related to this instance + """ + if self.osversion_id is not None: + return ItopapiPrototype.get_itop_class('OSVersion').find(self.osversion_id) + return None + + def set_osversion(self, osversion): + """ + Set the ItopapiOrganization parameters + """ + self.osversion_id = osversion.instance_id + self.osversion_id_friendlyname = osversion.friendlyname + self.osversion_name = osversion.name diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py index daebe32..f8aa7f7 100644 --- a/itopapi/model/osLicence.py +++ b/itopapi/model/osLicence.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasOSVersion import HasOSVersion __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOSLicence(ItopapiPrototype, HasOrganization): +class ItopapiOSLicence(ItopapiPrototype, HasOrganization, HasOSVersion): # Configuration specific to itop itop = { @@ -21,7 +22,7 @@ class ItopapiOSLicence(ItopapiPrototype, HasOrganization): 'save': ['name', 'usage_limit', 'description', 'perpetual', 'start_date', 'end_date', 'licence_key'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, + HasOSVersion.foreign_key, ], } @@ -44,9 +45,6 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiOSLicence, self).__init__(data) - self.osversion_id = None - self.osversion_id_friendlyname = None - self.osversion_name = None # Number of concurrent users or licences self.usage_limit = None self.description = None @@ -59,11 +57,3 @@ def __init__(self, data=None): self.documents_list = [] self.servers_list = [] self.virtualmachines_list = [] - - def find_os_version(self): - """ - Retrieve the ItopapiOSVersion corresponding to this server - """ - if self.osversion_id is not None: - return ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) - return None diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 02bb2de..7c87f2d 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -10,12 +10,13 @@ from itopapi.model.features.hasBrand import HasBrand from itopapi.model.features.hasModel import HasModel from itopapi.model.features.hasOSFamily import HasOSFamily +from itopapi.model.features.hasOSVersion import HasOSVersion __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, HasOSFamily): +class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, HasOSFamily, HasOSVersion): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -34,9 +35,9 @@ class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, Ha HasBrand.foreign_key, HasModel.foreign_key, HasOSFamily.foreign_key, + HasOSVersion.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, - {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, @@ -90,10 +91,6 @@ def __init__(self, data=None): # Properties/More Information # ################################## - self.osversion_id = None - self.osversion_id_friendlyname = None - self.osversion_name = None - self.managementip = None self.oslicence_id = None @@ -221,14 +218,6 @@ def find_enclosure(self): return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None - def find_os_version(self): - """ - Retrieve the ItopapiOSVersion corresponding to this server - """ - if self.osversion_id is not None: - return ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) - return None - def find_os_licence(self): """ Retrieve the ItopapiOSLicence corresponding to this server diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index d4280ba..0c5ba8e 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasOSFamily import HasOSFamily +from itopapi.model.features.hasOSVersion import HasOSVersion __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily): +class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasOSVersion): # Configuration specific to itop itop = { @@ -24,8 +25,8 @@ class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily): 'foreign_keys': [ HasOrganization.foreign_key, HasOSFamily.foreign_key, + HasOSVersion.foreign_key, {'id': 'virtualhost_id', 'name': 'virtualhost_name', 'table': 'VirtualHost'}, - {'id': 'osversion_id', 'name': 'osversion_name', 'table': 'OSVersion'}, {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, ], 'list_types': { @@ -70,10 +71,6 @@ def __init__(self, data=None): # Properties/More Information # ################################## - self.osversion_id = None - self.osversion_id_friendlyname = None - self.osversion_name = None - self.managementip = None self.oslicence_id = None @@ -149,14 +146,6 @@ def __init__(self, data=None): # VirtualMachine's services list self.services_list = {} - def find_os_version(self): - """ - Retrieve the ItopapiOSVersion corresponding to this server - """ - if self.osversion_id is not None: - return ItopapiPrototype.get_itop_class('OSVersion').find(self.osfamily_id) - return None - def find_os_licence(self): """ Retrieve the ItopapiOSLicence corresponding to this server diff --git a/vcenter2itop.py b/vcenter2itop.py index bec2f32..64abfc3 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -207,9 +207,7 @@ def get_server_params(itop_server, vcenter_host, organization): os_version = get_os_version(os_family, product.fullName) if itop_server.osversion_id != os_version.instance_id: has_changed = True - itop_server.osversion_id = os_version.instance_id - itop_server.osversion_id_friendlyname = os_version.friendlyname - itop_server.osversion_name = os_version.name + itop_server.set_osversion(os_version) # Set the brand itop_brand = get_brand(summary.hardware.vendor) if itop_server.brand_id != itop_brand.instance_id: @@ -280,9 +278,7 @@ def get_vm_params(itop_vm, vcenter_vm, organization): # Set the OS family itop_vm.set_osfamily(os_family) # Set the OS version - itop_vm.osversion_id = os_version.instance_id - itop_vm.osversion_id_friendlyname = os_version.friendlyname - itop_vm.osversion_name = os_version.name + itop_vm.set_osversion(os_version) # Set the virtual host (Hypervisor or Farm) itop_vm.virtualhost_id = virtualhost.instance_id itop_vm.virtualhost_id_friendlyname = virtualhost.friendlyname From f325945624312a3daa6e7feabb31c05448c1dbf7 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:00:00 +0100 Subject: [PATCH 080/104] Added HasOSLicence (sic) mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasOSLicence.py | 46 ++++++++++++++++++++++++++ itopapi/model/osLicence.py | 2 +- itopapi/model/server.py | 18 ++-------- itopapi/model/virtualMachine.py | 17 ++-------- 5 files changed, 54 insertions(+), 30 deletions(-) create mode 100644 itopapi/model/features/hasOSLicence.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index dfc0631..6468591 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -14,3 +14,4 @@ from itopapi.model.features.hasModel import HasModel from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion +from itopapi.model.features.hasOSLicence import HasOSLicence diff --git a/itopapi/model/features/hasOSLicence.py b/itopapi/model/features/hasOSLicence.py new file mode 100644 index 0000000..09ade7f --- /dev/null +++ b/itopapi/model/features/hasOSLicence.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasOSLicence is a mixin representing the oslicence attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasOSLicence(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'} + + def __init__(self): + super(HasOSLicence, self).__init__() + + # Object's oslicence id. Call find_oslicence to get the full information or just use + # oslicence_id_friendlyname and oslicence_name + self.oslicence_id = None + # Object's oslicence id's friendly name. Not sure the difference with oslicence_name + self.oslicence_id_friendlyname = None + # Object's oslicence name + self.oslicence_name = None + + def find_oslicence(self): + """ + Retrieve the ItopapiOSLicence related to this instance + """ + if self.oslicence_id is not None: + return ItopapiPrototype.get_itop_class('OSLicence').find(self.oslicence_id) + return None + + def set_oslicence(self, oslicence): + """ + Set the ItopapiOrganization parameters + """ + self.oslicence_id = oslicence.instance_id + self.oslicence_id_friendlyname = oslicence.friendlyname + self.oslicence_name = oslicence.name diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py index f8aa7f7..47bc053 100644 --- a/itopapi/model/osLicence.py +++ b/itopapi/model/osLicence.py @@ -41,7 +41,7 @@ def find_all(): return ItopapiPrototype.find_all(ItopapiOSLicence) """ - ItopapiOSLicence is an object that represents an OSLicence from iTop + ItopapiOSLicence is an object that represents an OSLicence (sic) from iTop """ def __init__(self, data=None): super(ItopapiOSLicence, self).__init__(data) diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 7c87f2d..bc11983 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -11,12 +11,13 @@ from itopapi.model.features.hasModel import HasModel from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion +from itopapi.model.features.hasOSLicence import HasOSLicence __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, HasOSFamily, HasOSVersion): +class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, HasOSFamily, HasOSVersion, HasOSLicence): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -36,9 +37,9 @@ class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, Ha HasModel.foreign_key, HasOSFamily.foreign_key, HasOSVersion.foreign_key, + HasOSLicence.foreign_key, {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, - {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, ], @@ -93,10 +94,6 @@ def __init__(self, data=None): self.managementip = None - self.oslicence_id = None - self.oslicence_id_friendlyname = None - self.oslicence_name = None - self.cpu = None self.ram = None # Rack units @@ -217,15 +214,6 @@ def find_enclosure(self): if self.enclosure_id is not None: return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None - - def find_os_licence(self): - """ - Retrieve the ItopapiOSLicence corresponding to this server - """ - if self.oslicence_id is not None: - return ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) - return None - def find_power_a(self): """ Retrieve the ItopapiPowerA corresponding to this server diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 0c5ba8e..3cca3c4 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -8,12 +8,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion +from itopapi.model.features.hasOSLicence import HasOSLicence __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasOSVersion): +class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasOSVersion, HasOSLicence): # Configuration specific to itop itop = { @@ -26,8 +27,8 @@ class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasO HasOrganization.foreign_key, HasOSFamily.foreign_key, HasOSVersion.foreign_key, + HasOSLicence.foreign_key, {'id': 'virtualhost_id', 'name': 'virtualhost_name', 'table': 'VirtualHost'}, - {'id': 'oslicence_id', 'name': 'oslicence_name', 'table': 'OSLicence'}, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -73,10 +74,6 @@ def __init__(self, data=None): self.managementip = None - self.oslicence_id = None - self.oslicence_id_friendlyname = None - self.oslicence_name = None - self.cpu = None self.ram = None @@ -145,11 +142,3 @@ def __init__(self, data=None): ################################## # VirtualMachine's services list self.services_list = {} - - def find_os_licence(self): - """ - Retrieve the ItopapiOSLicence corresponding to this server - """ - if self.oslicence_id is not None: - return ItopapiPrototype.get_itop_class('OSLicence').find(self.osfamily_id) - return None \ No newline at end of file From f77b74c97991206b47847e846c3339ff64e75a34 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:07:59 +0100 Subject: [PATCH 081/104] Added HasVirtualHost mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasVirtualhost.py | 46 +++++++++++++++++ itopapi/model/virtualMachine.py | 65 +++--------------------- vcenter2itop.py | 4 +- 4 files changed, 54 insertions(+), 62 deletions(-) create mode 100644 itopapi/model/features/hasVirtualhost.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 6468591..76092d9 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -15,3 +15,4 @@ from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion from itopapi.model.features.hasOSLicence import HasOSLicence +from itopapi.model.features.hasVirtualHost import HasVirtualhost diff --git a/itopapi/model/features/hasVirtualhost.py b/itopapi/model/features/hasVirtualhost.py new file mode 100644 index 0000000..cfe2856 --- /dev/null +++ b/itopapi/model/features/hasVirtualhost.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasVirtualHost is a mixin representing the virtualhost attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasVirtualHost(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'virtualhost_id', 'name': 'virtualhost_name', 'table': 'VirtualHost'} + + def __init__(self): + super(HasVirtualHost, self).__init__() + + # Object's virtualhost id. Call find_virtualhost to get the full information or just use + # virtualhost_id_friendlyname and virtualhost_name + self.virtualhost_id = None + # Object's virtualhost id's friendly name. Not sure the difference with virtualhost_name + self.virtualhost_id_friendlyname = None + # Object's virtualhost name + self.virtualhost_name = None + + def find_virtualhost(self): + """ + Retrieve the ItopapiVirtualHost related to this instance + """ + if self.virtualhost_id is not None: + return ItopapiPrototype.get_itop_class('VirtualHost').find(self.virtualhost_id) + return None + + def set_virtualhost(self, virtualhost): + """ + Set the ItopapiOrganization parameters + """ + self.virtualhost_id = virtualhost.instance_id + self.virtualhost_id_friendlyname = virtualhost.friendlyname + self.virtualhost_name = virtualhost.name diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index 3cca3c4..ec823e3 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -9,12 +9,13 @@ from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion from itopapi.model.features.hasOSLicence import HasOSLicence +from itopapi.model.features.hasVirtualHost import HasVirtualHost __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasOSVersion, HasOSLicence): +class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasOSVersion, HasOSLicence, HasVirtualHost): # Configuration specific to itop itop = { @@ -28,7 +29,7 @@ class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasO HasOSFamily.foreign_key, HasOSVersion.foreign_key, HasOSLicence.foreign_key, - {'id': 'virtualhost_id', 'name': 'virtualhost_name', 'table': 'VirtualHost'}, + HasVirtualHost.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -55,90 +56,36 @@ def find_all(): def __init__(self, data=None): super(ItopapiVirtualMachine, self).__init__(data) - ################################## - # Properties/General Information # - ################################## # VirtualMachine's status. Values within [implementation, obsolete, production, stock] self.status = None # VirtualMachine's business criticity. Values within [high, medium, low] self.business_criticity = None - # VirtualMachine's virtual host - self.virtualhost_id = None - self.virtualhost_id_finalclass_recall = None - self.virtualhost_id_friendlyname = None - self.virtualhost_name = None - - ################################## - # Properties/More Information # - ################################## - self.managementip = None - self.cpu = None self.ram = None - - ################################## - # Properties/Date # - ################################## - - ################################## - # Properties/Other Information # - ################################## # VirtualMachine's move to production date self.move2production = None # VirtualMachine's description, as a free text self.description = None - ################################## - # Softwares # - ################################## + ############################## + # Lists # + ############################## # VirtualMachine's softwares list self.softwares_list = {} - - ################################## - # Contacts # - ################################## # VirtualMachine's contacts list self.contacts_list = {} - - ################################## - # Documents # - ################################## # VirtualMachine's documents list self.documents_list = {} - - ################################## - # Tickets # - ################################## # VirtualMachine's tickets list self.tickets_list = {} - - ################################## - # Application solutions # - ################################## # VirtualMachine's application solutions list self.applicationsolution_list = {} - - ################################## - # Network interfaces # - ################################## # VirtualMachine's network interfaces list self.physicalinterface_list = {} - - ################################## - # Logical volumes # - ################################## # VirtualMachine's logical volumes list self.logicalvolumes_list = {} - - ################################## - # Provider contracts # - ################################## # VirtualMachine's provider contracts list self.providercontracts_list = {} - - ################################## - # Services # - ################################## # VirtualMachine's services list self.services_list = {} diff --git a/vcenter2itop.py b/vcenter2itop.py index 64abfc3..d6e54e1 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -280,9 +280,7 @@ def get_vm_params(itop_vm, vcenter_vm, organization): # Set the OS version itop_vm.set_osversion(os_version) # Set the virtual host (Hypervisor or Farm) - itop_vm.virtualhost_id = virtualhost.instance_id - itop_vm.virtualhost_id_friendlyname = virtualhost.friendlyname - itop_vm.virtualhost_name = virtualhost.name + itop_vm.set_virtualhost(virtualhost) # Set other fields config_cpu = int(config.hardware.numCPU) From aaaa0a23f07a8ef60e01e8980c6569ed11943646 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:12:18 +0100 Subject: [PATCH 082/104] Added HasRack mixin and updated data model. --- itopapi/model/enclosure.py | 20 ++----------- itopapi/model/features/__init__.py | 3 +- itopapi/model/features/hasRack.py | 46 ++++++++++++++++++++++++++++++ itopapi/model/server.py | 22 ++++---------- 4 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 itopapi/model/features/hasRack.py diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index 758d63c..ce79b07 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -9,12 +9,13 @@ from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasRack import HasRack __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel): +class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, HasRack): # Configuration specific to itop itop = { @@ -28,7 +29,7 @@ class ItopapiEnclosure(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasLocation.foreign_key, HasBrand.foreign_key, HasModel.foreign_key, - {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, + HasRack.foreign_key, ], } @@ -55,13 +56,6 @@ def __init__(self, data=None): self.status = None # Enclosure's business criticity. Values within [high, medium, low] self.business_criticity = None - # Enclosure's rack id. Call findRack to get the full information or just use rack_id - # friendlyname and rack_name - self.rack_id = None - # Enclosure's rack id's friendly name. Not sure the difference with rack_name - self.rack_id_friendlyname = None - # Enclosure's rack name - self.rack_name = None # Rack units self.nb_u = None # Serial number @@ -75,11 +69,3 @@ def __init__(self, data=None): # Server's end of warranty date self.end_of_warranty = None self.description = None - - def find_rack(self): - """ - Retrieve the ItopapiRack corresponding to this server - """ - if self.rack_id is not None: - return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) - return None diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 76092d9..cfda7ce 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -15,4 +15,5 @@ from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion from itopapi.model.features.hasOSLicence import HasOSLicence -from itopapi.model.features.hasVirtualHost import HasVirtualhost +from itopapi.model.features.hasVirtualHost import HasVirtualHost +from itopapi.model.features.hasRack import HasRack diff --git a/itopapi/model/features/hasRack.py b/itopapi/model/features/hasRack.py new file mode 100644 index 0000000..bfc0a82 --- /dev/null +++ b/itopapi/model/features/hasRack.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasRack is a mixin representing the rack attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasRack(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'} + + def __init__(self): + super(HasRack, self).__init__() + + # Object's rack id. Call find_rack to get the full information or just use + # rack_id_friendlyname and rack_name + self.rack_id = None + # Object's rack id's friendly name. Not sure the difference with rack_name + self.rack_id_friendlyname = None + # Object's rack name + self.rack_name = None + + def find_rack(self): + """ + Retrieve the ItopapiRack related to this instance + """ + if self.rack_id is not None: + return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) + return None + + def set_rack(self, rack): + """ + Set the ItopapiOrganization parameters + """ + self.rack_id = rack.instance_id + self.rack_id_friendlyname = rack.friendlyname + self.rack_name = rack.name diff --git a/itopapi/model/server.py b/itopapi/model/server.py index bc11983..cd7d507 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -12,12 +12,14 @@ from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion from itopapi.model.features.hasOSLicence import HasOSLicence +from itopapi.model.features.hasRack import HasRack __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, HasOSFamily, HasOSVersion, HasOSLicence): +class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, + HasOSFamily, HasOSVersion, HasOSLicence, HasRack): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -38,7 +40,7 @@ class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, Ha HasOSFamily.foreign_key, HasOSVersion.foreign_key, HasOSLicence.foreign_key, - {'id': 'rack_id', 'name': 'rack_name', 'table': 'Rack'}, + HasRack.foreign_key, {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, @@ -73,13 +75,6 @@ def __init__(self, data=None): self.status = None # Server's business criticity. Values within [high, medium, low] self.business_criticity = None - # Server's rack id. Call findRack to get the full information or just use rack_id - # friendlyname and rack_name - self.rack_id = None - # Server's rack id's friendly name. Not sure the difference with rack_name - self.rack_id_friendlyname = None - # Server's rack name - self.rack_name = None # Server's enclosure (chassis) id. Call findEnclosure to get the full information or just # use enclosure_id_friendlyname and enclosure_name self.enclosure_id = None @@ -199,14 +194,6 @@ def __init__(self, data=None): # Server's services list self.services_list = {} - def find_rack(self): - """ - Retrieve the ItopapiRack corresponding to this server - """ - if self.rack_id is not None: - return ItopapiPrototype.get_itop_class('Rack').find(self.rack_id) - return None - def find_enclosure(self): """ Retrieve the ItopapiEnclosure corresponding to this server @@ -214,6 +201,7 @@ def find_enclosure(self): if self.enclosure_id is not None: return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) return None + def find_power_a(self): """ Retrieve the ItopapiPowerA corresponding to this server From 34ce780d13f20e6bd1e252f422616724d3afd81a Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:16:32 +0100 Subject: [PATCH 083/104] Added HasEnclosure mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasEnclosure.py | 46 ++++++++++++++ itopapi/model/server.py | 87 ++------------------------ 3 files changed, 53 insertions(+), 81 deletions(-) create mode 100644 itopapi/model/features/hasEnclosure.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index cfda7ce..d298df9 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -17,3 +17,4 @@ from itopapi.model.features.hasOSLicence import HasOSLicence from itopapi.model.features.hasVirtualHost import HasVirtualHost from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasEnclosure import HasEnclosure diff --git a/itopapi/model/features/hasEnclosure.py b/itopapi/model/features/hasEnclosure.py new file mode 100644 index 0000000..340d184 --- /dev/null +++ b/itopapi/model/features/hasEnclosure.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasEnclosure is a mixin representing the enclosure attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasEnclosure(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'} + + def __init__(self): + super(HasEnclosure, self).__init__() + + # Object's enclosure id. Call find_enclosure to get the full information or just use + # enclosure_id_friendlyname and enclosure_name + self.enclosure_id = None + # Object's enclosure id's friendly name. Not sure the difference with enclosure_name + self.enclosure_id_friendlyname = None + # Object's enclosure name + self.enclosure_name = None + + def find_enclosure(self): + """ + Retrieve the ItopapiEnclosure related to this instance + """ + if self.enclosure_id is not None: + return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) + return None + + def set_enclosure(self, enclosure): + """ + Set the ItopapiOrganization parameters + """ + self.enclosure_id = enclosure.instance_id + self.enclosure_id_friendlyname = enclosure.friendlyname + self.enclosure_name = enclosure.name diff --git a/itopapi/model/server.py b/itopapi/model/server.py index cd7d507..8bc93ac 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -13,13 +13,14 @@ from itopapi.model.features.hasOSVersion import HasOSVersion from itopapi.model.features.hasOSLicence import HasOSLicence from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasEnclosure import HasEnclosure __version__ = '1.0' __authors__ = ['Julien Nauroy '] class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, - HasOSFamily, HasOSVersion, HasOSLicence, HasRack): + HasOSFamily, HasOSVersion, HasOSLicence, HasRack, HasEnclosure): """ ItopapiServers is an object that represents a Servers from iTop """ @@ -41,7 +42,7 @@ class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, Ha HasOSVersion.foreign_key, HasOSLicence.foreign_key, HasRack.foreign_key, - {'id': 'enclosure_id', 'name': 'enclosure_name', 'table': 'Enclosure'}, + HasEnclosure.foreign_key, {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, ], @@ -68,27 +69,11 @@ def find_all(): def __init__(self, data=None): super(ItopapiServer, self).__init__(data) - ################################## - # Properties/General Information # - ################################## # Server's status. Values within [implementation, obsolete, production, stock] self.status = None # Server's business criticity. Values within [high, medium, low] self.business_criticity = None - # Server's enclosure (chassis) id. Call findEnclosure to get the full information or just - # use enclosure_id_friendlyname and enclosure_name - self.enclosure_id = None - # Server's enclosure id's friendly name. Not sure the difference with enclosure_name - self.enclosure_id_friendlyname = None - # Server's enclosure name - self.enclosure_name = None - - ################################## - # Properties/More Information # - ################################## - self.managementip = None - self.cpu = None self.ram = None # Rack units @@ -97,20 +82,12 @@ def __init__(self, data=None): self.serialnumber = None # Server's asset number self.asset_number = None - - ################################## - # Properties/Date # - ################################## # Server's move to production date self.move2production = None # Server's purchase date self.purchase_date = None # Server's end of warranty date self.end_of_warranty = None - - ################################## - # Properties/Other Information # - ################################## self.powerA_id = None self.powerA_id_finalclass_recall = None self.powerA_id_friendlyname = None @@ -122,86 +99,34 @@ def __init__(self, data=None): # Server's description, as a free text self.description = None - ################################## - # Softwares # - ################################## + ############################## + # Lists # + ############################## # Server's softwares list self.softwares_list = {} - - ################################## - # Contacts # - ################################## # Server's contacts list self.contacts_list = {} - - ################################## - # Documents # - ################################## # Server's documents list self.documents_list = {} - - ################################## - # Tickets # - ################################## # Server's tickets list self.tickets_list = {} - - ################################## - # Application solutions # - ################################## # Server's application solutions list self.applicationsolution_list = {} - - ################################## - # Network interfaces # - ################################## # Server's network interfaces list self.physicalinterface_list = {} - - ################################## - # FC ports # - ################################## # Server's FC ports list self.fiberinterfacelist_list = {} - - ################################## - # Network devices # - ################################## # Server's network devices list self.networkdevice_list = {} - - ################################## - # SANs # - ################################## # Server's SANs list self.san_list = {} - - ################################## - # Logical volumes # - ################################## # Server's logical volumes list self.logicalvolumes_list = {} - - ################################## - # Provider contracts # - ################################## # Server's provider contracts list self.providercontracts_list = {} - - ################################## - # Services # - ################################## # Server's services list self.services_list = {} - def find_enclosure(self): - """ - Retrieve the ItopapiEnclosure corresponding to this server - """ - if self.enclosure_id is not None: - return ItopapiPrototype.get_itop_class('Enclosure').find(self.enclosure_id) - return None - def find_power_a(self): """ Retrieve the ItopapiPowerA corresponding to this server From 752c09b99beb407504e4e53d7f2f29402be0c37b Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:22:05 +0100 Subject: [PATCH 084/104] Organization was not well referenced in these classes --- itopapi/model/applicationSolution.py | 1 - itopapi/model/dbserver.py | 5 +++-- itopapi/model/webServer.py | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index 81d77b3..cd45fac 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -25,7 +25,6 @@ class ItopapiApplicationSolution(ItopapiPrototype, HasOrganization): 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, ], 'list_types': { 'functionalcis_list': 'functionalci_id_finalclass_recall', diff --git a/itopapi/model/dbserver.py b/itopapi/model/dbserver.py index 6759792..4688cb7 100644 --- a/itopapi/model/dbserver.py +++ b/itopapi/model/dbserver.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.othersoftware import ItopapiOtherSoftware +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiDBServer(ItopapiOtherSoftware): +class ItopapiDBServer(ItopapiOtherSoftware, HasOrganization): """ ItopapiDBServer is an object that represents a DBServer from iTop It has the same attributes as ItopapiOtherSoftware @@ -24,7 +25,7 @@ class ItopapiDBServer(ItopapiOtherSoftware): # Define which fields to save when creating or updating from the python API 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, ], diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index c14e044..1d32f00 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -5,13 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod -from itopapi.model.rack import ItopapiRack +from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiWebServer(ItopapiPrototype): +class ItopapiWebServer(ItopapiPrototype, HasOrganization): """ ItopapiWebServer is an object that represents a WebServer from iTop """ @@ -23,7 +23,7 @@ class ItopapiWebServer(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'status', 'business_criticity', 'path', 'move2production', 'description'], 'foreign_keys': [ - {'id': 'org_id', 'name': 'organization_name', 'table': 'Organization'}, + HasOrganization.foreign_key, {'id': 'system_id', 'name': 'system_id_friendlyname', 'table': 'Server'}, {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, From 82cf493e5325ad532f6990d99a82c448df4d71a4 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:26:10 +0100 Subject: [PATCH 085/104] Added HasServer mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasServer.py | 46 +++++++++++++++++++++++++++++ itopapi/model/hypervisor.py | 9 ++---- 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 itopapi/model/features/hasServer.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index d298df9..d0a0881 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -18,3 +18,4 @@ from itopapi.model.features.hasVirtualHost import HasVirtualHost from itopapi.model.features.hasRack import HasRack from itopapi.model.features.hasEnclosure import HasEnclosure +from itopapi.model.features.hasServer import HasServer diff --git a/itopapi/model/features/hasServer.py b/itopapi/model/features/hasServer.py new file mode 100644 index 0000000..e601fb1 --- /dev/null +++ b/itopapi/model/features/hasServer.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasServer is a mixin representing the server attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasServer(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'server_id', 'name': 'server_name', 'table': 'Server'} + + def __init__(self): + super(HasServer, self).__init__() + + # Object's server id. Call find_server to get the full information or just use + # server_id_friendlyname and server_name + self.server_id = None + # Object's server id's friendly name. Not sure the difference with server_name + self.server_id_friendlyname = None + # Object's server name + self.server_name = None + + def find_server(self): + """ + Retrieve the ItopapiServer related to this instance + """ + if self.server_id is not None: + return ItopapiPrototype.get_itop_class('Server').find(self.server_id) + return None + + def set_server(self, server): + """ + Set the ItopapiOrganization parameters + """ + self.server_id = server.instance_id + self.server_id_friendlyname = server.friendlyname + self.server_name = server.name diff --git a/itopapi/model/hypervisor.py b/itopapi/model/hypervisor.py index d4ecdb8..6448aa6 100644 --- a/itopapi/model/hypervisor.py +++ b/itopapi/model/hypervisor.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasServer import HasServer __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiHypervisor(ItopapiPrototype, HasOrganization): +class ItopapiHypervisor(ItopapiPrototype, HasOrganization, HasServer): # Configuration specific to itop itop = { @@ -21,7 +22,7 @@ class ItopapiHypervisor(ItopapiPrototype, HasOrganization): 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'server_id', 'name': 'server_name', 'table': 'Server'}, + HasServer.foreign_key, {'id': 'farm_id', 'name': 'farm_name', 'table': 'Farm'}, ], 'list_types': { @@ -56,10 +57,6 @@ def __init__(self, data=None): self.move2production = None # Hypervisor's description, as a free text self.description = None - # Physical server the hypervisor is running onto - self.server_id = None - self.server_id_friendlyname = None - self.server_name = None # Farm the hypervisor belongs to self.farm_id = None self.farm_id_friendlyname = None From 1ac277dc1996cf0785e9c07a8db2919e4420b6d0 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:28:50 +0100 Subject: [PATCH 086/104] Added HasFarm mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasFarm.py | 46 ++++++++++++++++++++++++++++++ itopapi/model/hypervisor.py | 9 ++---- vcenter2itop.py | 8 ++---- 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 itopapi/model/features/hasFarm.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index d0a0881..54702a7 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -19,3 +19,4 @@ from itopapi.model.features.hasRack import HasRack from itopapi.model.features.hasEnclosure import HasEnclosure from itopapi.model.features.hasServer import HasServer +from itopapi.model.features.hasFarm import HasFarm diff --git a/itopapi/model/features/hasFarm.py b/itopapi/model/features/hasFarm.py new file mode 100644 index 0000000..a366f03 --- /dev/null +++ b/itopapi/model/features/hasFarm.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasFarm is a mixin representing the farm attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasFarm(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'farm_id', 'name': 'farm_name', 'table': 'Farm'} + + def __init__(self): + super(HasFarm, self).__init__() + + # Object's farm id. Call find_farm to get the full information or just use + # farm_id_friendlyname and farm_name + self.farm_id = None + # Object's farm id's friendly name. Not sure the difference with farm_name + self.farm_id_friendlyname = None + # Object's farm name + self.farm_name = None + + def find_farm(self): + """ + Retrieve the ItopapiFarm related to this instance + """ + if self.farm_id is not None: + return ItopapiPrototype.get_itop_class('Farm').find(self.farm_id) + return None + + def set_farm(self, farm): + """ + Set the ItopapiOrganization parameters + """ + self.farm_id = farm.instance_id + self.farm_id_friendlyname = farm.friendlyname + self.farm_name = farm.name diff --git a/itopapi/model/hypervisor.py b/itopapi/model/hypervisor.py index 6448aa6..ad32749 100644 --- a/itopapi/model/hypervisor.py +++ b/itopapi/model/hypervisor.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasServer import HasServer +from itopapi.model.features.hasFarm import HasFarm __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiHypervisor(ItopapiPrototype, HasOrganization, HasServer): +class ItopapiHypervisor(ItopapiPrototype, HasOrganization, HasFarm): # Configuration specific to itop itop = { @@ -23,7 +24,7 @@ class ItopapiHypervisor(ItopapiPrototype, HasOrganization, HasServer): 'foreign_keys': [ HasOrganization.foreign_key, HasServer.foreign_key, - {'id': 'farm_id', 'name': 'farm_name', 'table': 'Farm'}, + HasFarm.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -57,10 +58,6 @@ def __init__(self, data=None): self.move2production = None # Hypervisor's description, as a free text self.description = None - # Farm the hypervisor belongs to - self.farm_id = None - self.farm_id_friendlyname = None - self.farm_name = None # Lists self.tickets_list = None diff --git a/vcenter2itop.py b/vcenter2itop.py index d6e54e1..c1b2b8f 100644 --- a/vcenter2itop.py +++ b/vcenter2itop.py @@ -244,11 +244,9 @@ def get_hypervisor_params(itop_hypervisor, itop_server): itop_hypervisor.server_id_friendlyname = itop_server.friendlyname itop_hypervisor.server_name = itop_server.name # Set the farm if possible - farm = host_to_farm.get(itop_server.name) - if farm is not None: - itop_hypervisor.farm_id = farm.instance_id - itop_hypervisor.farm_id_friendlyname = farm.friendlyname - itop_hypervisor.farm_name = farm.name + itop_farm = host_to_farm.get(itop_server.name) + if itop_farm is not None: + itop_hypervisor.set_farm(itop_farm) # Set other fields itop_hypervisor.name = itop_server.name From 9ea1f6cdac7cff716931bc059ff4712acd7dcc40 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:33:46 +0100 Subject: [PATCH 087/104] Added HasWebServer mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasWebServer.py | 46 ++++++++++++++++++++++++++ itopapi/model/webApplication.py | 17 ++-------- 3 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 itopapi/model/features/hasWebServer.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 54702a7..c73d83b 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -20,3 +20,4 @@ from itopapi.model.features.hasEnclosure import HasEnclosure from itopapi.model.features.hasServer import HasServer from itopapi.model.features.hasFarm import HasFarm +from itopapi.model.features.hasWebServer import HasWebServer diff --git a/itopapi/model/features/hasWebServer.py b/itopapi/model/features/hasWebServer.py new file mode 100644 index 0000000..5074120 --- /dev/null +++ b/itopapi/model/features/hasWebServer.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasWebServer is a mixin representing the webserver attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasWebServer(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'webserver_id', 'name': 'webserver_name', 'table': 'WebServer'} + + def __init__(self): + super(HasWebServer, self).__init__() + + # Object's webserver id. Call find_webserver to get the full information or just use + # webserver_id_friendlyname and webserver_name + self.webserver_id = None + # Object's webserver id's friendly name. Not sure the difference with webserver_name + self.webserver_id_friendlyname = None + # Object's webserver name + self.webserver_name = None + + def find_webserver(self): + """ + Retrieve the ItopapiWebServer related to this instance + """ + if self.webserver_id is not None: + return ItopapiPrototype.get_itop_class('WebServer').find(self.webserver_id) + return None + + def set_webserver(self, webserver): + """ + Set the ItopapiOrganization parameters + """ + self.webserver_id = webserver.instance_id + self.webserver_id_friendlyname = webserver.friendlyname + self.webserver_name = webserver.name diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 2b2fce6..ed37c09 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasWebServer import HasWebServer __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiWebApplication(ItopapiPrototype, HasOrganization): +class ItopapiWebApplication(ItopapiPrototype, HasOrganization, HasWebServer): """ ItopapiWebApplication is an object that represents a WebApplication from iTop """ @@ -25,7 +26,7 @@ class ItopapiWebApplication(ItopapiPrototype, HasOrganization): 'move2production', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'webserver_id', 'name': 'webserver_name', 'table': 'WebServer'}, + HasWebServer.foreign_key, ], 'list_types': { 'services_list': 'Service', @@ -53,10 +54,6 @@ def __init__(self, data=None): ################################## # Properties/General Information # ################################## - # WebServer hosting the application - self.webserver_id = None - self.webserver_id_friendlyname = None - self.webserver_name = None # WebApplication's URL self.url = None # WebApplication's business criticity. Values within [high, medium, low] @@ -101,11 +98,3 @@ def __init__(self, data=None): ################################## # WebApplication's services list self.services_list = {} - - def find_web_server(self): - """ - Retrieve the ItopapiWebServer corresponding to this WebApplication - """ - if self.webserver_id is not None: - return ItopapiPrototype.get_itop_class('WebServer').find(self.webserver_id) - return None From 655a88c8da2a8516ef2e1320c528f2f4b0c70fdc Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:40:35 +0100 Subject: [PATCH 088/104] added HasDeliveryModel mixin and updated data model. --- itopapi/model/features/__init__.py | 2 + itopapi/model/features/hasDeliveryModel.py | 46 +++++++++++++++++++ .../model/features/hasParentOrganization.py | 46 +++++++++++++++++++ itopapi/model/organization.py | 33 +++---------- 4 files changed, 100 insertions(+), 27 deletions(-) create mode 100644 itopapi/model/features/hasDeliveryModel.py create mode 100644 itopapi/model/features/hasParentOrganization.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index c73d83b..2209f6d 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -21,3 +21,5 @@ from itopapi.model.features.hasServer import HasServer from itopapi.model.features.hasFarm import HasFarm from itopapi.model.features.hasWebServer import HasWebServer +from itopapi.model.features.hasParentOrganization import HasParentOrganization +from itopapi.model.features.hasDeliveryModel import HasDeliveryModel diff --git a/itopapi/model/features/hasDeliveryModel.py b/itopapi/model/features/hasDeliveryModel.py new file mode 100644 index 0000000..7b104c2 --- /dev/null +++ b/itopapi/model/features/hasDeliveryModel.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasDeliveryModel is a mixin representing the deliverymodel attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasDeliveryModel(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'deliverymodel_id', 'name': 'deliverymodel_name', 'table': 'DeliveryModel'} + + def __init__(self): + super(HasDeliveryModel, self).__init__() + + # Object's deliverymodel id. Call find_deliverymodel to get the full information or just use + # deliverymodel_id_friendlyname and deliverymodel_name + self.deliverymodel_id = None + # Object's deliverymodel id's friendly name. Not sure the difference with deliverymodel_name + self.deliverymodel_id_friendlyname = None + # Object's deliverymodel name + self.deliverymodel_name = None + + def find_deliverymodel(self): + """ + Retrieve the ItopapiDeliveryModel related to this instance + """ + if self.deliverymodel_id is not None: + return ItopapiPrototype.get_itop_class('DeliveryModel').find(self.deliverymodel_id) + return None + + def set_deliverymodel(self, deliverymodel): + """ + Set the ItopapiOrganization parameters + """ + self.deliverymodel_id = deliverymodel.instance_id + self.deliverymodel_id_friendlyname = deliverymodel.friendlyname + self.deliverymodel_name = deliverymodel.name diff --git a/itopapi/model/features/hasParentOrganization.py b/itopapi/model/features/hasParentOrganization.py new file mode 100644 index 0000000..b987c1d --- /dev/null +++ b/itopapi/model/features/hasParentOrganization.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasParentOrganization is a mixin representing the parent organization attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasParentOrganization(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'parent_id', 'name': 'parent_name', 'table': 'Organization'} + + def __init__(self): + super(HasParentOrganization, self).__init__() + + # Object's parent id. Call find_parent to get the full information or just use + # parent_id_friendlyname and parent_name + self.parent_id = None + # Object's parent id's friendly name. Not sure the difference with parent_name + self.parent_id_friendlyname = None + # Object's parent name + self.parent_name = None + + def find_parent(self): + """ + Retrieve the ItopapiOrganization related to this instance + """ + if self.parent_id is not None: + return ItopapiPrototype.get_itop_class('Organization').find(self.parent_id) + return None + + def set_parent(self, parent): + """ + Set the ItopapiOrganization parameters + """ + self.parent_id = parent.instance_id + self.parent_id_friendlyname = parent.friendlyname + self.parent_name = parent.name diff --git a/itopapi/model/organization.py b/itopapi/model/organization.py index 12a2587..9b8fb51 100644 --- a/itopapi/model/organization.py +++ b/itopapi/model/organization.py @@ -6,11 +6,14 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.deliveryModel import ItopapiDeliveryModel +from itopapi.model.features.hasParentOrganization import HasParentOrganization +from itopapi.model.features.hasDeliveryModel import HasDeliveryModel __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOrganization(ItopapiPrototype): + +class ItopapiOrganization(ItopapiPrototype, HasParentOrganization, HasDeliveryModel): # Configuration specific to itop itop = { @@ -19,8 +22,8 @@ class ItopapiOrganization(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'code', 'status'], 'foreign_keys': [ - {'id': 'parent_id', 'name': 'parent_name', 'table': 'Organization'}, - {'id': 'deliverymodel_id', 'name': 'deliverymodel_name', 'table': 'DeliveryModel'}, + HasParentOrganization.foreign_key, + HasDeliveryModel.foreign_key, ] } @@ -47,27 +50,3 @@ def __init__(self, data=None): self.code = None # Application Solution's status. Values within [inactive, active] self.status = None - # Parent information - self.parent_id = None - self.parent_name = None - self.parent_id_friendlyname = None - # Delivery model - self.deliverymodel_id = None - self.deliverymodel_name = None - self.deliverymodel_id_friendlyname = None - - def find_parent(self): - """ - Retrieve the parent ItopapiOrganization - """ - if self.parent_id is not None: - return ItopapiOrganization.find(self.parent_id) - return None - - def find_delivery_model(self): - """ - Retrieve the ItopapiDeliveryModel associated with this entry - """ - if self.deliverymodel_id is not None: - return ItopapiDeliveryModel.find(self.deliverymodel_id) - return None \ No newline at end of file From 709ac3351153a7861ffe97ca518f4a4903a499d5 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:46:34 +0100 Subject: [PATCH 089/104] Added HasSoftwareLicence (sic) mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasSoftwareLicence.py | 46 +++++++++++++ itopapi/model/othersoftware.py | 9 +-- itopapi/model/webServer.py | 68 ++------------------ 4 files changed, 56 insertions(+), 68 deletions(-) create mode 100644 itopapi/model/features/hasSoftwareLicence.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 2209f6d..7e3b5ed 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -23,3 +23,4 @@ from itopapi.model.features.hasWebServer import HasWebServer from itopapi.model.features.hasParentOrganization import HasParentOrganization from itopapi.model.features.hasDeliveryModel import HasDeliveryModel +from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence diff --git a/itopapi/model/features/hasSoftwareLicence.py b/itopapi/model/features/hasSoftwareLicence.py new file mode 100644 index 0000000..2519af6 --- /dev/null +++ b/itopapi/model/features/hasSoftwareLicence.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasSoftwareLicence is a mixin representing the softwarelicence attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasSoftwareLicence(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'} + + def __init__(self): + super(HasSoftwareLicence, self).__init__() + + # Object's softwarelicence id. Call find_softwarelicence to get the full information or just use + # softwarelicence_id_friendlyname and softwarelicence_name + self.softwarelicence_id = None + # Object's softwarelicence id's friendly name. Not sure the difference with softwarelicence_name + self.softwarelicence_id_friendlyname = None + # Object's softwarelicence name + self.softwarelicence_name = None + + def find_softwarelicence(self): + """ + Retrieve the ItopapiSoftwareLicence related to this instance + """ + if self.softwarelicence_id is not None: + return ItopapiPrototype.get_itop_class('SoftwareLicence').find(self.softwarelicence_id) + return None + + def set_softwarelicence(self, softwarelicence): + """ + Set the ItopapiOrganization parameters + """ + self.softwarelicence_id = softwarelicence.instance_id + self.softwarelicence_id_friendlyname = softwarelicence.friendlyname + self.softwarelicence_name = softwarelicence.name diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index 8cfc0af..949a86b 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization): +class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization, HasSoftwareLicence): """ ItopapiOtherSoftware is an object that represents a OtherSoftware from iTop """ @@ -25,7 +26,7 @@ class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization): 'foreign_keys': [ HasOrganization.foreign_key, {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, - {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, + HasSoftwareLicence.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -56,10 +57,6 @@ def __init__(self, data=None): self.software_id = None self.software_id_friendlyname = None self.software_name = None - # OtherSoftware's software licence - self.softwarelicence_id = None - self.softwarelicence_id_friendlyname = None - self.softwarelicence_name = None # OtherSoftware's status. Values within [implementation, obsolete, production, stock] self.status = None # OtherSoftware's business criticity. Values within [high, medium, low] diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 1d32f00..685858f 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiWebServer(ItopapiPrototype, HasOrganization): +class ItopapiWebServer(ItopapiPrototype, HasOrganization, HasSoftwareLicence): """ ItopapiWebServer is an object that represents a WebServer from iTop """ @@ -26,7 +27,7 @@ class ItopapiWebServer(ItopapiPrototype, HasOrganization): HasOrganization.foreign_key, {'id': 'system_id', 'name': 'system_id_friendlyname', 'table': 'Server'}, {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, - {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, + HasSoftwareLicence.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -66,10 +67,6 @@ def __init__(self, data=None): self.software_id = None self.software_id_friendlyname = None self.software_name = None - # Web server's software licence - self.softwarelicence_id = None - self.softwarelicence_id_friendlyname = None - self.softwarelicence_name = None # Web server's path ? self.path = None # WebServer's move to production date @@ -77,75 +74,31 @@ def __init__(self, data=None): # WebServer's description, as a free text self.description = None - ################################## - # Contacts # - ################################## + ############################### + # Lists # + ############################### # WebServer's contacts list self.contacts_list = {} - - ################################## - # Documents # - ################################## # WebServer's documents list self.documents_list = {} - - ################################## - # Tickets # - ################################## # WebServer's tickets list self.tickets_list = {} - - ################################## - # Application solutions # - ################################## # WebServer's application solutions list self.applicationsolution_list = {} - - ################################## - # Web applications # - ################################## # WebServer's web applications list self.webapp_list = {} - - ################################## - # Network interfaces # - ################################## # WebServer's network interfaces list self.physicalinterface_list = {} - - ################################## - # FC ports # - ################################## # WebServer's FC ports list self.fiberinterfacelist_list = {} - - ################################## - # Network devices # - ################################## # WebServer's network devices list self.networkdevice_list = {} - - ################################## - # SANs # - ################################## # WebServer's SANs list self.san_list = {} - - ################################## - # Logical volumes # - ################################## # WebServer's logical volumes list self.logicalvolumes_list = {} - - ################################## - # Provider contracts # - ################################## # WebServer's provider contracts list self.providercontracts_list = {} - - ################################## - # Services # - ################################## # WebServer's services list self.services_list = {} @@ -166,12 +119,3 @@ def find_software(self): # TODO define Software raise ItopapiUnimplementedMethod() return None - - def find_software_licence(self): - """ - Retrieve the Software Licence corresponding to this WebServer - """ - if self.software_licence_id is not None: - # TODO define SoftwareLicense - raise ItopapiUnimplementedMethod() - return None From 609750222ce7b77458fab066211e3111cb545fa4 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:49:39 +0100 Subject: [PATCH 090/104] Added HasSoftware mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasSoftware.py | 46 +++++++++++++++++++++++++++ itopapi/model/othersoftware.py | 9 ++---- itopapi/model/webServer.py | 18 ++--------- 4 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 itopapi/model/features/hasSoftware.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 7e3b5ed..2b451fe 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -24,3 +24,4 @@ from itopapi.model.features.hasParentOrganization import HasParentOrganization from itopapi.model.features.hasDeliveryModel import HasDeliveryModel from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence +from itopapi.model.features.hasSoftware import HasSoftware diff --git a/itopapi/model/features/hasSoftware.py b/itopapi/model/features/hasSoftware.py new file mode 100644 index 0000000..f460a9a --- /dev/null +++ b/itopapi/model/features/hasSoftware.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasSoftware is a mixin representing the software attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasSoftware(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'software_id', 'name': 'software_name', 'table': 'Software'} + + def __init__(self): + super(HasSoftware, self).__init__() + + # Object's software id. Call find_software to get the full information or just use + # software_id_friendlyname and software_name + self.software_id = None + # Object's software id's friendly name. Not sure the difference with software_name + self.software_id_friendlyname = None + # Object's software name + self.software_name = None + + def find_software(self): + """ + Retrieve the ItopapiSoftware related to this instance + """ + if self.software_id is not None: + return ItopapiPrototype.get_itop_class('Software').find(self.software_id) + return None + + def set_software(self, software): + """ + Set the ItopapiOrganization parameters + """ + self.software_id = software.instance_id + self.software_id_friendlyname = software.friendlyname + self.software_name = software.name diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index 949a86b..b5d1570 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence +from itopapi.model.features.hasSoftware import HasSoftware __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization, HasSoftwareLicence): +class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization, HasSoftwareLicence, HasSoftware): """ ItopapiOtherSoftware is an object that represents a OtherSoftware from iTop """ @@ -25,7 +26,7 @@ class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization, HasSoftwareLicence 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, + HasSoftware.foreign_key, HasSoftwareLicence.foreign_key, ], 'list_types': { @@ -53,10 +54,6 @@ def __init__(self, data=None): ################################## # Properties # ################################## - # OtherSoftware's software (good job!) - self.software_id = None - self.software_id_friendlyname = None - self.software_name = None # OtherSoftware's status. Values within [implementation, obsolete, production, stock] self.status = None # OtherSoftware's business criticity. Values within [high, medium, low] diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 685858f..0752c09 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence +from itopapi.model.features.hasSoftware import HasSoftware __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiWebServer(ItopapiPrototype, HasOrganization, HasSoftwareLicence): +class ItopapiWebServer(ItopapiPrototype, HasOrganization, HasSoftwareLicence, HasSoftware): """ ItopapiWebServer is an object that represents a WebServer from iTop """ @@ -26,7 +27,7 @@ class ItopapiWebServer(ItopapiPrototype, HasOrganization, HasSoftwareLicence): 'foreign_keys': [ HasOrganization.foreign_key, {'id': 'system_id', 'name': 'system_id_friendlyname', 'table': 'Server'}, - {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, + HasSoftware.foreign_key, HasSoftwareLicence.foreign_key, ], 'list_types': { @@ -63,10 +64,6 @@ def __init__(self, data=None): self.system_id_finalclass_recall = None self.system_id_friendlyname = None self.system_name = None - # Web server's software - self.software_id = None - self.software_id_friendlyname = None - self.software_name = None # Web server's path ? self.path = None # WebServer's move to production date @@ -110,12 +107,3 @@ def find_system(self): # TODO define System raise ItopapiUnimplementedMethod() return None - - def find_software(self): - """ - Retrieve the Software corresponding to this WebServer - """ - if self.software_id is not None: - # TODO define Software - raise ItopapiUnimplementedMethod() - return None From 86e883e8b9a8887648d9f00ec7d10c5e54dfd02e Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:51:38 +0100 Subject: [PATCH 091/104] Forgot to update this class' data model. --- itopapi/model/dbserver.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/itopapi/model/dbserver.py b/itopapi/model/dbserver.py index 4688cb7..fbb9597 100644 --- a/itopapi/model/dbserver.py +++ b/itopapi/model/dbserver.py @@ -7,6 +7,8 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.othersoftware import ItopapiOtherSoftware from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasSoftware import HasSoftware +from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence __version__ = '1.0' __authors__ = ['Julien Nauroy '] @@ -26,8 +28,8 @@ class ItopapiDBServer(ItopapiOtherSoftware, HasOrganization): 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'software_id', 'name': 'software_name', 'table': 'Software'}, - {'id': 'softwarelicence_id', 'name': 'softwarelicence_name', 'table': 'SoftwareLicence'}, + HasSoftware.foreign_key, + HasSoftwareLicence.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' From 8657c6c28d603694f312e89c38db976702b7186f Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:55:17 +0100 Subject: [PATCH 092/104] Added HasTeam mixin and updated data model. --- itopapi/model/features/__init__.py | 3 +- itopapi/model/features/hasTeam.py | 46 ++++++++++++++++++++++++++++++ itopapi/model/incident.py | 9 ++---- 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 itopapi/model/features/hasTeam.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 2b451fe..6220a2d 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -23,5 +23,6 @@ from itopapi.model.features.hasWebServer import HasWebServer from itopapi.model.features.hasParentOrganization import HasParentOrganization from itopapi.model.features.hasDeliveryModel import HasDeliveryModel -from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasSoftware import HasSoftware +from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence +from itopapi.model.features.hasTeam import HasTeam diff --git a/itopapi/model/features/hasTeam.py b/itopapi/model/features/hasTeam.py new file mode 100644 index 0000000..8065b48 --- /dev/null +++ b/itopapi/model/features/hasTeam.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasTeam is a mixin representing the team attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasTeam(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'team_id', 'name': 'team_name', 'table': 'Team'} + + def __init__(self): + super(HasTeam, self).__init__() + + # Object's team id. Call find_team to get the full information or just use + # team_id_friendlyname and team_name + self.team_id = None + # Object's team id's friendly name. Not sure the difference with team_name + self.team_id_friendlyname = None + # Object's team name + self.team_name = None + + def find_team(self): + """ + Retrieve the ItopapiTeam related to this instance + """ + if self.team_id is not None: + return ItopapiPrototype.get_itop_class('Team').find(self.team_id) + return None + + def set_team(self, team): + """ + Set the ItopapiOrganization parameters + """ + self.team_id = team.instance_id + self.team_id_friendlyname = team.friendlyname + self.team_name = team.name diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index 986f16e..16f7056 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasTeam import HasTeam __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiIncident(ItopapiPrototype, HasOrganization): +class ItopapiIncident(ItopapiPrototype, HasOrganization, HasTeam): # Configuration specific to itop itop = { @@ -22,7 +23,7 @@ class ItopapiIncident(ItopapiPrototype, HasOrganization): 'foreign_keys': [ HasOrganization.foreign_key, {'id': 'agent_id', 'name': 'agent_name', 'table': 'Person'}, - {'id': 'team_id', 'name': 'team_name', 'table': 'Team'}, + HasTeam.foreign_key, ], 'list_types': { 'functionalcis_list': 'functionalci_id_finalclass_recall', @@ -62,10 +63,6 @@ def __init__(self, data=None): self.agent_id = None self.agent_name = None - self.team_id = None - self.team_id_friendlyname = None - self.team_name = None - ################################## # Lists # ################################## From 9ddb80258b15bd311f1367ee6e8f17a8ee0505db Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 22:59:10 +0100 Subject: [PATCH 093/104] Added HasAgent mixin and updated data model. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasAgent.py | 42 ++++++++++++++++++++++++++++++ itopapi/model/incident.py | 9 +++---- 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 itopapi/model/features/hasAgent.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 6220a2d..dc0e77b 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -26,3 +26,4 @@ from itopapi.model.features.hasSoftware import HasSoftware from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasTeam import HasTeam +from itopapi.model.features.hasAgent import HasAgent diff --git a/itopapi/model/features/hasAgent.py b/itopapi/model/features/hasAgent.py new file mode 100644 index 0000000..aae8d26 --- /dev/null +++ b/itopapi/model/features/hasAgent.py @@ -0,0 +1,42 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasAgent is a mixin representing the agent attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasAgent(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'agent_id', 'name': 'agent_name', 'table': 'Person'} + + def __init__(self): + super(HasAgent, self).__init__() + + # Object's agent id. Call find_agent to get the full information or just use agent_name + self.agent_id = None + # Object's agent name + self.agent_name = None + + def find_agent(self): + """ + Retrieve the ItopapiAgent related to this instance + """ + if self.agent_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.agent_id) + return None + + def set_agent(self, agent): + """ + Set the ItopapiOrganization parameters + """ + self.agent_id = agent.instance_id + self.agent_name = agent.name diff --git a/itopapi/model/incident.py b/itopapi/model/incident.py index 16f7056..9299529 100644 --- a/itopapi/model/incident.py +++ b/itopapi/model/incident.py @@ -7,12 +7,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasTeam import HasTeam +from itopapi.model.features.hasAgent import HasAgent __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiIncident(ItopapiPrototype, HasOrganization, HasTeam): +class ItopapiIncident(ItopapiPrototype, HasOrganization, HasTeam, HasAgent): # Configuration specific to itop itop = { @@ -22,7 +23,7 @@ class ItopapiIncident(ItopapiPrototype, HasOrganization, HasTeam): 'save': ['title', 'description', 'ref', 'start_date', 'end_date', 'close_date', 'last_update'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'agent_id', 'name': 'agent_name', 'table': 'Person'}, + HasAgent.foreign_key, HasTeam.foreign_key, ], 'list_types': { @@ -59,10 +60,6 @@ def __init__(self, data=None): self.close_date = None self.last_update = None - # Foreign key to a Person - self.agent_id = None - self.agent_name = None - ################################## # Lists # ################################## From dfcef95dfbd20eae6be978f748fa204690ea16d5 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 23:05:18 +0100 Subject: [PATCH 094/104] Fixed errors in the comments --- itopapi/model/features/hasAgent.py | 2 +- itopapi/model/features/hasBrand.py | 2 +- itopapi/model/features/hasDeliveryModel.py | 2 +- itopapi/model/features/hasEnclosure.py | 2 +- itopapi/model/features/hasFarm.py | 2 +- itopapi/model/features/hasLocation.py | 2 +- itopapi/model/features/hasModel.py | 2 +- itopapi/model/features/hasOSFamily.py | 2 +- itopapi/model/features/hasOSLicence.py | 2 +- itopapi/model/features/hasOSVersion.py | 2 +- itopapi/model/features/hasRack.py | 2 +- itopapi/model/features/hasServer.py | 2 +- itopapi/model/features/hasSoftware.py | 2 +- itopapi/model/features/hasSoftwareLicence.py | 2 +- itopapi/model/features/hasTeam.py | 2 +- itopapi/model/features/hasVirtualhost.py | 2 +- itopapi/model/features/hasWebServer.py | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/itopapi/model/features/hasAgent.py b/itopapi/model/features/hasAgent.py index aae8d26..03f8e98 100644 --- a/itopapi/model/features/hasAgent.py +++ b/itopapi/model/features/hasAgent.py @@ -36,7 +36,7 @@ def find_agent(self): def set_agent(self, agent): """ - Set the ItopapiOrganization parameters + Set the ItopapiPerson parameters """ self.agent_id = agent.instance_id self.agent_name = agent.name diff --git a/itopapi/model/features/hasBrand.py b/itopapi/model/features/hasBrand.py index 48a60d9..83df634 100644 --- a/itopapi/model/features/hasBrand.py +++ b/itopapi/model/features/hasBrand.py @@ -39,7 +39,7 @@ def find_brand(self): def set_brand(self, brand): """ - Set the ItopapiOrganization parameters + Set the ItopapiBrand parameters """ self.brand_id = brand.instance_id self.brand_id_friendlyname = brand.friendlyname diff --git a/itopapi/model/features/hasDeliveryModel.py b/itopapi/model/features/hasDeliveryModel.py index 7b104c2..af55ce3 100644 --- a/itopapi/model/features/hasDeliveryModel.py +++ b/itopapi/model/features/hasDeliveryModel.py @@ -39,7 +39,7 @@ def find_deliverymodel(self): def set_deliverymodel(self, deliverymodel): """ - Set the ItopapiOrganization parameters + Set the ItopapiDeliveryModel parameters """ self.deliverymodel_id = deliverymodel.instance_id self.deliverymodel_id_friendlyname = deliverymodel.friendlyname diff --git a/itopapi/model/features/hasEnclosure.py b/itopapi/model/features/hasEnclosure.py index 340d184..87192bc 100644 --- a/itopapi/model/features/hasEnclosure.py +++ b/itopapi/model/features/hasEnclosure.py @@ -39,7 +39,7 @@ def find_enclosure(self): def set_enclosure(self, enclosure): """ - Set the ItopapiOrganization parameters + Set the ItopapiEnclosure parameters """ self.enclosure_id = enclosure.instance_id self.enclosure_id_friendlyname = enclosure.friendlyname diff --git a/itopapi/model/features/hasFarm.py b/itopapi/model/features/hasFarm.py index a366f03..7019700 100644 --- a/itopapi/model/features/hasFarm.py +++ b/itopapi/model/features/hasFarm.py @@ -39,7 +39,7 @@ def find_farm(self): def set_farm(self, farm): """ - Set the ItopapiOrganization parameters + Set the ItopapiFarm parameters """ self.farm_id = farm.instance_id self.farm_id_friendlyname = farm.friendlyname diff --git a/itopapi/model/features/hasLocation.py b/itopapi/model/features/hasLocation.py index 8d1b11b..909d0db 100644 --- a/itopapi/model/features/hasLocation.py +++ b/itopapi/model/features/hasLocation.py @@ -39,7 +39,7 @@ def find_location(self): def set_location(self, location): """ - Set the ItopapiOrganization parameters + Set the ItopapiLocation parameters """ self.location_id = location.instance_id self.location_id_friendlyname = location.friendlyname diff --git a/itopapi/model/features/hasModel.py b/itopapi/model/features/hasModel.py index 117b93f..2443d0b 100644 --- a/itopapi/model/features/hasModel.py +++ b/itopapi/model/features/hasModel.py @@ -39,7 +39,7 @@ def find_model(self): def set_model(self, model): """ - Set the ItopapiOrganization parameters + Set the ItopapiModel parameters """ self.model_id = model.instance_id self.model_id_friendlyname = model.friendlyname diff --git a/itopapi/model/features/hasOSFamily.py b/itopapi/model/features/hasOSFamily.py index 8e420ff..7c21fda 100644 --- a/itopapi/model/features/hasOSFamily.py +++ b/itopapi/model/features/hasOSFamily.py @@ -39,7 +39,7 @@ def find_osfamily(self): def set_osfamily(self, osfamily): """ - Set the ItopapiOrganization parameters + Set the ItopapiFamily parameters """ self.osfamily_id = osfamily.instance_id self.osfamily_id_friendlyname = osfamily.friendlyname diff --git a/itopapi/model/features/hasOSLicence.py b/itopapi/model/features/hasOSLicence.py index 09ade7f..98380b5 100644 --- a/itopapi/model/features/hasOSLicence.py +++ b/itopapi/model/features/hasOSLicence.py @@ -39,7 +39,7 @@ def find_oslicence(self): def set_oslicence(self, oslicence): """ - Set the ItopapiOrganization parameters + Set the ItopapiOSlicence parameters """ self.oslicence_id = oslicence.instance_id self.oslicence_id_friendlyname = oslicence.friendlyname diff --git a/itopapi/model/features/hasOSVersion.py b/itopapi/model/features/hasOSVersion.py index 4a2a642..f7768d3 100644 --- a/itopapi/model/features/hasOSVersion.py +++ b/itopapi/model/features/hasOSVersion.py @@ -39,7 +39,7 @@ def find_osversion(self): def set_osversion(self, osversion): """ - Set the ItopapiOrganization parameters + Set the ItopapiOSVersion parameters """ self.osversion_id = osversion.instance_id self.osversion_id_friendlyname = osversion.friendlyname diff --git a/itopapi/model/features/hasRack.py b/itopapi/model/features/hasRack.py index bfc0a82..f32a53d 100644 --- a/itopapi/model/features/hasRack.py +++ b/itopapi/model/features/hasRack.py @@ -39,7 +39,7 @@ def find_rack(self): def set_rack(self, rack): """ - Set the ItopapiOrganization parameters + Set the ItopapiRack parameters """ self.rack_id = rack.instance_id self.rack_id_friendlyname = rack.friendlyname diff --git a/itopapi/model/features/hasServer.py b/itopapi/model/features/hasServer.py index e601fb1..540f8ac 100644 --- a/itopapi/model/features/hasServer.py +++ b/itopapi/model/features/hasServer.py @@ -39,7 +39,7 @@ def find_server(self): def set_server(self, server): """ - Set the ItopapiOrganization parameters + Set the ItopapiServer parameters """ self.server_id = server.instance_id self.server_id_friendlyname = server.friendlyname diff --git a/itopapi/model/features/hasSoftware.py b/itopapi/model/features/hasSoftware.py index f460a9a..8daef1e 100644 --- a/itopapi/model/features/hasSoftware.py +++ b/itopapi/model/features/hasSoftware.py @@ -39,7 +39,7 @@ def find_software(self): def set_software(self, software): """ - Set the ItopapiOrganization parameters + Set the ItopapiServer parameters """ self.software_id = software.instance_id self.software_id_friendlyname = software.friendlyname diff --git a/itopapi/model/features/hasSoftwareLicence.py b/itopapi/model/features/hasSoftwareLicence.py index 2519af6..7a23ae9 100644 --- a/itopapi/model/features/hasSoftwareLicence.py +++ b/itopapi/model/features/hasSoftwareLicence.py @@ -39,7 +39,7 @@ def find_softwarelicence(self): def set_softwarelicence(self, softwarelicence): """ - Set the ItopapiOrganization parameters + Set the ItopapiSoftwareLicence parameters """ self.softwarelicence_id = softwarelicence.instance_id self.softwarelicence_id_friendlyname = softwarelicence.friendlyname diff --git a/itopapi/model/features/hasTeam.py b/itopapi/model/features/hasTeam.py index 8065b48..4ce2244 100644 --- a/itopapi/model/features/hasTeam.py +++ b/itopapi/model/features/hasTeam.py @@ -39,7 +39,7 @@ def find_team(self): def set_team(self, team): """ - Set the ItopapiOrganization parameters + Set the ItopapiTeam parameters """ self.team_id = team.instance_id self.team_id_friendlyname = team.friendlyname diff --git a/itopapi/model/features/hasVirtualhost.py b/itopapi/model/features/hasVirtualhost.py index cfe2856..65b6f01 100644 --- a/itopapi/model/features/hasVirtualhost.py +++ b/itopapi/model/features/hasVirtualhost.py @@ -39,7 +39,7 @@ def find_virtualhost(self): def set_virtualhost(self, virtualhost): """ - Set the ItopapiOrganization parameters + Set the ItopapiVirtualHost parameters """ self.virtualhost_id = virtualhost.instance_id self.virtualhost_id_friendlyname = virtualhost.friendlyname diff --git a/itopapi/model/features/hasWebServer.py b/itopapi/model/features/hasWebServer.py index 5074120..aac972a 100644 --- a/itopapi/model/features/hasWebServer.py +++ b/itopapi/model/features/hasWebServer.py @@ -39,7 +39,7 @@ def find_webserver(self): def set_webserver(self, webserver): """ - Set the ItopapiOrganization parameters + Set the ItopapiWebServer parameters """ self.webserver_id = webserver.instance_id self.webserver_id_friendlyname = webserver.friendlyname From d853ddc98b6efa5bb6fb56d073b0881c46569de1 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sat, 30 Jan 2016 23:36:48 +0100 Subject: [PATCH 095/104] Added HasManager fixin and updated data model. Plus double checked fields within Person and found a few mistakes. --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasManager.py | 42 ++++++++++++++++++++++++++++ itopapi/model/person.py | 19 +++++-------- 3 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 itopapi/model/features/hasManager.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index dc0e77b..5eaee57 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -27,3 +27,4 @@ from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasTeam import HasTeam from itopapi.model.features.hasAgent import HasAgent +from itopapi.model.features.hasManager import HasManager diff --git a/itopapi/model/features/hasManager.py b/itopapi/model/features/hasManager.py new file mode 100644 index 0000000..928f5a8 --- /dev/null +++ b/itopapi/model/features/hasManager.py @@ -0,0 +1,42 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasManager is a mixin representing the manager attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasManager(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'manager_id', 'name': 'manager_name', 'table': 'Person'} + + def __init__(self): + super(HasManager, self).__init__() + + # Object's manager id. Call find_manager to get the full information or just use manager_name + self.manager_id = None + # Object's manager name + self.manager_name = None + + def find_manager(self): + """ + Retrieve the ItopapiManager related to this instance + """ + if self.manager_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.manager_id) + return None + + def set_manager(self, manager): + """ + Set the ItopapiPerson parameters + """ + self.manager_id = manager.instance_id + self.manager_name = manager.name diff --git a/itopapi/model/person.py b/itopapi/model/person.py index c201f34..5a4b2ef 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -8,12 +8,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasManager import HasManager __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPerson(ItopapiPrototype, HasOrganization, HasLocation): +class ItopapiPerson(ItopapiPrototype, HasOrganization, HasLocation, HasManager): # Configuration specific to itop itop = { @@ -25,7 +26,7 @@ class ItopapiPerson(ItopapiPrototype, HasOrganization, HasLocation): 'foreign_keys': [ HasOrganization.foreign_key, HasLocation.foreign_key, - {'id': 'manager_id', 'name': 'manager_name', 'table': 'Person'}, + HasManager.foreign_key, ], 'list_types': { 'team_list': 'Team', @@ -52,27 +53,21 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiPerson, self).__init__(data) + ################################## # Properties # ################################## - self.contact_id = None - self.contact_name = None - self.manager_id = None, - self.manager_id_friendlyname = None, - self.manager_name = None, - self.function = None self.first_name = None + self.function = None self.email = None self.mobile_phone = None self.phone = None - self.organization_name = None self.notify = None self.employee_number = None - self.organization_name = None self.status = None ################################## # Lists # ################################## self.tickets_list = None - self.tickets_list = None - self.tickets_list = None + self.cis_list = None + self.team_list = None From 17db42e89f0936bbcdecfe90b6dda16c37792b28 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sun, 31 Jan 2016 11:58:21 +0100 Subject: [PATCH 096/104] Now find() is able to search for generic classes (first use case in next commit) --- itopapi/model/prototype.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index f0c1d46..551b8d2 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -144,7 +144,15 @@ def find(itop_class, key): objects = [] for information in data['objects']: - obj = itop_class({}) + # If the class is provided in the returned object, use it, else ise itop_class + # Sometimes itop_class is a generic type (e.g. Contact) and instances are a specific class (e.g. Person) + object_class = itop_class + try: + object_class = ItopapiPrototype.get_itop_class(data['objects'][information]['class']) + except UnknownItopClass as e: + pass + # TODO find the proper object class if any + obj = object_class({}) obj.instance_id = data['objects'][information]['key'] # update all the object's fields with the following line obj.__dict__.update(data['objects'][information]['fields']) From 57428f1428283d52e490447fb371239c79cb4644 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Sun, 31 Jan 2016 23:05:35 +0100 Subject: [PATCH 097/104] Worked on the inheritance model and added a lot of new classes --- itopapi/model/FunctionalCI.py | 43 +++++++++++++ itopapi/model/__init__.py | 80 ++++++++++++++++++----- itopapi/model/applicationSolution.py | 13 ++-- itopapi/model/brand.py | 8 ++- itopapi/model/businessProcess.py | 77 +++++++++++++++++++++++ itopapi/model/connectableCI.py | 47 ++++++++++++++ itopapi/model/contact.py | 43 +++++++++++++ itopapi/model/databaseSchema.py | 76 ++++++++++++++++++++++ itopapi/model/datacenterDevice.py | 47 ++++++++++++++ itopapi/model/dbserver.py | 8 ++- itopapi/model/farm.py | 9 ++- itopapi/model/features/__init__.py | 2 + itopapi/model/features/hasAgent.py | 3 + itopapi/model/features/hasDBServer.py | 46 ++++++++++++++ itopapi/model/features/hasManager.py | 3 + itopapi/model/features/hasMiddleware.py | 46 ++++++++++++++ itopapi/model/hypervisor.py | 7 ++- itopapi/model/licence.py | 42 +++++++++++++ itopapi/model/middleware.py | 84 +++++++++++++++++++++++++ itopapi/model/middlewareInstance.py | 76 ++++++++++++++++++++++ itopapi/model/model.py | 9 ++- itopapi/model/osFamily.py | 7 ++- itopapi/model/osLicence.py | 7 ++- itopapi/model/osVersion.py | 6 +- itopapi/model/othersoftware.py | 8 ++- itopapi/model/pcsoftware.py | 83 ++++++++++++++++++++++++ itopapi/model/person.py | 10 ++- itopapi/model/physicalDevice.py | 47 ++++++++++++++ itopapi/model/prototype.py | 1 - itopapi/model/rack.py | 6 +- itopapi/model/server.py | 6 +- itopapi/model/softwareInstance.py | 46 ++++++++++++++ itopapi/model/softwareLicence.py | 63 +++++++++++++++++++ itopapi/model/team.py | 7 ++- itopapi/model/typology.py | 42 +++++++++++++ itopapi/model/virtualDevice.py | 47 ++++++++++++++ itopapi/model/virtualHost.py | 48 ++++++++++++++ itopapi/model/virtualMachine.py | 9 ++- itopapi/model/webApplication.py | 10 ++- itopapi/model/webServer.py | 9 ++- 40 files changed, 1183 insertions(+), 48 deletions(-) create mode 100644 itopapi/model/FunctionalCI.py create mode 100644 itopapi/model/businessProcess.py create mode 100644 itopapi/model/connectableCI.py create mode 100644 itopapi/model/contact.py create mode 100644 itopapi/model/databaseSchema.py create mode 100644 itopapi/model/datacenterDevice.py create mode 100644 itopapi/model/features/hasDBServer.py create mode 100644 itopapi/model/features/hasMiddleware.py create mode 100644 itopapi/model/licence.py create mode 100644 itopapi/model/middleware.py create mode 100644 itopapi/model/middlewareInstance.py create mode 100644 itopapi/model/pcsoftware.py create mode 100644 itopapi/model/physicalDevice.py create mode 100644 itopapi/model/softwareInstance.py create mode 100644 itopapi/model/softwareLicence.py create mode 100644 itopapi/model/typology.py create mode 100644 itopapi/model/virtualDevice.py create mode 100644 itopapi/model/virtualHost.py diff --git a/itopapi/model/FunctionalCI.py b/itopapi/model/FunctionalCI.py new file mode 100644 index 0000000..6b3afb0 --- /dev/null +++ b/itopapi/model/FunctionalCI.py @@ -0,0 +1,43 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiFunctionalCI is an abstraction of Functional CI representation on iTop +It serves as a base class for a lot of subclasses. +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiFunctionalCI(ItopapiPrototype): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'FunctionalCI', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Functional CI with the given key or criteria """ + return ItopapiPrototype.find(ItopapiFunctionalCI, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiFunctionalCI, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Functional CI """ + return ItopapiPrototype.find_all(ItopapiFunctionalCI) + + """ + ItopapiFunctionalCI is an object that represents a Functional CI from iTop + """ + def __init__(self, data=None): + super(ItopapiFunctionalCI, self).__init__(data) diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 9ce0964..ec630a5 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -8,32 +8,78 @@ __authors__ = ['Guillaume Philippon ', 'Julien Nauroy '] from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.organization import ItopapiOrganization +from itopapi.model.location import ItopapiLocation +from itopapi.model.contact import ItopapiContact +from itopapi.model.person import ItopapiPerson +from itopapi.model.team import ItopapiTeam +from itopapi.model.functionalCI import ItopapiFunctionalCI +from itopapi.model.physicalDevice import ItopapiPhysicalDevice from itopapi.model.rack import ItopapiRack +from itopapi.model.connectableCI import ItopapiConnectableCI +from itopapi.model.datacenterDevice import ItopapiDatacenterDevice from itopapi.model.server import ItopapiServer +from itopapi.model.applicationSolution import ItopapiApplicationSolution +from itopapi.model.businessProcess import ItopapiBusinessProcess +from itopapi.model.softwareInstance import ItopapiSoftwareInstance +from itopapi.model.dbserver import ItopapiDBServer +from itopapi.model.webServer import ItopapiWebServer +from itopapi.model.pcSoftware import ItopapiPCSoftware +from itopapi.model.middleware import ItopapiMiddleware +from itopapi.model.otherSoftware import ItopapiOtherSoftware +from itopapi.model.middlewareInstance import ItopapiMiddlewareInstance +from itopapi.model.databaseSchema import ItopapiDatabaseSchema +from itopapi.model.webServer import ItopapiWebServer +from itopapi.model.webApplication import ItopapiWebApplication +from itopapi.model.virtualDevice import ItopapiVirtualDevice +from itopapi.model.virtualMachine import ItopapiVirtualMachine +from itopapi.model.virtualHost import ItopapiVirtualHost +from itopapi.model.hypervisor import ItopapiHypervisor +from itopapi.model.farm import ItopapiFarm +from itopapi.model.licence import ItopapiLicence +from itopapi.model.osLicence import ItopapiOSLicence +from itopapi.model.softwareLicence import ItopapiSoftwareLicence +from itopapi.model.typology import ItopapiTypology from itopapi.model.osFamily import ItopapiOSFamily from itopapi.model.osVersion import ItopapiOSVersion -from itopapi.model.osLicence import ItopapiOSLicence +from itopapi.model.brand import ItopapiBrand +from itopapi.model.model import ItopapiModel + + +# TODO Check inheritance from itopapi.model.powerSource import ItopapiPowerSource from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.physicalInterface import ItopapiPhysicalInterface -from itopapi.model.hypervisor import ItopapiHypervisor -from itopapi.model.farm import ItopapiFarm -from itopapi.model.virtualMachine import ItopapiVirtualMachine -from itopapi.model.webServer import ItopapiWebServer -from itopapi.model.webApplication import ItopapiWebApplication from itopapi.model.service import ItopapiService -from itopapi.model.organization import ItopapiOrganization -from itopapi.model.location import ItopapiLocation from itopapi.model.enclosure import ItopapiEnclosure -from itopapi.model.brand import ItopapiBrand -from itopapi.model.model import ItopapiModel -from itopapi.model.applicationSolution import ItopapiApplicationSolution -from itopapi.model.person import ItopapiPerson -from itopapi.model.team import ItopapiTeam from itopapi.model.incident import ItopapiIncident -from itopapi.model.othersoftware import ItopapiOtherSoftware -from itopapi.model.dbserver import ItopapiDBServer -# TODO partial list of missing classes, with no particular order: Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, -# Tablet, TapeLibrary, SANSwitchNAS, PDU, DatabaseSchema, OtherSoftware +# TODO partial list of missing classes, with no particular order and along with their inheritance hierarchy : +# Document +# DocumentFile +# DocumentNote +# DocumentWeb +# DatacenterDevice (defined) +# NetworkDevice +# StorageSystem +# SANSwitch +# TapeLibrary +# NAS +# ConnectableCI (defined) +# Enclosure +# PowerConnection +# PowerSource +# PDU +# Patch +# OSPatch +# SoftwarePatch +# Typology (defined +# DocumentType +# ContactType +# NetworkDeviceType +# IOSVersion +# ContractType + +# Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, +# Tablet, TapeLibrary, SANSwitchNAS, PDU, DatabaseSchema diff --git a/itopapi/model/applicationSolution.py b/itopapi/model/applicationSolution.py index cd45fac..07c975a 100644 --- a/itopapi/model/applicationSolution.py +++ b/itopapi/model/applicationSolution.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI from itopapi.model.features.hasOrganization import HasOrganization @@ -12,17 +13,14 @@ __authors__ = ['Julien Nauroy '] -class ItopapiApplicationSolution(ItopapiPrototype, HasOrganization): - """ - TODO not completed and tested yet, created as a dependency of TiopapiRack. Probably missing redundancy - """ +class ItopapiApplicationSolution(ItopapiFunctionalCI, HasOrganization): # Configuration specific to itop itop = { # Name of the class in Itop 'name': 'ApplicationSolution', # Define which fields to save when creating or updating from the python API - 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], + 'save': ['name', 'status', 'business_criticity', 'move2production', 'description', 'redundancy'], 'foreign_keys': [ HasOrganization.foreign_key, ], @@ -62,6 +60,7 @@ def __init__(self, data=None): self.move2production = None # Application Solution's description, as a free text self.description = None + self.redundancy = None ################################## # Lists # ################################## @@ -74,3 +73,7 @@ def __init__(self, data=None): self.services_list = None self.contacts_list = None self.providercontracts_list = None + + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiApplicationSolution) diff --git a/itopapi/model/brand.py b/itopapi/model/brand.py index d3bc386..96422a2 100644 --- a/itopapi/model/brand.py +++ b/itopapi/model/brand.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiBrand(ItopapiPrototype): +class ItopapiBrand(ItopapiTypology): # Configuration specific to itop itop = { @@ -40,5 +41,10 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiBrand, self).__init__(data) + # Physical devices using this brand self.physicaldevices_list = None + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiBrand) diff --git a/itopapi/model/businessProcess.py b/itopapi/model/businessProcess.py new file mode 100644 index 0000000..d0def04 --- /dev/null +++ b/itopapi/model/businessProcess.py @@ -0,0 +1,77 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiBusinessProcess is an abstraction of Business Process representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI +from itopapi.model.features.hasOrganization import HasOrganization + + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiBusinessProcess(ItopapiFunctionalCI, HasOrganization): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'BusinessProcess', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'move2production', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of BusinessProcess with the given key or criteria """ + return ItopapiPrototype.find(ItopapiBusinessProcess, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiBusinessProcess, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of BusinessProcess """ + return ItopapiPrototype.find_all(ItopapiBusinessProcess) + + """ + ItopapiBusinessProcess is an object that represents an Business Process from iTop + """ + def __init__(self, data=None): + super(ItopapiBusinessProcess, self).__init__(data) + ################################## + # Properties # + ################################## + # Business Process's status. Values within [inactive, active] + self.status = None + # Business Process's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Business Process's move to production date + self.move2production = None + # Business Process's description, as a free text + self.description = None + ################################## + # Lists # + ################################## + # One with an s, one without. Because why not? + self.applicationsolution_list = None + self.applicationsolutions_list = None + self.documents_list = None + self.softwares_list = None + self.tickets_list = None + self.services_list = None + self.contacts_list = None + self.providercontracts_list = None + + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiBusinessProcess) diff --git a/itopapi/model/connectableCI.py b/itopapi/model/connectableCI.py new file mode 100644 index 0000000..f4770e5 --- /dev/null +++ b/itopapi/model/connectableCI.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiConnectableCI is an abstraction of Connectable CI representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.physicalDevice import ItopapiPhysicalDevice + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiConnectableCI(ItopapiPhysicalDevice): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'ConnectableCI', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Connectable CI with the given key or criteria """ + return ItopapiPrototype.find(ItopapiConnectableCI, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiConnectableCI, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Connectable CI """ + return ItopapiPrototype.find_all(ItopapiConnectableCI) + + """ + ItopapiConnectableCI is an object that represents a Connectable CI from iTop + """ + def __init__(self, data=None): + super(ItopapiConnectableCI, self).__init__(data) + + +# Register as a subclass of PhysicalDevice +ItopapiPhysicalDevice.register(ItopapiConnectableCI) \ No newline at end of file diff --git a/itopapi/model/contact.py b/itopapi/model/contact.py new file mode 100644 index 0000000..54acff7 --- /dev/null +++ b/itopapi/model/contact.py @@ -0,0 +1,43 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiContact is an abstraction of Contact representation on iTop +It serves as a base class for Person and Team +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiContact(ItopapiPrototype): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'Contact', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Contact with the given key or criteria """ + return ItopapiPrototype.find(ItopapiContact, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiContact, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Contact """ + return ItopapiPrototype.find_all(ItopapiContact) + + """ + ItopapiContact is an object that represents a Contact from iTop + """ + def __init__(self, data=None): + super(ItopapiContact, self).__init__(data) diff --git a/itopapi/model/databaseSchema.py b/itopapi/model/databaseSchema.py new file mode 100644 index 0000000..ac228c2 --- /dev/null +++ b/itopapi/model/databaseSchema.py @@ -0,0 +1,76 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiDatabaseSchema is an abstraction of Database Schema representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasDBServer import HasDBServer + + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiDatabaseSchema(ItopapiFunctionalCI, HasOrganization, HasDBServer): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'DatabaseSchema', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'business_criticity', 'move2production', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasDBServer.foreign_key, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of DatabaseSchema with the given key or criteria """ + return ItopapiPrototype.find(ItopapiDatabaseSchema, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiDatabaseSchema, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of DatabaseSchema """ + return ItopapiPrototype.find_all(ItopapiDatabaseSchema) + + """ + ItopapiDatabaseSchema is an object that represents an Database Schema from iTop + """ + def __init__(self, data=None): + super(ItopapiDatabaseSchema, self).__init__(data) + ################################## + # Properties # + ################################## + # Database Schema's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Database Schema's move to production date + self.move2production = None + # Database Schema's description, as a free text + self.description = None + ################################## + # Lists # + ################################## + # One with an s, one without. Because why not? + self.applicationsolution_list = None + self.documents_list = None + self.softwares_list = None + self.tickets_list = None + self.services_list = None + self.contacts_list = None + self.providercontracts_list = None + + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiDatabaseSchema) diff --git a/itopapi/model/datacenterDevice.py b/itopapi/model/datacenterDevice.py new file mode 100644 index 0000000..77d7686 --- /dev/null +++ b/itopapi/model/datacenterDevice.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiDatacenterDevice is an abstraction of Datacenter Device representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.connectableCI import ItopapiConnectableCI + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiDatacenterDevice(ItopapiConnectableCI): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'DatacenterDevice', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Datacenter Device with the given key or criteria """ + return ItopapiPrototype.find(ItopapiDatacenterDevice, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiDatacenterDevice, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Datacenter Device """ + return ItopapiPrototype.find_all(ItopapiDatacenterDevice) + + """ + ItopapiDatacenterDevice is an object that represents a Datacenter Device from iTop + """ + def __init__(self, data=None): + super(ItopapiDatacenterDevice, self).__init__(data) + + +# Register as a subclass of ConnectableCI +ItopapiConnectableCI.register(ItopapiDatacenterDevice) \ No newline at end of file diff --git a/itopapi/model/dbserver.py b/itopapi/model/dbserver.py index fbb9597..9f395aa 100644 --- a/itopapi/model/dbserver.py +++ b/itopapi/model/dbserver.py @@ -5,7 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype -from itopapi.model.othersoftware import ItopapiOtherSoftware +from itopapi.model.softwareInstance import ItopapiSoftwareInstance from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftware import HasSoftware from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence @@ -14,7 +14,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiDBServer(ItopapiOtherSoftware, HasOrganization): +class ItopapiDBServer(ItopapiSoftwareInstance, HasOrganization): """ ItopapiDBServer is an object that represents a DBServer from iTop It has the same attributes as ItopapiOtherSoftware @@ -52,3 +52,7 @@ def find_all(): def __init__(self, data=None): super(ItopapiDBServer, self).__init__(data) + + +# Register as a subclass of SoftwareInstance +ItopapiSoftwareInstance.register(ItopapiDBServer) diff --git a/itopapi/model/farm.py b/itopapi/model/farm.py index 6a5b1c5..dce0a58 100644 --- a/itopapi/model/farm.py +++ b/itopapi/model/farm.py @@ -5,13 +5,14 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.virtualHost import ItopapiVirtualHost from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiFarm(ItopapiPrototype, HasOrganization): +class ItopapiFarm(ItopapiVirtualHost, HasOrganization): # Configuration specific to itop itop = { @@ -64,4 +65,8 @@ def __init__(self, data=None): self.services_list = None self.logicalvolumes_list = None self.hypervisor_list = None - self.virtualmachine_list = None \ No newline at end of file + self.virtualmachine_list = None + + +# Register as a subclass of VirtualHost +ItopapiVirtualHost.register(ItopapiFarm) diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 5eaee57..16a88d4 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -28,3 +28,5 @@ from itopapi.model.features.hasTeam import HasTeam from itopapi.model.features.hasAgent import HasAgent from itopapi.model.features.hasManager import HasManager +from itopapi.model.features.hasMiddleware import HasMiddleware +from itopapi.model.features.hasDBServer import HasDBServer diff --git a/itopapi/model/features/hasAgent.py b/itopapi/model/features/hasAgent.py index 03f8e98..10e480c 100644 --- a/itopapi/model/features/hasAgent.py +++ b/itopapi/model/features/hasAgent.py @@ -23,6 +23,8 @@ def __init__(self): # Object's agent id. Call find_agent to get the full information or just use agent_name self.agent_id = None + # Object's agent id's friendly name. Not sure the difference with agent_name + self.agent_id_friendlyname = None # Object's agent name self.agent_name = None @@ -39,4 +41,5 @@ def set_agent(self, agent): Set the ItopapiPerson parameters """ self.agent_id = agent.instance_id + self.agent_id_friendlyname = agent.friendlyname self.agent_name = agent.name diff --git a/itopapi/model/features/hasDBServer.py b/itopapi/model/features/hasDBServer.py new file mode 100644 index 0000000..cf2941d --- /dev/null +++ b/itopapi/model/features/hasDBServer.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasDBServer is a mixin representing the dbserver attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasDBServer(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'dbserver_id', 'name': 'dbserver_name', 'table': 'DBServer'} + + def __init__(self): + super(HasDBServer, self).__init__() + + # Object's dbserver id. Call find_dbserver to get the full information or just use + # dbserver_id_friendlyname and dbserver_name + self.dbserver_id = None + # Object's dbserver id's friendly name. Not sure the difference with dbserver_name + self.dbserver_id_friendlyname = None + # Object's dbserver name + self.dbserver_name = None + + def find_dbserver(self): + """ + Retrieve the ItopapiDBServer related to this instance + """ + if self.dbserver_id is not None: + return ItopapiPrototype.get_itop_class('DBServer').find(self.dbserver_id) + return None + + def set_dbserver(self, dbserver): + """ + Set the ItopapiDBServer parameters + """ + self.dbserver_id = dbserver.instance_id + self.dbserver_id_friendlyname = dbserver.friendlyname + self.dbserver_name = dbserver.name diff --git a/itopapi/model/features/hasManager.py b/itopapi/model/features/hasManager.py index 928f5a8..fe7342e 100644 --- a/itopapi/model/features/hasManager.py +++ b/itopapi/model/features/hasManager.py @@ -23,6 +23,8 @@ def __init__(self): # Object's manager id. Call find_manager to get the full information or just use manager_name self.manager_id = None + # Object's manager id's friendly name. Not sure the difference with manager_name + self.manager_id_friendlyname = None # Object's manager name self.manager_name = None @@ -39,4 +41,5 @@ def set_manager(self, manager): Set the ItopapiPerson parameters """ self.manager_id = manager.instance_id + self.manager_id_friendlyname = manager.friendlyname self.manager_name = manager.name diff --git a/itopapi/model/features/hasMiddleware.py b/itopapi/model/features/hasMiddleware.py new file mode 100644 index 0000000..923d089 --- /dev/null +++ b/itopapi/model/features/hasMiddleware.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasMiddleware is a mixin representing the middleware attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasMiddleware(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'middleware_id', 'name': 'middleware_name', 'table': 'Middleware'} + + def __init__(self): + super(HasMiddleware, self).__init__() + + # Object's middleware id. Call find_middleware to get the full information or just use + # middleware_id_friendlyname and middleware_name + self.middleware_id = None + # Object's middleware id's friendly name. Not sure the difference with middleware_name + self.middleware_id_friendlyname = None + # Object's middleware name + self.middleware_name = None + + def find_middleware(self): + """ + Retrieve the ItopapiMiddleware related to this instance + """ + if self.middleware_id is not None: + return ItopapiPrototype.get_itop_class('Middleware').find(self.middleware_id) + return None + + def set_middleware(self, middleware): + """ + Set the ItopapiMiddleware parameters + """ + self.middleware_id = middleware.instance_id + self.middleware_id_friendlyname = middleware.friendlyname + self.middleware_name = middleware.name diff --git a/itopapi/model/hypervisor.py b/itopapi/model/hypervisor.py index ad32749..8f8b9fa 100644 --- a/itopapi/model/hypervisor.py +++ b/itopapi/model/hypervisor.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.virtualHost import ItopapiVirtualHost from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasServer import HasServer from itopapi.model.features.hasFarm import HasFarm @@ -13,7 +14,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiHypervisor(ItopapiPrototype, HasOrganization, HasFarm): +class ItopapiHypervisor(ItopapiVirtualHost, HasOrganization, HasFarm): # Configuration specific to itop itop = { @@ -69,3 +70,7 @@ def __init__(self, data=None): self.documents_list = None self.contacts_list = None self.logicalvolumes_list = None + + +# Register as a subclass of VirtualHost +ItopapiVirtualHost.register(ItopapiHypervisor) diff --git a/itopapi/model/licence.py b/itopapi/model/licence.py new file mode 100644 index 0000000..a9c0949 --- /dev/null +++ b/itopapi/model/licence.py @@ -0,0 +1,42 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiLicence is an abstraction of Licence representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiLicence(ItopapiPrototype): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'Licence', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Licence with the given key or criteria """ + return ItopapiPrototype.find(ItopapiLicence, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiLicence, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Licence """ + return ItopapiPrototype.find_all(ItopapiLicence) + + """ + ItopapiLicence is an object that represents a Licence from iTop + """ + def __init__(self, data=None): + super(ItopapiLicence, self).__init__(data) diff --git a/itopapi/model/middleware.py b/itopapi/model/middleware.py new file mode 100644 index 0000000..ea18a94 --- /dev/null +++ b/itopapi/model/middleware.py @@ -0,0 +1,84 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +ItopapiMiddleware is an abstraction of Middleware representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.softwareInstance import ItopapiSoftwareInstance +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence +from itopapi.model.features.hasSoftware import HasSoftware + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiMiddleware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware): + """ + ItopapiMiddleware is an object that represents a Middleware from iTop + """ + + """ Configuration specific to itop """ + itop = { + # Name of the class in Itop + 'name': 'Middleware', + # Define which fields to save when creating or updating from the python API + 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasSoftware.foreign_key, + HasSoftwareLicence.foreign_key, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Middleware with the given key or criteria """ + return ItopapiPrototype.find(ItopapiMiddleware, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiMiddleware, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Rack """ + return ItopapiPrototype.find_all(ItopapiMiddleware) + + def __init__(self, data=None): + super(ItopapiMiddleware, self).__init__(data) + + ################################## + # Properties # + ################################## + # Middleware's status. Values within [implementation, obsolete, production, stock] + self.status = None + # Middleware's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Middleware's path ? + self.path = None + # Middleware's description, as a free text + self.description = None + # Middleware's move to production date + self.move2production = None + + ################################## + # Lists # + ################################## + self.documents_list = {} + self.softwares_list = {} + self.tickets_list = {} + self.services_list = {} + self.contacts_list = {} + self.providercontracts_list = {} + self.applicationsolution_list = {} + self.middlewareinstance_list = {} + + +# Register as a subclass of SoftwareInstance +ItopapiSoftwareInstance.register(ItopapiMiddleware) + diff --git a/itopapi/model/middlewareInstance.py b/itopapi/model/middlewareInstance.py new file mode 100644 index 0000000..a48b9af --- /dev/null +++ b/itopapi/model/middlewareInstance.py @@ -0,0 +1,76 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiMiddlewareInstance is an abstraction of Middleware Instance representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasMiddleware import HasMiddleware + + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiMiddlewareInstance(ItopapiFunctionalCI, HasOrganization, HasMiddleware): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'MiddlewareInstance', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'business_criticity', 'move2production', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasMiddleware.foreign_key, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of MiddlewareInstance with the given key or criteria """ + return ItopapiPrototype.find(ItopapiMiddlewareInstance, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiMiddlewareInstance, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of MiddlewareInstance """ + return ItopapiPrototype.find_all(ItopapiMiddlewareInstance) + + """ + ItopapiMiddlewareInstance is an object that represents an Middleware Instance from iTop + """ + def __init__(self, data=None): + super(ItopapiMiddlewareInstance, self).__init__(data) + ################################## + # Properties # + ################################## + # Middleware Instance's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Middleware Instance's move to production date + self.move2production = None + # Middleware Instance's description, as a free text + self.description = None + ################################## + # Lists # + ################################## + # One with an s, one without. Because why not? + self.applicationsolution_list = None + self.documents_list = None + self.softwares_list = None + self.tickets_list = None + self.services_list = None + self.contacts_list = None + self.providercontracts_list = None + + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiMiddlewareInstance) diff --git a/itopapi/model/model.py b/itopapi/model/model.py index 2c14c5b..220c601 100644 --- a/itopapi/model/model.py +++ b/itopapi/model/model.py @@ -5,13 +5,14 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology from itopapi.model.features.hasBrand import HasBrand __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiModel(ItopapiPrototype, HasBrand): +class ItopapiModel(ItopapiTypology, HasBrand): # Configuration specific to itop itop = { @@ -48,4 +49,8 @@ def __init__(self, data=None): # Type of item the Model refers to. Values are within # [DiskArray, Enclosure, IPPhone, MobilePhone, NAS, NetworkDevice, PC, PDU, Peripheral, Phone, # PowerSource, Printer, Rack, SANSwitch, Server, StorageSystem, Tablet, TapeLibrary] - self.type = None \ No newline at end of file + self.type = None + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiModel) diff --git a/itopapi/model/osFamily.py b/itopapi/model/osFamily.py index a7533d5..0dc8a1c 100644 --- a/itopapi/model/osFamily.py +++ b/itopapi/model/osFamily.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOSFamily(ItopapiPrototype): +class ItopapiOSFamily(ItopapiTypology): # Configuration specific to itop itop = { @@ -40,3 +41,7 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiOSFamily, self).__init__(data) + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiOSFamily) diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py index 47bc053..5cf8e44 100644 --- a/itopapi/model/osLicence.py +++ b/itopapi/model/osLicence.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.licence import ItopapiLicence from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasOSVersion import HasOSVersion @@ -12,7 +13,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiOSLicence(ItopapiPrototype, HasOrganization, HasOSVersion): +class ItopapiOSLicence(ItopapiLicence, HasOrganization, HasOSVersion): # Configuration specific to itop itop = { @@ -57,3 +58,7 @@ def __init__(self, data=None): self.documents_list = [] self.servers_list = [] self.virtualmachines_list = [] + + +# Register as a subclass of FunctionalCI +ItopapiLicence.register(ItopapiOSLicence) diff --git a/itopapi/model/osVersion.py b/itopapi/model/osVersion.py index 2c8f6a6..0e98dce 100644 --- a/itopapi/model/osVersion.py +++ b/itopapi/model/osVersion.py @@ -5,13 +5,14 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology from itopapi.model.features.hasOSFamily import HasOSFamily __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOSVersion(ItopapiPrototype, HasOSFamily): +class ItopapiOSVersion(ItopapiTypology, HasOSFamily): # Configuration specific to itop itop = { @@ -44,3 +45,6 @@ def find_all(): def __init__(self, data=None): super(ItopapiOSVersion, self).__init__(data) + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiOSVersion) diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index b5d1570..fb3f8fa 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.softwareInstance import ItopapiSoftwareInstance from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasSoftware import HasSoftware @@ -13,7 +14,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiOtherSoftware(ItopapiPrototype, HasOrganization, HasSoftwareLicence, HasSoftware): +class ItopapiOtherSoftware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware): """ ItopapiOtherSoftware is an object that represents a OtherSoftware from iTop """ @@ -75,3 +76,8 @@ def __init__(self, data=None): self.contacts_list = {} self.providercontracts_list = {} self.applicationsolution_list = {} + + +# Register as a subclass of SoftwareInstance +ItopapiSoftwareInstance.register(ItopapiOtherSoftware) + diff --git a/itopapi/model/pcsoftware.py b/itopapi/model/pcsoftware.py new file mode 100644 index 0000000..2819c76 --- /dev/null +++ b/itopapi/model/pcsoftware.py @@ -0,0 +1,83 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +ItopapiPCSoftware is an abstraction of PCSoftware representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.softwareInstance import ItopapiSoftwareInstance +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence +from itopapi.model.features.hasSoftware import HasSoftware + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiPCSoftware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware): + """ + ItopapiPCSoftware is an object that represents a PCSoftware from iTop + """ + + """ Configuration specific to itop """ + itop = { + # Name of the class in Itop + 'name': 'PCSoftware', + # Define which fields to save when creating or updating from the python API + 'save': ['move2production', 'description', 'status', 'name', 'business_criticity', 'path'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasSoftware.foreign_key, + HasSoftwareLicence.foreign_key, + ], + 'list_types': { + 'contacts_list': 'contact_id_finalclass_recall' + }, + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of PCSoftware with the given key or criteria """ + return ItopapiPrototype.find(ItopapiPCSoftware, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiPCSoftware, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Rack """ + return ItopapiPrototype.find_all(ItopapiPCSoftware) + + def __init__(self, data=None): + super(ItopapiPCSoftware, self).__init__(data) + + ################################## + # Properties # + ################################## + # PCSoftware's status. Values within [implementation, obsolete, production, stock] + self.status = None + # PCSoftware's business criticity. Values within [high, medium, low] + self.business_criticity = None + # PCSoftware's path ? + self.path = None + # PCSoftware's description, as a free text + self.description = None + # PCSoftware's move to production date + self.move2production = None + + ################################## + # Lists # + ################################## + self.documents_list = {} + self.softwares_list = {} + self.tickets_list = {} + self.services_list = {} + self.contacts_list = {} + self.providercontracts_list = {} + self.applicationsolution_list = {} + + +# Register as a subclass of SoftwareInstance +ItopapiSoftwareInstance.register(ItopapiPCSoftware) + diff --git a/itopapi/model/person.py b/itopapi/model/person.py index 5a4b2ef..c2da9d0 100644 --- a/itopapi/model/person.py +++ b/itopapi/model/person.py @@ -2,10 +2,11 @@ """ ItopapiPerson is an abstraction of a Person representation on iTop -Note : Person has no finalclass and name. It complicates things... +It inherits from ItopapiContact """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.contact import ItopapiContact from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasManager import HasManager @@ -14,14 +15,14 @@ __authors__ = ['Julien Nauroy '] -class ItopapiPerson(ItopapiPrototype, HasOrganization, HasLocation, HasManager): +class ItopapiPerson(ItopapiContact, HasOrganization, HasLocation, HasManager): # Configuration specific to itop itop = { # Name of the class in Itop 'name': 'Person', # Define which fields to save when creating or updating from the python API - 'save': ['contact_id', 'contact_name', 'function', 'first_name', 'name', + 'save': ['name', 'contact_id', 'contact_name', 'function', 'first_name', 'email', 'mobile_phone', 'phone', 'notify', 'employee_number', 'status'], 'foreign_keys': [ HasOrganization.foreign_key, @@ -71,3 +72,6 @@ def __init__(self, data=None): self.tickets_list = None self.cis_list = None self.team_list = None + +# Register as a subclass of Contact +ItopapiContact.register(ItopapiPerson) diff --git a/itopapi/model/physicalDevice.py b/itopapi/model/physicalDevice.py new file mode 100644 index 0000000..7e06ce8 --- /dev/null +++ b/itopapi/model/physicalDevice.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiPhysicalDevice is an abstraction of Physical Device representation on iTop +It serves as a base class for Racks Servers and much more. +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiPhysicalDevice(ItopapiFunctionalCI): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'PhysicalDevice', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Physical Device with the given key or criteria """ + return ItopapiPrototype.find(ItopapiPhysicalDevice, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiPhysicalDevice, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Physical Device """ + return ItopapiPrototype.find_all(ItopapiPhysicalDevice) + + """ + ItopapiPhysicalDevice is an object that represents a Physical Device from iTop + """ + def __init__(self, data=None): + super(ItopapiPhysicalDevice, self).__init__(data) + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiPhysicalDevice) diff --git a/itopapi/model/prototype.py b/itopapi/model/prototype.py index 551b8d2..ab79dd9 100644 --- a/itopapi/model/prototype.py +++ b/itopapi/model/prototype.py @@ -151,7 +151,6 @@ def find(itop_class, key): object_class = ItopapiPrototype.get_itop_class(data['objects'][information]['class']) except UnknownItopClass as e: pass - # TODO find the proper object class if any obj = object_class({}) obj.instance_id = data['objects'][information]['key'] # update all the object's fields with the following line diff --git a/itopapi/model/rack.py b/itopapi/model/rack.py index a2e0ff8..fdefd7f 100644 --- a/itopapi/model/rack.py +++ b/itopapi/model/rack.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.physicalDevice import ItopapiPhysicalDevice from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation @@ -12,7 +13,7 @@ __authors__ = ['Guillaume Philippon ', 'Julien Nauroy '] -class ItopapiRack(ItopapiPrototype, HasOrganization, HasLocation): +class ItopapiRack(ItopapiPhysicalDevice, HasOrganization, HasLocation): """ ItopapiRack is an object that represents a Rack from iTop """ @@ -118,3 +119,6 @@ def __init__(self, data=None): self.applicationsolution_list = None self.softwares_list = None self.logicalvolumes_list = None + +# Register as a subclass of PhysicalDevice +ItopapiPhysicalDevice.register(ItopapiRack) \ No newline at end of file diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 8bc93ac..396f983 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.datacenterDevice import ItopapiDatacenterDevice from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand @@ -19,7 +20,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiServer(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel, +class ItopapiServer(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBrand, HasModel, HasOSFamily, HasOSVersion, HasOSLicence, HasRack, HasEnclosure): """ ItopapiServers is an object that represents a Servers from iTop @@ -142,3 +143,6 @@ def find_power_b(self): if self.powerB_id is not None: return ItopapiPrototype.get_itop_class('PowerSource').find(self.powerB_id) return None + +# Register as a subclass of Datacenter Device +ItopapiDatacenterDevice.register(ItopapiServer) \ No newline at end of file diff --git a/itopapi/model/softwareInstance.py b/itopapi/model/softwareInstance.py new file mode 100644 index 0000000..afa43fc --- /dev/null +++ b/itopapi/model/softwareInstance.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiSoftwareInstance is an abstraction of Software Instance representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiSoftwareInstance(ItopapiFunctionalCI): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'SoftwareInstance', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Software Instance with the given key or criteria """ + return ItopapiPrototype.find(ItopapiSoftwareInstance, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiSoftwareInstance, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Software Instance """ + return ItopapiPrototype.find_all(ItopapiSoftwareInstance) + + """ + ItopapiSoftwareInstance is an object that represents a Software Instance from iTop + """ + def __init__(self, data=None): + super(ItopapiSoftwareInstance, self).__init__(data) + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiSoftwareInstance) diff --git a/itopapi/model/softwareLicence.py b/itopapi/model/softwareLicence.py new file mode 100644 index 0000000..2e6b9a2 --- /dev/null +++ b/itopapi/model/softwareLicence.py @@ -0,0 +1,63 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiSoftwareLicence is an abstraction of Rack representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.licence import ItopapiLicence +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasSoftware import HasSoftware + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiSoftwareLicence(ItopapiLicence, HasOrganization, HasSoftware): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'SoftwareLicence', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'usage_limit', 'description', 'perpetual', 'start_date', 'end_date', 'licence_key'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasSoftware.foreign_key, + ], + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of SoftwareLicence with the given key or criteria """ + return ItopapiPrototype.find(ItopapiSoftwareLicence, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiSoftwareLicence, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of SoftwareLicence """ + return ItopapiPrototype.find_all(ItopapiSoftwareLicence) + + """ + ItopapiSoftwareLicence is an object that represents an SoftwareLicence (sic) from iTop + """ + def __init__(self, data=None): + super(ItopapiSoftwareLicence, self).__init__(data) + # Number of concurrent users or licences + self.usage_limit = None + self.description = None + # Possible values are ['yes', 'no'] + self.perpetual = 'no' + self.start_date = None + self.end_date = None + self.licence_key = None + # Lists + self.documents_list = [] + self.softwareinstance_list = [] + + +# Register as a subclass of FunctionalCI +ItopapiLicence.register(ItopapiSoftwareLicence) diff --git a/itopapi/model/team.py b/itopapi/model/team.py index 3ea5de8..0214c9d 100644 --- a/itopapi/model/team.py +++ b/itopapi/model/team.py @@ -2,16 +2,18 @@ # pylint: disable=too-many-instance-attributes, invalid-name """ ItopapiTeam is an abstraction of Team representation on iTop +It inherits from ItopapiContact """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.contact import ItopapiContact from itopapi.model.features.hasOrganization import HasOrganization __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiTeam(ItopapiPrototype, HasOrganization): +class ItopapiTeam(ItopapiContact, HasOrganization): """ ItopapiTeam is an object that represents a Team from iTop """ @@ -62,3 +64,6 @@ def __init__(self, data=None): self.cis_list = None self.tickets_list = None self.persons_list = None + +# Register as a subclass of Contact +ItopapiContact.register(ItopapiTeam) \ No newline at end of file diff --git a/itopapi/model/typology.py b/itopapi/model/typology.py new file mode 100644 index 0000000..d9f9b16 --- /dev/null +++ b/itopapi/model/typology.py @@ -0,0 +1,42 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiTypology is an abstraction of Typology representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiTypology(ItopapiPrototype): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'Typology', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Functional CI with the given key or criteria """ + return ItopapiPrototype.find(ItopapiTypology, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiTypology, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Functional CI """ + return ItopapiPrototype.find_all(ItopapiTypology) + + """ + ItopapiTypology is an object that represents a Functional CI from iTop + """ + def __init__(self, data=None): + super(ItopapiTypology, self).__init__(data) diff --git a/itopapi/model/virtualDevice.py b/itopapi/model/virtualDevice.py new file mode 100644 index 0000000..c766046 --- /dev/null +++ b/itopapi/model/virtualDevice.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiVirtualDevice is an abstraction of VirtualDevice representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiVirtualDevice(ItopapiFunctionalCI): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'VirtualDevice', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of VirtualDevice with the given key or criteria """ + return ItopapiPrototype.find(ItopapiVirtualDevice, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiVirtualDevice, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of VirtualDevice """ + return ItopapiPrototype.find_all(ItopapiVirtualDevice) + + """ + ItopapiVirtualDevice is an object that represents a VirtualDevice from iTop + """ + def __init__(self, data=None): + super(ItopapiVirtualDevice, self).__init__(data) + + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiVirtualDevice) diff --git a/itopapi/model/virtualHost.py b/itopapi/model/virtualHost.py new file mode 100644 index 0000000..de915d2 --- /dev/null +++ b/itopapi/model/virtualHost.py @@ -0,0 +1,48 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiVirtualHost is an abstraction of VirtualHost representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.virtualDevice import ItopapiVirtualDevice +from itopapi.model.functionalCI import ItopapiFunctionalCI + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiVirtualHost(ItopapiVirtualDevice): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'VirtualHost', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of VirtualHost with the given key or criteria """ + return ItopapiPrototype.find(ItopapiVirtualHost, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiVirtualHost, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of VirtualHost """ + return ItopapiPrototype.find_all(ItopapiVirtualHost) + + """ + ItopapiVirtualHost is an object that represents a VirtualHost from iTop + """ + def __init__(self, data=None): + super(ItopapiVirtualHost, self).__init__(data) + + +# Register as a subclass of VirtualDevice +ItopapiVirtualDevice.register(ItopapiVirtualHost) diff --git a/itopapi/model/virtualMachine.py b/itopapi/model/virtualMachine.py index ec823e3..781014d 100644 --- a/itopapi/model/virtualMachine.py +++ b/itopapi/model/virtualMachine.py @@ -1,10 +1,11 @@ # -*- coding: utf8 -*-fr """ -ItopapiVirtualMachine is an abstraction of VLAN representation on iTop +ItopapiVirtualMachine is an abstraction of a VirtualMachine representation on iTop """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.virtualDevice import ItopapiVirtualDevice from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasOSFamily import HasOSFamily from itopapi.model.features.hasOSVersion import HasOSVersion @@ -15,7 +16,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiVirtualMachine(ItopapiPrototype, HasOrganization, HasOSFamily, HasOSVersion, HasOSLicence, HasVirtualHost): +class ItopapiVirtualMachine(ItopapiVirtualDevice, HasOrganization, HasOSFamily, HasOSVersion, HasOSLicence, HasVirtualHost): # Configuration specific to itop itop = { @@ -89,3 +90,7 @@ def __init__(self, data=None): self.providercontracts_list = {} # VirtualMachine's services list self.services_list = {} + + +# Register as a subclass of VirtualDevice +ItopapiVirtualDevice.register(ItopapiVirtualMachine) diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index ed37c09..2e447d8 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.functionalCI import ItopapiFunctionalCI from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasWebServer import HasWebServer @@ -12,7 +13,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiWebApplication(ItopapiPrototype, HasOrganization, HasWebServer): +class ItopapiWebApplication(ItopapiFunctionalCI, HasOrganization, HasWebServer): """ ItopapiWebApplication is an object that represents a WebApplication from iTop """ @@ -22,8 +23,7 @@ class ItopapiWebApplication(ItopapiPrototype, HasOrganization, HasWebServer): # Name of the class in Itop 'name': 'WebApplication', # Define which fields to save when creating or updating from the python API - 'save': ['name', 'url', 'business_criticity', - 'move2production', 'description'], + 'save': ['name', 'url', 'business_criticity', 'move2production', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, HasWebServer.foreign_key, @@ -98,3 +98,7 @@ def __init__(self, data=None): ################################## # WebApplication's services list self.services_list = {} + + +# Register as a subclass of FunctionalCI +ItopapiFunctionalCI.register(ItopapiWebApplication) diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 0752c09..8d56cd6 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -1,10 +1,11 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements """ -ItopapiWebServer is an abstraction of Rack representation on iTop +ItopapiWebServer is an abstraction of WebServer representation on iTop """ from itopapi.model.prototype import ItopapiPrototype, ItopapiUnimplementedMethod +from itopapi.model.softwareInstance import ItopapiSoftwareInstance from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasSoftware import HasSoftware @@ -13,7 +14,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiWebServer(ItopapiPrototype, HasOrganization, HasSoftwareLicence, HasSoftware): +class ItopapiWebServer(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware): """ ItopapiWebServer is an object that represents a WebServer from iTop """ @@ -107,3 +108,7 @@ def find_system(self): # TODO define System raise ItopapiUnimplementedMethod() return None + + +# Register as a subclass of SoftwareInstance +ItopapiSoftwareInstance.register(ItopapiWebServer) From e06ec651892e2f937209a1a290dc3a4ae30af7c7 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Mon, 1 Feb 2016 16:47:48 +0100 Subject: [PATCH 098/104] Added some more classes to the data model. --- itopapi/model/__init__.py | 41 +++++---- itopapi/model/features/__init__.py | 3 + itopapi/model/features/hasDatacenterDevice.py | 46 ++++++++++ itopapi/model/features/hasPowerStart.py | 45 ++++++++++ itopapi/model/features/hasVirtualMachine.py | 46 ++++++++++ itopapi/model/fiberChannelInterface.py | 62 ++++++++++++++ itopapi/model/ipInterface.py | 47 +++++++++++ itopapi/model/logicalInterface.py | 62 ++++++++++++++ itopapi/model/networkInterface.py | 42 ++++++++++ itopapi/model/pdu.py | 83 +++++++++++++++++++ itopapi/model/physicalInterface.py | 12 ++- itopapi/model/powerConnection.py | 47 +++++++++++ itopapi/model/powerSource.py | 3 +- 13 files changed, 520 insertions(+), 19 deletions(-) create mode 100644 itopapi/model/features/hasDatacenterDevice.py create mode 100644 itopapi/model/features/hasPowerStart.py create mode 100644 itopapi/model/features/hasVirtualMachine.py create mode 100644 itopapi/model/fiberChannelInterface.py create mode 100644 itopapi/model/ipInterface.py create mode 100644 itopapi/model/logicalInterface.py create mode 100644 itopapi/model/networkInterface.py create mode 100644 itopapi/model/pdu.py create mode 100644 itopapi/model/powerConnection.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index ec630a5..1e90ffb 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -16,6 +16,7 @@ from itopapi.model.functionalCI import ItopapiFunctionalCI from itopapi.model.physicalDevice import ItopapiPhysicalDevice from itopapi.model.rack import ItopapiRack +from itopapi.model.enclosure import ItopapiEnclosure from itopapi.model.connectableCI import ItopapiConnectableCI from itopapi.model.datacenterDevice import ItopapiDatacenterDevice from itopapi.model.server import ItopapiServer @@ -44,15 +45,17 @@ from itopapi.model.osVersion import ItopapiOSVersion from itopapi.model.brand import ItopapiBrand from itopapi.model.model import ItopapiModel - - -# TODO Check inheritance +from itopapi.model.networkInterface import ItopapiNetworkInterface +from itopapi.model.ipInterface import ItopapiIPInterface +from itopapi.model.physicalInterface import ItopapiPhysicalInterface +from itopapi.model.logicalInterface import ItopapiLogicalInterface +from itopapi.model.fiberChannelInterface import ItopapiFiberChannelInterface +from itopapi.model.powerConnection import ItopapiPowerConnection from itopapi.model.powerSource import ItopapiPowerSource +from itopapi.model.pdu import ItopapiPDU +from itopapi.model.service import ItopapiService from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet -from itopapi.model.physicalInterface import ItopapiPhysicalInterface -from itopapi.model.service import ItopapiService -from itopapi.model.enclosure import ItopapiEnclosure from itopapi.model.incident import ItopapiIncident # TODO partial list of missing classes, with no particular order and along with their inheritance hierarchy : @@ -66,20 +69,30 @@ # SANSwitch # TapeLibrary # NAS -# ConnectableCI (defined) -# Enclosure -# PowerConnection -# PowerSource -# PDU # Patch # OSPatch # SoftwarePatch -# Typology (defined +# Typology (defined) # DocumentType # ContactType # NetworkDeviceType # IOSVersion # ContractType +# Group +# Contract +# CustomerContract +# ProviderContract +# ServiceFamily +# Service +# ServiceSubcategory +# SLA +# SLT +# DeliveryModel +# Contract +# CustomerContract +# ProviderContract +# Tape +# NASFileSystem +# LogicalVolume -# Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, -# Tablet, TapeLibrary, SANSwitchNAS, PDU, DatabaseSchema +# Peripheral, MobilePhone, Printer, PC, Phone, IPPhone, Tablet, TapeLibrary, SANSwitchNAS diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 16a88d4..f378553 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -30,3 +30,6 @@ from itopapi.model.features.hasManager import HasManager from itopapi.model.features.hasMiddleware import HasMiddleware from itopapi.model.features.hasDBServer import HasDBServer +from itopapi.model.features.hasVirtualMachine import HasVirtualMachine +from itopapi.model.features.hasDatacenterDevice import HasDatacenterDevice +from itopapi.model.features.hasPowerStart import HasPowerStart diff --git a/itopapi/model/features/hasDatacenterDevice.py b/itopapi/model/features/hasDatacenterDevice.py new file mode 100644 index 0000000..0941903 --- /dev/null +++ b/itopapi/model/features/hasDatacenterDevice.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasDatacenterDevice is a mixin representing the datacenterdevice attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasDatacenterDevice(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'datacenterdevice_id', 'name': 'datacenterdevice_name', 'table': 'DatacenterDevice'} + + def __init__(self): + super(HasDatacenterDevice, self).__init__() + + # Object's datacenterdevice id. Call find_datacenterdevice to get the full information or just use + # datacenterdevice_id_friendlyname and datacenterdevice_name + self.datacenterdevice_id = None + # Object's datacenterdevice id's friendly name. Not sure the difference with datacenterdevice_name + self.datacenterdevice_id_friendlyname = None + # Object's datacenterdevice name + self.datacenterdevice_name = None + + def find_datacenterdevice(self): + """ + Retrieve the ItopapiDatacenterDevice related to this instance + """ + if self.datacenterdevice_id is not None: + return ItopapiPrototype.get_itop_class('DatacenterDevice').find(self.datacenterdevice_id) + return None + + def set_datacenterdevice(self, datacenterdevice): + """ + Set the ItopapiDatacenterDevice parameters + """ + self.datacenterdevice_id = datacenterdevice.instance_id + self.datacenterdevice_id_friendlyname = datacenterdevice.friendlyname + self.datacenterdevice_name = datacenterdevice.name diff --git a/itopapi/model/features/hasPowerStart.py b/itopapi/model/features/hasPowerStart.py new file mode 100644 index 0000000..2cfd813 --- /dev/null +++ b/itopapi/model/features/hasPowerStart.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasPowerStart is a mixin representing the powerstart attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasPowerStart(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'powerstart_id', 'name': 'powerstart_name', 'table': 'PowerConnection'} + + def __init__(self): + super(HasPowerStart, self).__init__() + + # Object's powerstart id. Call find_powerstart to get the full information or just use powerstart_name + self.powerstart_id = None + # Object's powerstart id's friendly name. Not sure the difference with powerstart_name + self.powerstart_id_friendlyname = None + # Object's powerstart name + self.powerstart_name = None + + def find_powerstart(self): + """ + Retrieve the ItopapiPowerStart related to this instance + """ + if self.powerstart_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.powerstart_id) + return None + + def set_powerstart(self, powerstart): + """ + Set the ItopapiPerson parameters + """ + self.powerstart_id = powerstart.instance_id + self.powerstart_id_friendlyname = powerstart.friendlyname + self.powerstart_name = powerstart.name diff --git a/itopapi/model/features/hasVirtualMachine.py b/itopapi/model/features/hasVirtualMachine.py new file mode 100644 index 0000000..1aaca65 --- /dev/null +++ b/itopapi/model/features/hasVirtualMachine.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasVirtualMachine is a mixin representing the virtualmachine attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasVirtualMachine(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'virtualmachine_id', 'name': 'virtualmachine_name', 'table': 'VirtualMachine'} + + def __init__(self): + super(HasVirtualMachine, self).__init__() + + # Object's virtualmachine id. Call find_virtualmachine to get the full information or just use + # virtualmachine_id_friendlyname and virtualmachine_name + self.virtualmachine_id = None + # Object's virtualmachine id's friendly name. Not sure the difference with virtualmachine_name + self.virtualmachine_id_friendlyname = None + # Object's virtualmachine name + self.virtualmachine_name = None + + def find_virtualmachine(self): + """ + Retrieve the ItopapiVirtualMachine related to this instance + """ + if self.virtualmachine_id is not None: + return ItopapiPrototype.get_itop_class('VirtualMachine').find(self.virtualmachine_id) + return None + + def set_virtualmachine(self, virtualmachine): + """ + Set the ItopapiVirtualMachine parameters + """ + self.virtualmachine_id = virtualmachine.instance_id + self.virtualmachine_id_friendlyname = virtualmachine.friendlyname + self.virtualmachine_name = virtualmachine.name diff --git a/itopapi/model/fiberChannelInterface.py b/itopapi/model/fiberChannelInterface.py new file mode 100644 index 0000000..c15fbb4 --- /dev/null +++ b/itopapi/model/fiberChannelInterface.py @@ -0,0 +1,62 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiFiberChannelInterface is an abstraction of FiberChannelInterface representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.ipInterface import ItopapiIPInterface +from itopapi.model.features.hasDatacenterDevice import HasDatacenterDevice + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiFiberChannelInterface(ItopapiIPInterface): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'FiberChannelInterface', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'ipaddress', 'macaddress', 'comment', 'ipgateway', 'ipmask', 'speed'], + 'foreign_keys': [ + HasDatacenterDevice.foreign_key, + ], + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of FiberChannelInterface with the given key or criteria """ + return ItopapiPrototype.find(ItopapiFiberChannelInterface, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiFiberChannelInterface, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of FiberChannelInterface """ + return ItopapiPrototype.find_all(ItopapiFiberChannelInterface) + + """ + ItopapiFiberChannelInterface is an object that represents a FiberChannelInterface from iTop + """ + def __init__(self, data=None): + super(ItopapiFiberChannelInterface, self).__init__(data) + # IP address of the FiberChannelInterface + self.ipaddress = None + # MAC address of the FiberChannelInterface + self.macaddress = None + # Any kind of comment + self.comment = None + # IP gateway of the FiberChannelInterface + self.ipgateway = None + # IP mask of the FiberChannelInterface + self.ipmask = None + # speed of the FiberChannelInterface + self.speed = None + + +# Register as a subclass of IPInterface +ItopapiIPInterface.register(ItopapiFiberChannelInterface) diff --git a/itopapi/model/ipInterface.py b/itopapi/model/ipInterface.py new file mode 100644 index 0000000..dbdeb6c --- /dev/null +++ b/itopapi/model/ipInterface.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiIPInterface is an abstraction of IPInterface representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.networkInterface import ItopapiNetworkInterface + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiIPInterface(ItopapiNetworkInterface): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'IPInterface', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of IPInterface with the given key or criteria """ + return ItopapiPrototype.find(ItopapiIPInterface, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiIPInterface, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of IPInterface """ + return ItopapiPrototype.find_all(ItopapiIPInterface) + + """ + ItopapiIPInterface is an object that represents a IPInterface from iTop + """ + def __init__(self, data=None): + super(ItopapiIPInterface, self).__init__(data) + + +# Register as a subclass of NetworkInterface +ItopapiNetworkInterface.register(ItopapiIPInterface) diff --git a/itopapi/model/logicalInterface.py b/itopapi/model/logicalInterface.py new file mode 100644 index 0000000..aa527c1 --- /dev/null +++ b/itopapi/model/logicalInterface.py @@ -0,0 +1,62 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiLogicalInterface is an abstraction of LogicalInterface representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.ipInterface import ItopapiIPInterface +from itopapi.model.features.hasVirtualMachine import HasVirtualMachine + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiLogicalInterface(ItopapiIPInterface, HasVirtualMachine): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'LogicalInterface', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'ipaddress', 'macaddress', 'comment', 'ipgateway', 'ipmask', 'speed'], + 'foreign_keys': [ + HasVirtualMachine.foreign_key, + ], + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of LogicalInterface with the given key or criteria """ + return ItopapiPrototype.find(ItopapiLogicalInterface, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiLogicalInterface, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of LogicalInterface """ + return ItopapiPrototype.find_all(ItopapiLogicalInterface) + + """ + ItopapiLogicalInterface is an object that represents a LogicalInterface from iTop + """ + def __init__(self, data=None): + super(ItopapiLogicalInterface, self).__init__(data) + # IP address of the LogicalInterface + self.ipaddress = None + # MAC address of the LogicalInterface + self.macaddress = None + # Any kind of comment + self.comment = None + # IP gateway of the LogicalInterface + self.ipgateway = None + # IP mask of the LogicalInterface + self.ipmask = None + # speed of the LogicalInterface + self.speed = None + + +# Register as a subclass of IPInterface +ItopapiIPInterface.register(ItopapiLogicalInterface) diff --git a/itopapi/model/networkInterface.py b/itopapi/model/networkInterface.py new file mode 100644 index 0000000..788f1c0 --- /dev/null +++ b/itopapi/model/networkInterface.py @@ -0,0 +1,42 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiNetworkInterface is an abstraction of NetworkInterface representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiNetworkInterface(ItopapiPrototype): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'NetworkInterface', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of NetworkInterface with the given key or criteria """ + return ItopapiPrototype.find(ItopapiNetworkInterface, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiNetworkInterface, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of NetworkInterface """ + return ItopapiPrototype.find_all(ItopapiNetworkInterface) + + """ + ItopapiNetworkInterface is an object that represents a NetworkInterface from iTop + """ + def __init__(self, data=None): + super(ItopapiNetworkInterface, self).__init__(data) diff --git a/itopapi/model/pdu.py b/itopapi/model/pdu.py new file mode 100644 index 0000000..601a410 --- /dev/null +++ b/itopapi/model/pdu.py @@ -0,0 +1,83 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiPDU is an abstraction of PDU representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.powerConnection import ItopapiPowerConnection +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasPowerStart import HasPowerStart + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiPDU(ItopapiPowerConnection, HasOrganization, HasLocation, HasBrand, HasModel, HasRack, HasPowerStart): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'PDU', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'serialnumber', 'asset_number', + 'move2production', 'purchase_date', 'end_of_warranty', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasLocation.foreign_key, + HasBrand.foreign_key, + HasModel.foreign_key, + HasPowerStart.foreign_key, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of PDU with the given key or criteria """ + return ItopapiPrototype.find(ItopapiPDU, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiPDU, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of PDU """ + return ItopapiPrototype.find_all(ItopapiPDU) + + """ + ItopapiPDU is an object that represents a PDU from iTop + """ + def __init__(self, data=None): + super(ItopapiPDU, self).__init__(data) + + # PDU's status. Values within [implementation, obsolete, production, stock] + self.status = None + # PDU's business criticity. Values within [high, medium, low] + self.business_criticity = None + # Serial number + self.serialnumber = None + # Asset number + self.asset_number = None + # Server's move to production date + self.move2production = None + # Server's purchase date + self.purchase_date = None + # Server's end of warranty date + self.end_of_warranty = None + self.description = None + ################################## + # Lists # + ################################## + self.documents_list = {} + self.softwares_list = {} + self.services_list = {} + self.applicationsolution_list = {} + self.contacts_list = {} + self.tickets_list = {} + self.providercontracts_list = {} + self.pdus_list = {} diff --git a/itopapi/model/physicalInterface.py b/itopapi/model/physicalInterface.py index dbb93a6..c8bb486 100644 --- a/itopapi/model/physicalInterface.py +++ b/itopapi/model/physicalInterface.py @@ -5,12 +5,13 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.ipInterface import ItopapiIPInterface __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPhysicalInterface(ItopapiPrototype): +class ItopapiPhysicalInterface(ItopapiIPInterface): # Configuration specific to itop itop = { @@ -19,8 +20,7 @@ class ItopapiPhysicalInterface(ItopapiPrototype): # Define which fields to save when creating or updating from the python API 'save': ['name', 'ipaddress', 'macaddress', 'comment', 'ipgateway', 'ipmask', 'speed'], 'foreign_keys': [ - # TODO the table is not necessarily a server, it is defined by connectableci_id_finalclass_recall - {'id': 'connectableci_id', 'name': 'connectableci_name', 'table': 'Server'}, + {'id': 'connectableci_id', 'name': 'connectableci_name', 'table': 'ConnectableCI'}, # TODO good for fetching, but not for saving since there is no "name" and "finalclass" in this list! # Find a solution # {'id': 'vlan_id', 'name': 'vlan_tag', 'table': 'VLAN'}, @@ -65,4 +65,8 @@ def __init__(self, data=None): # speed of the PhysicalInterface self.speed = None # List of vlans for the PhysicalInterface - self.vlans_list = None \ No newline at end of file + self.vlans_list = None + + +# Register as a subclass of IPInterface +ItopapiIPInterface.register(ItopapiPhysicalInterface) diff --git a/itopapi/model/powerConnection.py b/itopapi/model/powerConnection.py new file mode 100644 index 0000000..cdc6c10 --- /dev/null +++ b/itopapi/model/powerConnection.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiPowerConnection is an abstraction of Connectable CI representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.physicalDevice import ItopapiPhysicalDevice + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiPowerConnection(ItopapiPhysicalDevice): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'PowerConnection', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Connectable CI with the given key or criteria """ + return ItopapiPrototype.find(ItopapiPowerConnection, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiPowerConnection, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Connectable CI """ + return ItopapiPrototype.find_all(ItopapiPowerConnection) + + """ + ItopapiPowerConnection is an object that represents a Connectable CI from iTop + """ + def __init__(self, data=None): + super(ItopapiPowerConnection, self).__init__(data) + + +# Register as a subclass of PhysicalDevice +ItopapiPhysicalDevice.register(ItopapiPowerConnection) \ No newline at end of file diff --git a/itopapi/model/powerSource.py b/itopapi/model/powerSource.py index 38fed44..99c1e68 100644 --- a/itopapi/model/powerSource.py +++ b/itopapi/model/powerSource.py @@ -5,6 +5,7 @@ """ from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.powerConnection import ItopapiPowerConnection from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasLocation import HasLocation from itopapi.model.features.hasBrand import HasBrand @@ -14,7 +15,7 @@ __authors__ = ['Julien Nauroy '] -class ItopapiPowerSource(ItopapiPrototype, HasOrganization, HasLocation, HasBrand, HasModel): +class ItopapiPowerSource(ItopapiPowerConnection, HasOrganization, HasLocation, HasBrand, HasModel): # Configuration specific to itop itop = { From d47c860c39098c8bdaeb0d1eda83fbfb2caac14e Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Mon, 1 Feb 2016 23:05:07 +0100 Subject: [PATCH 099/104] Added HasSystem mixin and updated classes accordingly. --- itopapi/model/dbserver.py | 4 ++- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasSystem.py | 45 +++++++++++++++++++++++++++++ itopapi/model/middleware.py | 4 ++- itopapi/model/othersoftware.py | 4 ++- itopapi/model/webServer.py | 14 ++------- 6 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 itopapi/model/features/hasSystem.py diff --git a/itopapi/model/dbserver.py b/itopapi/model/dbserver.py index 9f395aa..9b2709f 100644 --- a/itopapi/model/dbserver.py +++ b/itopapi/model/dbserver.py @@ -9,12 +9,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftware import HasSoftware from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence +from itopapi.model.features.hasSystem import HasSystem __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiDBServer(ItopapiSoftwareInstance, HasOrganization): +class ItopapiDBServer(ItopapiSoftwareInstance, HasOrganization, HasSoftware, HasSoftwareLicence, HasSystem): """ ItopapiDBServer is an object that represents a DBServer from iTop It has the same attributes as ItopapiOtherSoftware @@ -30,6 +31,7 @@ class ItopapiDBServer(ItopapiSoftwareInstance, HasOrganization): HasOrganization.foreign_key, HasSoftware.foreign_key, HasSoftwareLicence.foreign_key, + HasSystem.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index f378553..418f05d 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -33,3 +33,4 @@ from itopapi.model.features.hasVirtualMachine import HasVirtualMachine from itopapi.model.features.hasDatacenterDevice import HasDatacenterDevice from itopapi.model.features.hasPowerStart import HasPowerStart +from itopapi.model.features.hasSystem import HasSystem diff --git a/itopapi/model/features/hasSystem.py b/itopapi/model/features/hasSystem.py new file mode 100644 index 0000000..120a683 --- /dev/null +++ b/itopapi/model/features/hasSystem.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasSystem is a mixin representing the FunctionalCI attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasSystem(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'system_id', 'name': 'system_name', 'table': 'FunctionalCI'} + + def __init__(self): + super(HasSystem, self).__init__() + + # Object's system id. Call find_system to get the full information or just use system_name + self.system_id = None + # Object's system id's friendly name. Not sure the difference with system_name + self.system_id_friendlyname = None + # Object's system name + self.system_name = None + + def find_system(self): + """ + Retrieve the Itopapisystem related to this instance + """ + if self.system_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.system_id) + return None + + def set_system(self, system): + """ + Set the ItopapiPerson parameters + """ + self.system_id = system.instance_id + self.system_id_friendlyname = system.friendlyname + self.system_name = system.name diff --git a/itopapi/model/middleware.py b/itopapi/model/middleware.py index ea18a94..e428add 100644 --- a/itopapi/model/middleware.py +++ b/itopapi/model/middleware.py @@ -9,12 +9,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasSoftware import HasSoftware +from itopapi.model.features.hasSystem import HasSystem __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiMiddleware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware): +class ItopapiMiddleware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware, HasSystem): """ ItopapiMiddleware is an object that represents a Middleware from iTop """ @@ -29,6 +30,7 @@ class ItopapiMiddleware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLic HasOrganization.foreign_key, HasSoftware.foreign_key, HasSoftwareLicence.foreign_key, + HasSystem.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' diff --git a/itopapi/model/othersoftware.py b/itopapi/model/othersoftware.py index fb3f8fa..8085b3f 100644 --- a/itopapi/model/othersoftware.py +++ b/itopapi/model/othersoftware.py @@ -9,12 +9,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasSoftware import HasSoftware +from itopapi.model.features.hasSystem import HasSystem __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiOtherSoftware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware): +class ItopapiOtherSoftware(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware, HasSystem): """ ItopapiOtherSoftware is an object that represents a OtherSoftware from iTop """ @@ -29,6 +30,7 @@ class ItopapiOtherSoftware(ItopapiSoftwareInstance, HasOrganization, HasSoftware HasOrganization.foreign_key, HasSoftware.foreign_key, HasSoftwareLicence.foreign_key, + HasSystem.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' diff --git a/itopapi/model/webServer.py b/itopapi/model/webServer.py index 8d56cd6..6a9eefd 100644 --- a/itopapi/model/webServer.py +++ b/itopapi/model/webServer.py @@ -9,12 +9,13 @@ from itopapi.model.features.hasOrganization import HasOrganization from itopapi.model.features.hasSoftwareLicence import HasSoftwareLicence from itopapi.model.features.hasSoftware import HasSoftware +from itopapi.model.features.hasSystem import HasSystem __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiWebServer(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware): +class ItopapiWebServer(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLicence, HasSoftware, HasSystem): """ ItopapiWebServer is an object that represents a WebServer from iTop """ @@ -27,9 +28,9 @@ class ItopapiWebServer(ItopapiSoftwareInstance, HasOrganization, HasSoftwareLice 'save': ['name', 'status', 'business_criticity', 'path', 'move2production', 'description'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'system_id', 'name': 'system_id_friendlyname', 'table': 'Server'}, HasSoftware.foreign_key, HasSoftwareLicence.foreign_key, + HasSystem.foreign_key, ], 'list_types': { 'contacts_list': 'contact_id_finalclass_recall' @@ -100,15 +101,6 @@ def __init__(self, data=None): # WebServer's services list self.services_list = {} - def find_system(self): - """ - Retrieve the System (Server or VirtualMachine) corresponding to this WebServer - """ - if self.system_id is not None: - # TODO define System - raise ItopapiUnimplementedMethod() - return None - # Register as a subclass of SoftwareInstance ItopapiSoftwareInstance.register(ItopapiWebServer) From 218a009674c9205da8f7e77d0194ac468d17f320 Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Tue, 2 Feb 2016 07:58:35 +0100 Subject: [PATCH 100/104] Finished with the Typology and started NetworkDevices --- itopapi/model/__init__.py | 17 ++-- itopapi/model/contactType.py | 47 +++++++++ itopapi/model/contractType.py | 47 +++++++++ itopapi/model/documentType.py | 47 +++++++++ itopapi/model/enclosure.py | 2 +- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasPowerA.py | 45 +++++++++ itopapi/model/features/hasPowerB.py | 45 +++++++++ itopapi/model/features/hasTapeLibrary.py | 45 +++++++++ itopapi/model/iosVersion.py | 50 ++++++++++ itopapi/model/networkDeviceType.py | 50 ++++++++++ itopapi/model/osFamily.py | 2 +- itopapi/model/osLicence.py | 2 +- itopapi/model/sanSwitch.py | 117 +++++++++++++++++++++++ itopapi/model/server.py | 37 ++----- itopapi/model/softwareLicence.py | 2 +- itopapi/model/tape.py | 48 ++++++++++ itopapi/model/tapeLibrary.py | 117 +++++++++++++++++++++++ itopapi/model/webApplication.py | 2 +- 19 files changed, 679 insertions(+), 44 deletions(-) create mode 100644 itopapi/model/contactType.py create mode 100644 itopapi/model/contractType.py create mode 100644 itopapi/model/documentType.py create mode 100644 itopapi/model/features/hasPowerA.py create mode 100644 itopapi/model/features/hasPowerB.py create mode 100644 itopapi/model/features/hasTapeLibrary.py create mode 100644 itopapi/model/iosVersion.py create mode 100644 itopapi/model/networkDeviceType.py create mode 100644 itopapi/model/sanSwitch.py create mode 100644 itopapi/model/tape.py create mode 100644 itopapi/model/tapeLibrary.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 1e90ffb..8e285b0 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -20,6 +20,8 @@ from itopapi.model.connectableCI import ItopapiConnectableCI from itopapi.model.datacenterDevice import ItopapiDatacenterDevice from itopapi.model.server import ItopapiServer +from itopapi.model.sanSwitch import ItopapiSANSwitch +from itopapi.model.tapeLibrary import ItopapiTapeLibrary from itopapi.model.applicationSolution import ItopapiApplicationSolution from itopapi.model.businessProcess import ItopapiBusinessProcess from itopapi.model.softwareInstance import ItopapiSoftwareInstance @@ -43,8 +45,13 @@ from itopapi.model.typology import ItopapiTypology from itopapi.model.osFamily import ItopapiOSFamily from itopapi.model.osVersion import ItopapiOSVersion +from itopapi.model.contactType import ItopapiContactType +from itopapi.model.contractType import ItopapiContractType +from itopapi.model.documentType import ItopapiDocumentType from itopapi.model.brand import ItopapiBrand +from itopapi.model.iosVersion import ItopapiIOSVersion from itopapi.model.model import ItopapiModel +from itopapi.model.networkDeviceType import ItopapiNetworkDeviceType from itopapi.model.networkInterface import ItopapiNetworkInterface from itopapi.model.ipInterface import ItopapiIPInterface from itopapi.model.physicalInterface import ItopapiPhysicalInterface @@ -56,6 +63,7 @@ from itopapi.model.service import ItopapiService from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet +from itopapi.model.tape import ItopapiTape from itopapi.model.incident import ItopapiIncident # TODO partial list of missing classes, with no particular order and along with their inheritance hierarchy : @@ -66,18 +74,10 @@ # DatacenterDevice (defined) # NetworkDevice # StorageSystem -# SANSwitch -# TapeLibrary # NAS # Patch # OSPatch # SoftwarePatch -# Typology (defined) -# DocumentType -# ContactType -# NetworkDeviceType -# IOSVersion -# ContractType # Group # Contract # CustomerContract @@ -91,7 +91,6 @@ # Contract # CustomerContract # ProviderContract -# Tape # NASFileSystem # LogicalVolume diff --git a/itopapi/model/contactType.py b/itopapi/model/contactType.py new file mode 100644 index 0000000..9df7054 --- /dev/null +++ b/itopapi/model/contactType.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiContactType is an abstraction of ContactType representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiContactType(ItopapiTypology): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'ContactType', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ContactType with the given key or criteria """ + return ItopapiPrototype.find(ItopapiContactType, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiContactType, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of ContactType """ + return ItopapiPrototype.find_all(ItopapiContactType) + + """ + ItopapiContactType is an object that represents an ContactType from iTop + """ + def __init__(self, data=None): + super(ItopapiContactType, self).__init__(data) + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiContactType) diff --git a/itopapi/model/contractType.py b/itopapi/model/contractType.py new file mode 100644 index 0000000..8f4069f --- /dev/null +++ b/itopapi/model/contractType.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiContractType is an abstraction of ContractType representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiContractType(ItopapiTypology): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'ContractType', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ContractType with the given key or criteria """ + return ItopapiPrototype.find(ItopapiContractType, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiContractType, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of ContractType """ + return ItopapiPrototype.find_all(ItopapiContractType) + + """ + ItopapiContractType is an object that represents an ContractType from iTop + """ + def __init__(self, data=None): + super(ItopapiContractType, self).__init__(data) + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiContractType) diff --git a/itopapi/model/documentType.py b/itopapi/model/documentType.py new file mode 100644 index 0000000..7e555b4 --- /dev/null +++ b/itopapi/model/documentType.py @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiDocumentType is an abstraction of DocumentType representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiDocumentType(ItopapiTypology): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'DocumentType', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of DocumentType with the given key or criteria """ + return ItopapiPrototype.find(ItopapiDocumentType, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiDocumentType, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of DocumentType """ + return ItopapiPrototype.find_all(ItopapiDocumentType) + + """ + ItopapiDocumentType is an object that represents an DocumentType from iTop + """ + def __init__(self, data=None): + super(ItopapiDocumentType, self).__init__(data) + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiDocumentType) diff --git a/itopapi/model/enclosure.py b/itopapi/model/enclosure.py index ce79b07..8d34baf 100644 --- a/itopapi/model/enclosure.py +++ b/itopapi/model/enclosure.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiEnclosure is an abstraction of Rack representation on iTop +ItopapiEnclosure is an abstraction of Enclosure representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 418f05d..3e04001 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -34,3 +34,4 @@ from itopapi.model.features.hasDatacenterDevice import HasDatacenterDevice from itopapi.model.features.hasPowerStart import HasPowerStart from itopapi.model.features.hasSystem import HasSystem +from itopapi.model.features.hasTapeLibrary import HasTapeLibrary diff --git a/itopapi/model/features/hasPowerA.py b/itopapi/model/features/hasPowerA.py new file mode 100644 index 0000000..e777a6c --- /dev/null +++ b/itopapi/model/features/hasPowerA.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasPowerA is a mixin representing the powerA attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasPowerA(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'Power'} + + def __init__(self): + super(HasPowerA, self).__init__() + + # Object's powerA id. Call find_powerA to get the full information or just use powerA_name + self.powerA_id = None + # Object's powerA id's friendly name. Not sure the difference with powerA_name + self.powerA_id_friendlyname = None + # Object's powerA name + self.powerA_name = None + + def find_powerA(self): + """ + Retrieve the ItopapiAgent related to this instance + """ + if self.powerA_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.powerA_id) + return None + + def set_powerA(self, powerA): + """ + Set the ItopapiPerson parameters + """ + self.powerA_id = powerA.instance_id + self.powerA_id_friendlyname = powerA.friendlyname + self.powerA_name = powerA.name diff --git a/itopapi/model/features/hasPowerB.py b/itopapi/model/features/hasPowerB.py new file mode 100644 index 0000000..9b25111 --- /dev/null +++ b/itopapi/model/features/hasPowerB.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasPowerB is a mixin representing the powerB attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasPowerB(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'Power'} + + def __init__(self): + super(HasPowerB, self).__init__() + + # Object's powerB id. Call find_powerB to get the full information or just use powerB_name + self.powerB_id = None + # Object's powerB id's friendly name. Not sure the difference with powerB_name + self.powerB_id_friendlyname = None + # Object's powerB name + self.powerB_name = None + + def find_powerB(self): + """ + Retrieve the ItopapiAgent related to this instance + """ + if self.powerB_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.powerB_id) + return None + + def set_powerB(self, powerB): + """ + Set the ItopapiPerson parameters + """ + self.powerB_id = powerB.instance_id + self.powerB_id_friendlyname = powerB.friendlyname + self.powerB_name = powerB.name diff --git a/itopapi/model/features/hasTapeLibrary.py b/itopapi/model/features/hasTapeLibrary.py new file mode 100644 index 0000000..8f91423 --- /dev/null +++ b/itopapi/model/features/hasTapeLibrary.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasTapeLibrary is a mixin representing the tapelibrary attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasTapeLibrary(object): + """ + HasOrganization represents the organization attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'tapelibrary_id', 'name': 'tapelibrary_name', 'table': 'TapeLibrary'} + + def __init__(self): + super(HasTapeLibrary, self).__init__() + + # Object's tapelibrary id. Call find_tapelibrary to get the full information or just use tapelibrary_name + self.tapelibrary_id = None + # Object's tapelibrary id's friendly name. Not sure the difference with tapelibrary_name + self.tapelibrary_id_friendlyname = None + # Object's tapelibrary name + self.tapelibrary_name = None + + def find_tapelibrary(self): + """ + Retrieve the ItopapiTapeLibrary related to this instance + """ + if self.tapelibrary_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.tapelibrary_id) + return None + + def set_tapelibrary(self, tapelibrary): + """ + Set the ItopapiPerson parameters + """ + self.tapelibrary_id = tapelibrary.instance_id + self.tapelibrary_id_friendlyname = tapelibrary.friendlyname + self.tapelibrary_name = tapelibrary.name diff --git a/itopapi/model/iosVersion.py b/itopapi/model/iosVersion.py new file mode 100644 index 0000000..5693307 --- /dev/null +++ b/itopapi/model/iosVersion.py @@ -0,0 +1,50 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiIOSVersion is an abstraction of IOSVersion representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology +from itopapi.model.features.hasBrand import HasBrand + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiIOSVersion(ItopapiTypology, HasBrand): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'IOSVersion', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [ + HasBrand.foreign_key, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of IOSVersion with the given key or criteria """ + return ItopapiPrototype.find(ItopapiIOSVersion, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiIOSVersion, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of IOSVersion """ + return ItopapiPrototype.find_all(ItopapiIOSVersion) + + """ + ItopapiIOSVersion is an object that represents an IOSVersion from iTop + """ + def __init__(self, data=None): + super(ItopapiIOSVersion, self).__init__(data) + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiIOSVersion) diff --git a/itopapi/model/networkDeviceType.py b/itopapi/model/networkDeviceType.py new file mode 100644 index 0000000..3cfbae0 --- /dev/null +++ b/itopapi/model/networkDeviceType.py @@ -0,0 +1,50 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiNetworkDeviceType is an abstraction of NetworkDeviceType representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.typology import ItopapiTypology + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiNetworkDeviceType(ItopapiTypology): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'NetworkDeviceType', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of NetworkDeviceType with the given key or criteria """ + return ItopapiPrototype.find(ItopapiNetworkDeviceType, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiNetworkDeviceType, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of NetworkDeviceType """ + return ItopapiPrototype.find_all(ItopapiNetworkDeviceType) + + """ + ItopapiNetworkDeviceType is an object that represents an NetworkDeviceType from iTop + """ + def __init__(self, data=None): + super(ItopapiNetworkDeviceType, self).__init__(data) + + # list of NetworkDevice(s) using this type. + self.networkdevicesdevices = {} + + +# Register as a subclass of Typology +ItopapiTypology.register(ItopapiNetworkDeviceType) diff --git a/itopapi/model/osFamily.py b/itopapi/model/osFamily.py index 0dc8a1c..ae628c2 100644 --- a/itopapi/model/osFamily.py +++ b/itopapi/model/osFamily.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiOSFamily is an abstraction of Rack representation on iTop +ItopapiOSFamily is an abstraction of OSFamily representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/osLicence.py b/itopapi/model/osLicence.py index 5cf8e44..9e36265 100644 --- a/itopapi/model/osLicence.py +++ b/itopapi/model/osLicence.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiOSLicence is an abstraction of Rack representation on iTop +ItopapiOSLicence is an abstraction of OSLicence representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/sanSwitch.py b/itopapi/model/sanSwitch.py new file mode 100644 index 0000000..1a83468 --- /dev/null +++ b/itopapi/model/sanSwitch.py @@ -0,0 +1,117 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements +""" +ItopapiSANSwitchs is an abstraction of SANSwitch representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.datacenterDevice import ItopapiDatacenterDevice +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasEnclosure import HasEnclosure +from itopapi.model.features.hasPowerA import HasPowerA +from itopapi.model.features.hasPowerB import HasPowerB + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiSANSwitch(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBrand, HasModel, + HasRack, HasEnclosure, HasPowerA, HasPowerB): + """ + ItopapiSANSwitch is an object that represents a SANSwitch from iTop + """ + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'SANSwitch', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'managementip', + 'nb_u', 'serialnumber', 'asset_number', 'move2production', + 'purchase_date', 'end_of_warranty', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasLocation.foreign_key, + HasBrand.foreign_key, + HasModel.foreign_key, + HasRack.foreign_key, + HasEnclosure.foreign_key, + HasPowerA.foreign_key, + HasPowerB.foreign_key, + ], + 'list_types': { + 'contacts_list': 'Person', + }, + } + + @staticmethod + def find(key): + """ Retrieve one or mor instance of SANSwitch with the given key or criteria """ + return ItopapiPrototype.find(ItopapiSANSwitch, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiSANSwitch, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of SANSwitch """ + return ItopapiPrototype.find_all(ItopapiSANSwitch) + + def __init__(self, data=None): + super(ItopapiSANSwitch, self).__init__(data) + + # SANSwitch's status. Values within [implementation, obsolete, production, stock] + self.status = None + # SANSwitch's business criticity. Values within [high, medium, low] + self.business_criticity = None + self.managementip = None + # Rack units + self.nb_u = None + # SANSwitch's serial number + self.serialnumber = None + # SANSwitch's asset number + self.asset_number = None + # SANSwitch's move to production date + self.move2production = None + # SANSwitch's purchase date + self.purchase_date = None + # SANSwitch's end of warranty date + self.end_of_warranty = None + # SANSwitch's description, as a free text + self.description = None + + ############################## + # Lists # + ############################## + # SANSwitch's softwares list + self.softwares_list = {} + # SANSwitch's contacts list + self.contacts_list = {} + # SANSwitch's documents list + self.documents_list = {} + # SANSwitch's tickets list + self.tickets_list = {} + # SANSwitch's application solutions list + self.applicationsolution_list = {} + # SANSwitch's network interfaces list + self.physicalinterface_list = {} + # SANSwitch's FC ports list + self.fiberinterfacelist_list = {} + # SANSwitch's network devices list + self.networkdevice_list = {} + # SANSwitch's SANs list + self.san_list = {} + # SANSwitch's provider contracts list + self.providercontracts_list = {} + # SANSwitch's services list + self.services_list = {} + # List of DataCenterDevices + self.datacenterdevice_list = {} + +# Register as a subclass of Datacenter Device +ItopapiDatacenterDevice.register(ItopapiSANSwitch) \ No newline at end of file diff --git a/itopapi/model/server.py b/itopapi/model/server.py index 396f983..6a3f8da 100644 --- a/itopapi/model/server.py +++ b/itopapi/model/server.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements """ -ItopapiServers is an abstraction of Rack representation on iTop +ItopapiServers is an abstraction of Server representation on iTop """ from itopapi.model.prototype import ItopapiPrototype @@ -15,15 +15,17 @@ from itopapi.model.features.hasOSLicence import HasOSLicence from itopapi.model.features.hasRack import HasRack from itopapi.model.features.hasEnclosure import HasEnclosure +from itopapi.model.features.hasPowerA import HasPowerA +from itopapi.model.features.hasPowerB import HasPowerB __version__ = '1.0' __authors__ = ['Julien Nauroy '] class ItopapiServer(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBrand, HasModel, - HasOSFamily, HasOSVersion, HasOSLicence, HasRack, HasEnclosure): + HasOSFamily, HasOSVersion, HasOSLicence, HasRack, HasEnclosure, HasPowerA, HasPowerB): """ - ItopapiServers is an object that represents a Servers from iTop + ItopapiServers is an object that represents a Server from iTop """ # Configuration specific to itop @@ -44,12 +46,11 @@ class ItopapiServer(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBr HasOSLicence.foreign_key, HasRack.foreign_key, HasEnclosure.foreign_key, - {'id': 'powerA_id', 'name': 'powerA_name', 'table': 'TODO'}, - {'id': 'powerB_id', 'name': 'powerB_name', 'table': 'TODO'}, + HasPowerA.foreign_key, + HasPowerB.foreign_key, ], 'list_types': { 'contacts_list': 'Person', - 'contacts_list': 'contact_id_finalclass_recall' }, } @@ -89,14 +90,6 @@ def __init__(self, data=None): self.purchase_date = None # Server's end of warranty date self.end_of_warranty = None - self.powerA_id = None - self.powerA_id_finalclass_recall = None - self.powerA_id_friendlyname = None - self.powerA_name = None - self.powerB_id = None - self.powerB_id_finalclass_recall = None - self.powerB_id_friendlyname = None - self.powerB_name = None # Server's description, as a free text self.description = None @@ -128,21 +121,5 @@ def __init__(self, data=None): # Server's services list self.services_list = {} - def find_power_a(self): - """ - Retrieve the ItopapiPowerA corresponding to this server - """ - if self.powerA_id is not None: - return ItopapiPrototype.get_itop_class('PowerSource').find(self.powerA_id) - return None - - def find_power_b(self): - """ - Retrieve the ItopapiPowerB corresponding to this server - """ - if self.powerB_id is not None: - return ItopapiPrototype.get_itop_class('PowerSource').find(self.powerB_id) - return None - # Register as a subclass of Datacenter Device ItopapiDatacenterDevice.register(ItopapiServer) \ No newline at end of file diff --git a/itopapi/model/softwareLicence.py b/itopapi/model/softwareLicence.py index 2e6b9a2..33a92c0 100644 --- a/itopapi/model/softwareLicence.py +++ b/itopapi/model/softwareLicence.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr """ -ItopapiSoftwareLicence is an abstraction of Rack representation on iTop +ItopapiSoftwareLicence is an abstraction of SoftwareLicence representation on iTop """ from itopapi.model.prototype import ItopapiPrototype diff --git a/itopapi/model/tape.py b/itopapi/model/tape.py new file mode 100644 index 0000000..642d75d --- /dev/null +++ b/itopapi/model/tape.py @@ -0,0 +1,48 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiTape is an abstraction of Tape representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasTapeLibrary import HasTapeLibrary + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiTape(ItopapiPrototype, HasTapeLibrary): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'Tape', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'description', 'size'], + 'foreign_keys': [ + HasTapeLibrary.foreign_key, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ApplicationSolution with the given key or criteria """ + return ItopapiPrototype.find(ItopapiTape, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiTape, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSFamily """ + return ItopapiPrototype.find_all(ItopapiTape) + + """ + ItopapiTape is an object that represents an Application Solution from iTop + """ + def __init__(self, data=None): + super(ItopapiTape, self).__init__(data) + + self.description = None + self.size = None diff --git a/itopapi/model/tapeLibrary.py b/itopapi/model/tapeLibrary.py new file mode 100644 index 0000000..1a22048 --- /dev/null +++ b/itopapi/model/tapeLibrary.py @@ -0,0 +1,117 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements +""" +ItopapiTapeLibrarys is an abstraction of TapeLibrary representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.datacenterDevice import ItopapiDatacenterDevice +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasEnclosure import HasEnclosure +from itopapi.model.features.hasPowerA import HasPowerA +from itopapi.model.features.hasPowerB import HasPowerB + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiTapeLibrary(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBrand, HasModel, + HasRack, HasEnclosure, HasPowerA, HasPowerB): + """ + ItopapiTapeLibrary is an object that represents a TapeLibrary from iTop + """ + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'TapeLibrary', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'managementip', + 'nb_u', 'serialnumber', 'asset_number', 'move2production', + 'purchase_date', 'end_of_warranty', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasLocation.foreign_key, + HasBrand.foreign_key, + HasModel.foreign_key, + HasRack.foreign_key, + HasEnclosure.foreign_key, + HasPowerA.foreign_key, + HasPowerB.foreign_key, + ], + 'list_types': { + 'contacts_list': 'Person', + }, + } + + @staticmethod + def find(key): + """ Retrieve one or mor instance of TapeLibrary with the given key or criteria """ + return ItopapiPrototype.find(ItopapiTapeLibrary, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiTapeLibrary, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of TapeLibrary """ + return ItopapiPrototype.find_all(ItopapiTapeLibrary) + + def __init__(self, data=None): + super(ItopapiTapeLibrary, self).__init__(data) + + # TapeLibrary's status. Values within [implementation, obsolete, production, stock] + self.status = None + # TapeLibrary's business criticity. Values within [high, medium, low] + self.business_criticity = None + self.managementip = None + # Rack units + self.nb_u = None + # TapeLibrary's serial number + self.serialnumber = None + # TapeLibrary's asset number + self.asset_number = None + # TapeLibrary's move to production date + self.move2production = None + # TapeLibrary's purchase date + self.purchase_date = None + # TapeLibrary's end of warranty date + self.end_of_warranty = None + # TapeLibrary's description, as a free text + self.description = None + + ############################## + # Lists # + ############################## + # TapeLibrary's softwares list + self.softwares_list = {} + # TapeLibrary's contacts list + self.contacts_list = {} + # TapeLibrary's documents list + self.documents_list = {} + # TapeLibrary's tickets list + self.tickets_list = {} + # TapeLibrary's application solutions list + self.applicationsolution_list = {} + # TapeLibrary's network interfaces list + self.physicalinterface_list = {} + # TapeLibrary's FC ports list + self.fiberinterfacelist_list = {} + # TapeLibrary's network devices list + self.networkdevice_list = {} + # TapeLibrary's SANs list + self.san_list = {} + # TapeLibrary's provider contracts list + self.providercontracts_list = {} + # TapeLibrary's services list + self.services_list = {} + # List of Tapes + self.tapes_list = {} + +# Register as a subclass of Datacenter Device +ItopapiDatacenterDevice.register(ItopapiTapeLibrary) \ No newline at end of file diff --git a/itopapi/model/webApplication.py b/itopapi/model/webApplication.py index 2e447d8..9e3b909 100644 --- a/itopapi/model/webApplication.py +++ b/itopapi/model/webApplication.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*-fr # pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements """ -ItopapiWebApplication is an abstraction of Rack representation on iTop +ItopapiWebApplication is an abstraction of WebApplication representation on iTop """ from itopapi.model.prototype import ItopapiPrototype From 4575a49a9812486d5acce7ed92cd2cd2dd6c3054 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Feb 2016 12:29:26 +0100 Subject: [PATCH 101/104] Added network appliances to the model. --- itopapi/model/__init__.py | 6 +- itopapi/model/features/hasAgent.py | 2 +- itopapi/model/features/hasBrand.py | 2 +- itopapi/model/features/hasDBServer.py | 2 +- itopapi/model/features/hasDatacenterDevice.py | 2 +- itopapi/model/features/hasDeliveryModel.py | 2 +- itopapi/model/features/hasEnclosure.py | 2 +- itopapi/model/features/hasFarm.py | 2 +- itopapi/model/features/hasIOSVersion.py | 45 +++++++ itopapi/model/features/hasLocation.py | 2 +- itopapi/model/features/hasManager.py | 2 +- itopapi/model/features/hasMiddleware.py | 2 +- itopapi/model/features/hasModel.py | 2 +- .../model/features/hasNetworkDeviceType.py | 46 +++++++ itopapi/model/features/hasOSFamily.py | 2 +- itopapi/model/features/hasOSLicence.py | 2 +- itopapi/model/features/hasOSVersion.py | 2 +- itopapi/model/features/hasOrganization2.py | 4 +- .../model/features/hasParentOrganization.py | 2 +- itopapi/model/features/hasPowerA.py | 2 +- itopapi/model/features/hasPowerB.py | 2 +- itopapi/model/features/hasPowerStart.py | 2 +- itopapi/model/features/hasRack.py | 2 +- itopapi/model/features/hasServer.py | 2 +- itopapi/model/features/hasSoftware.py | 2 +- itopapi/model/features/hasSoftwareLicence.py | 2 +- itopapi/model/features/hasSystem.py | 2 +- itopapi/model/features/hasTapeLibrary.py | 2 +- itopapi/model/features/hasTeam.py | 2 +- itopapi/model/features/hasVirtualMachine.py | 2 +- itopapi/model/features/hasVirtualhost.py | 2 +- itopapi/model/features/hasWebServer.py | 2 +- itopapi/model/nas.py | 117 +++++++++++++++++ itopapi/model/networkDevice.py | 123 ++++++++++++++++++ itopapi/model/storageSystem.py | 117 +++++++++++++++++ 35 files changed, 481 insertions(+), 33 deletions(-) create mode 100644 itopapi/model/features/hasIOSVersion.py create mode 100644 itopapi/model/features/hasNetworkDeviceType.py create mode 100644 itopapi/model/nas.py create mode 100644 itopapi/model/networkDevice.py create mode 100644 itopapi/model/storageSystem.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index 8e285b0..bd559a4 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -22,6 +22,7 @@ from itopapi.model.server import ItopapiServer from itopapi.model.sanSwitch import ItopapiSANSwitch from itopapi.model.tapeLibrary import ItopapiTapeLibrary +from itopapi.model.storageSystem import ItopapiStorageSystem from itopapi.model.applicationSolution import ItopapiApplicationSolution from itopapi.model.businessProcess import ItopapiBusinessProcess from itopapi.model.softwareInstance import ItopapiSoftwareInstance @@ -52,6 +53,7 @@ from itopapi.model.iosVersion import ItopapiIOSVersion from itopapi.model.model import ItopapiModel from itopapi.model.networkDeviceType import ItopapiNetworkDeviceType +from itopapi.model.nas import ItopapiNAS from itopapi.model.networkInterface import ItopapiNetworkInterface from itopapi.model.ipInterface import ItopapiIPInterface from itopapi.model.physicalInterface import ItopapiPhysicalInterface @@ -71,10 +73,6 @@ # DocumentFile # DocumentNote # DocumentWeb -# DatacenterDevice (defined) -# NetworkDevice -# StorageSystem -# NAS # Patch # OSPatch # SoftwarePatch diff --git a/itopapi/model/features/hasAgent.py b/itopapi/model/features/hasAgent.py index 10e480c..06591e1 100644 --- a/itopapi/model/features/hasAgent.py +++ b/itopapi/model/features/hasAgent.py @@ -12,7 +12,7 @@ class HasAgent(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasAgent represents the Agent attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasBrand.py b/itopapi/model/features/hasBrand.py index 83df634..1543b7d 100644 --- a/itopapi/model/features/hasBrand.py +++ b/itopapi/model/features/hasBrand.py @@ -12,7 +12,7 @@ class HasBrand(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasBrand represents the Brand attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasDBServer.py b/itopapi/model/features/hasDBServer.py index cf2941d..7b8b57b 100644 --- a/itopapi/model/features/hasDBServer.py +++ b/itopapi/model/features/hasDBServer.py @@ -12,7 +12,7 @@ class HasDBServer(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasDBServer represents the DBServer attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasDatacenterDevice.py b/itopapi/model/features/hasDatacenterDevice.py index 0941903..b006c94 100644 --- a/itopapi/model/features/hasDatacenterDevice.py +++ b/itopapi/model/features/hasDatacenterDevice.py @@ -12,7 +12,7 @@ class HasDatacenterDevice(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasDatacenterDevice represents the DatacenterDevice attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasDeliveryModel.py b/itopapi/model/features/hasDeliveryModel.py index af55ce3..edfe63d 100644 --- a/itopapi/model/features/hasDeliveryModel.py +++ b/itopapi/model/features/hasDeliveryModel.py @@ -12,7 +12,7 @@ class HasDeliveryModel(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasDeliveryModel represents the DeliveryModel attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasEnclosure.py b/itopapi/model/features/hasEnclosure.py index 87192bc..74bf83b 100644 --- a/itopapi/model/features/hasEnclosure.py +++ b/itopapi/model/features/hasEnclosure.py @@ -12,7 +12,7 @@ class HasEnclosure(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasEnclosure represents the Enclosure attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasFarm.py b/itopapi/model/features/hasFarm.py index 7019700..a558d1e 100644 --- a/itopapi/model/features/hasFarm.py +++ b/itopapi/model/features/hasFarm.py @@ -12,7 +12,7 @@ class HasFarm(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasFarm represents the Farm attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasIOSVersion.py b/itopapi/model/features/hasIOSVersion.py new file mode 100644 index 0000000..2487427 --- /dev/null +++ b/itopapi/model/features/hasIOSVersion.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasIOSVersion is a mixin representing the iosversion attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasIOSVersion(object): + """ + HasIOSVersion represents the IOSVersion attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'iosversion_id', 'name': 'iosversion_name', 'table': 'IOSVersion'} + + def __init__(self): + super(HasIOSVersion, self).__init__() + + # Object's iosversion id. Call find_iosversion to get the full information or just use iosversion_name + self.iosversion_id = None + # Object's iosversion id's friendly name. Not sure the difference with iosversion_name + self.iosversion_id_friendlyname = None + # Object's iosversion name + self.iosversion_name = None + + def find_iosversion(self): + """ + Retrieve the ItopapiIOSVersion related to this instance + """ + if self.iosversion_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.iosversion_id) + return None + + def set_iosversion(self, iosversion): + """ + Set the ItopapiPerson parameters + """ + self.iosversion_id = iosversion.instance_id + self.iosversion_id_friendlyname = iosversion.friendlyname + self.iosversion_name = iosversion.name diff --git a/itopapi/model/features/hasLocation.py b/itopapi/model/features/hasLocation.py index 909d0db..72995c8 100644 --- a/itopapi/model/features/hasLocation.py +++ b/itopapi/model/features/hasLocation.py @@ -12,7 +12,7 @@ class HasLocation(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasLocation represents the Location attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasManager.py b/itopapi/model/features/hasManager.py index fe7342e..c9de785 100644 --- a/itopapi/model/features/hasManager.py +++ b/itopapi/model/features/hasManager.py @@ -12,7 +12,7 @@ class HasManager(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasManager represents the Manager attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasMiddleware.py b/itopapi/model/features/hasMiddleware.py index 923d089..e1e1a54 100644 --- a/itopapi/model/features/hasMiddleware.py +++ b/itopapi/model/features/hasMiddleware.py @@ -12,7 +12,7 @@ class HasMiddleware(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasMiddleware represents the Middleware attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasModel.py b/itopapi/model/features/hasModel.py index 2443d0b..14551d5 100644 --- a/itopapi/model/features/hasModel.py +++ b/itopapi/model/features/hasModel.py @@ -12,7 +12,7 @@ class HasModel(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasModel represents the Model attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasNetworkDeviceType.py b/itopapi/model/features/hasNetworkDeviceType.py new file mode 100644 index 0000000..393317b --- /dev/null +++ b/itopapi/model/features/hasNetworkDeviceType.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasNetworkDeviceType is a mixin representing the NetworkDeviceType attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasNetworkDeviceType(object): + """ + HasNetworkDeviceType represents the NetworkDeviceType attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'networkdevicetype_id', 'name': 'networkdevicetype_name', 'table': 'NetworkDeviceType'} + + def __init__(self): + super(HasNetworkDeviceType, self).__init__() + + # Object's NetworkDeviceType id. Call find_NetworkDeviceType to get the full information or just use + # networkdevicetype_id_friendlyname and networkdevicetype_name + self.networkdevicetype_id = None + # Object's NetworkDeviceType id's friendly name. Not sure the difference with networkdevicetype_name + self.networkdevicetype_id_friendlyname = None + # Object's NetworkDeviceType name + self.networkdevicetype_name = None + + def find_NetworkDeviceType(self): + """ + Retrieve the ItopapiNetworkDeviceType related to this instance + """ + if self.networkdevicetype_id is not None: + return ItopapiPrototype.get_itop_class('NetworkDeviceType').find(self.networkdevicetype_id) + return None + + def set_NetworkDeviceType(self, NetworkDeviceType): + """ + Set the ItopapiNetworkDeviceType parameters + """ + self.networkdevicetype_id = NetworkDeviceType.instance_id + self.networkdevicetype_id_friendlyname = NetworkDeviceType.friendlyname + self.networkdevicetype_name = NetworkDeviceType.name diff --git a/itopapi/model/features/hasOSFamily.py b/itopapi/model/features/hasOSFamily.py index 7c21fda..875b3d2 100644 --- a/itopapi/model/features/hasOSFamily.py +++ b/itopapi/model/features/hasOSFamily.py @@ -12,7 +12,7 @@ class HasOSFamily(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasOSFamily represents the OSFamily attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasOSLicence.py b/itopapi/model/features/hasOSLicence.py index 98380b5..358891c 100644 --- a/itopapi/model/features/hasOSLicence.py +++ b/itopapi/model/features/hasOSLicence.py @@ -12,7 +12,7 @@ class HasOSLicence(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasOSLicence represents the OSLicence attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasOSVersion.py b/itopapi/model/features/hasOSVersion.py index f7768d3..eb5b277 100644 --- a/itopapi/model/features/hasOSVersion.py +++ b/itopapi/model/features/hasOSVersion.py @@ -12,7 +12,7 @@ class HasOSVersion(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasOSVersion represents the OSVersion attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasOrganization2.py b/itopapi/model/features/hasOrganization2.py index bb7ee65..7090175 100644 --- a/itopapi/model/features/hasOrganization2.py +++ b/itopapi/model/features/hasOrganization2.py @@ -13,7 +13,9 @@ class HasOrganization2(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasOrganization2 represents the Organization attached to some top-level objects. + It is nearly a duplicate of HasOrganization with org_name instead of organization_name + because of iTop's poor naming conventions. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasParentOrganization.py b/itopapi/model/features/hasParentOrganization.py index b987c1d..5583665 100644 --- a/itopapi/model/features/hasParentOrganization.py +++ b/itopapi/model/features/hasParentOrganization.py @@ -12,7 +12,7 @@ class HasParentOrganization(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasParentOrganization represents the ParentOrganization attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasPowerA.py b/itopapi/model/features/hasPowerA.py index e777a6c..fcd163f 100644 --- a/itopapi/model/features/hasPowerA.py +++ b/itopapi/model/features/hasPowerA.py @@ -12,7 +12,7 @@ class HasPowerA(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasPowerA represents the Power attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasPowerB.py b/itopapi/model/features/hasPowerB.py index 9b25111..92e1763 100644 --- a/itopapi/model/features/hasPowerB.py +++ b/itopapi/model/features/hasPowerB.py @@ -12,7 +12,7 @@ class HasPowerB(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasPowerB represents the Power attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasPowerStart.py b/itopapi/model/features/hasPowerStart.py index 2cfd813..fb1adcd 100644 --- a/itopapi/model/features/hasPowerStart.py +++ b/itopapi/model/features/hasPowerStart.py @@ -12,7 +12,7 @@ class HasPowerStart(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasPowerStart represents the PowerConnection attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasRack.py b/itopapi/model/features/hasRack.py index f32a53d..d0f1238 100644 --- a/itopapi/model/features/hasRack.py +++ b/itopapi/model/features/hasRack.py @@ -12,7 +12,7 @@ class HasRack(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasRack represents the Rack attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasServer.py b/itopapi/model/features/hasServer.py index 540f8ac..4a9f7c4 100644 --- a/itopapi/model/features/hasServer.py +++ b/itopapi/model/features/hasServer.py @@ -12,7 +12,7 @@ class HasServer(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasServer represents the Server attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasSoftware.py b/itopapi/model/features/hasSoftware.py index 8daef1e..248b2e6 100644 --- a/itopapi/model/features/hasSoftware.py +++ b/itopapi/model/features/hasSoftware.py @@ -12,7 +12,7 @@ class HasSoftware(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasSoftware represents the Software attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasSoftwareLicence.py b/itopapi/model/features/hasSoftwareLicence.py index 7a23ae9..edf88ba 100644 --- a/itopapi/model/features/hasSoftwareLicence.py +++ b/itopapi/model/features/hasSoftwareLicence.py @@ -12,7 +12,7 @@ class HasSoftwareLicence(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasSoftwareLicence represents the SoftwareLicence attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasSystem.py b/itopapi/model/features/hasSystem.py index 120a683..3dbfe60 100644 --- a/itopapi/model/features/hasSystem.py +++ b/itopapi/model/features/hasSystem.py @@ -12,7 +12,7 @@ class HasSystem(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasSystem represents the System attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasTapeLibrary.py b/itopapi/model/features/hasTapeLibrary.py index 8f91423..8109f53 100644 --- a/itopapi/model/features/hasTapeLibrary.py +++ b/itopapi/model/features/hasTapeLibrary.py @@ -12,7 +12,7 @@ class HasTapeLibrary(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasTapeLibrary represents the TapeLibrary attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasTeam.py b/itopapi/model/features/hasTeam.py index 4ce2244..a299a6d 100644 --- a/itopapi/model/features/hasTeam.py +++ b/itopapi/model/features/hasTeam.py @@ -12,7 +12,7 @@ class HasTeam(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasTeam represents the Team attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasVirtualMachine.py b/itopapi/model/features/hasVirtualMachine.py index 1aaca65..cd8c4a7 100644 --- a/itopapi/model/features/hasVirtualMachine.py +++ b/itopapi/model/features/hasVirtualMachine.py @@ -12,7 +12,7 @@ class HasVirtualMachine(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasVirtualMachine represents the VirtualMachine attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasVirtualhost.py b/itopapi/model/features/hasVirtualhost.py index 65b6f01..e673095 100644 --- a/itopapi/model/features/hasVirtualhost.py +++ b/itopapi/model/features/hasVirtualhost.py @@ -12,7 +12,7 @@ class HasVirtualHost(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasVirtualHost represents the VirtualHost attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/features/hasWebServer.py b/itopapi/model/features/hasWebServer.py index aac972a..de1f2f5 100644 --- a/itopapi/model/features/hasWebServer.py +++ b/itopapi/model/features/hasWebServer.py @@ -12,7 +12,7 @@ class HasWebServer(object): """ - HasOrganization represents the organization attached to some top-level objects. + HasWebServer represents the WebServer attached to some top-level objects. """ """ Configuration specific to itop """ diff --git a/itopapi/model/nas.py b/itopapi/model/nas.py new file mode 100644 index 0000000..8cb8c00 --- /dev/null +++ b/itopapi/model/nas.py @@ -0,0 +1,117 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements +""" +ItopapiNAS is an abstraction of NAS representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.datacenterDevice import ItopapiDatacenterDevice +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasEnclosure import HasEnclosure +from itopapi.model.features.hasPowerA import HasPowerA +from itopapi.model.features.hasPowerB import HasPowerB + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiNAS(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBrand, HasModel, + HasRack, HasEnclosure, HasPowerA, HasPowerB): + """ + ItopapiNAS is an object that represents a NAS from iTop + """ + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'NAS', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'managementip', + 'nb_u', 'serialnumber', 'asset_number', 'move2production', + 'purchase_date', 'end_of_warranty', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasLocation.foreign_key, + HasBrand.foreign_key, + HasModel.foreign_key, + HasRack.foreign_key, + HasEnclosure.foreign_key, + HasPowerA.foreign_key, + HasPowerB.foreign_key, + ], + 'list_types': { + 'contacts_list': 'Person', + }, + } + + @staticmethod + def find(key): + """ Retrieve one or mor instance of NAS with the given key or criteria """ + return ItopapiPrototype.find(ItopapiNAS, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiNAS, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of NAS """ + return ItopapiPrototype.find_all(ItopapiNAS) + + def __init__(self, data=None): + super(ItopapiNAS, self).__init__(data) + + # NAS's status. Values within [implementation, obsolete, production, stock] + self.status = None + # NAS's business criticity. Values within [high, medium, low] + self.business_criticity = None + self.managementip = None + # Rack units + self.nb_u = None + # NAS's serial number + self.serialnumber = None + # NAS's asset number + self.asset_number = None + # NAS's move to production date + self.move2production = None + # NAS's purchase date + self.purchase_date = None + # NAS's end of warranty date + self.end_of_warranty = None + # NAS's description, as a free text + self.description = None + + ############################## + # Lists # + ############################## + # NAS's softwares list + self.softwares_list = {} + # NAS's contacts list + self.contacts_list = {} + # NAS's documents list + self.documents_list = {} + # NAS's tickets list + self.tickets_list = {} + # NAS's application solutions list + self.applicationsolution_list = {} + # NAS's network interfaces list + self.physicalinterface_list = {} + # NAS's FC ports list + self.fiberinterfacelist_list = {} + # NAS's network devices list + self.networkdevice_list = {} + # NAS's SANs list + self.san_list = {} + # NAS's provider contracts list + self.providercontracts_list = {} + # NAS's services list + self.services_list = {} + # NASFileSystem's list + self.nasfilesystem_list = {} + +# Register as a subclass of Datacenter Device +ItopapiDatacenterDevice.register(ItopapiNAS) \ No newline at end of file diff --git a/itopapi/model/networkDevice.py b/itopapi/model/networkDevice.py new file mode 100644 index 0000000..a68a1bb --- /dev/null +++ b/itopapi/model/networkDevice.py @@ -0,0 +1,123 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements +""" +ItopapiNetworkDevice is an abstraction of NetworkDevice representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.datacenterDevice import ItopapiDatacenterDevice +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasEnclosure import HasEnclosure +from itopapi.model.features.hasNetworkDeviceType import HasNetworkDeviceType +from itopapi.model.features.hasIOSVersion import HasIOSVersion +from itopapi.model.features.hasPowerA import HasPowerA +from itopapi.model.features.hasPowerB import HasPowerB + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiNetworkDevice(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBrand, HasModel, + HasRack, HasEnclosure, HasNetworkDeviceType, HasIOSVersion, HasPowerA, HasPowerB): + """ + ItopapiNetworkDevice is an object that represents a NetworkDevice from iTop + """ + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'NetworkDevice', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'managementip', + 'nb_u', 'serialnumber', 'asset_number', 'move2production', + 'purchase_date', 'end_of_warranty', 'description', 'ram'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasLocation.foreign_key, + HasBrand.foreign_key, + HasModel.foreign_key, + HasRack.foreign_key, + HasNetworkDeviceType.foreign_key, + HasEnclosure.foreign_key, + HasIOSVersion.foreign_key, + HasPowerA.foreign_key, + HasPowerB.foreign_key, + ], + 'list_types': { + 'contacts_list': 'Person', + }, + } + + @staticmethod + def find(key): + """ Retrieve one or mor instance of NetworkDevice with the given key or criteria """ + return ItopapiPrototype.find(ItopapiNetworkDevice, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiNetworkDevice, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of NetworkDevice """ + return ItopapiPrototype.find_all(ItopapiNetworkDevice) + + def __init__(self, data=None): + super(ItopapiNetworkDevice, self).__init__(data) + + # NetworkDevice's status. Values within [implementation, obsolete, production, stock] + self.status = None + # NetworkDevice's business criticity. Values within [high, medium, low] + self.business_criticity = None + self.managementip = None + # Rack units + self.nb_u = None + # NetworkDevice's serial number + self.serialnumber = None + # NetworkDevice's asset number + self.asset_number = None + # NetworkDevice's move to production date + self.move2production = None + # NetworkDevice's purchase date + self.purchase_date = None + # NetworkDevice's end of warranty date + self.end_of_warranty = None + # NetworkDevice's description, as a free text + self.description = None + # Amount of RAM in the device + self.ram = None + + ############################## + # Lists # + ############################## + # NetworkDevice's softwares list + self.softwares_list = {} + # NetworkDevice's contacts list + self.contacts_list = {} + # NetworkDevice's documents list + self.documents_list = {} + # NetworkDevice's tickets list + self.tickets_list = {} + # NetworkDevice's application solutions list + self.applicationsolution_list = {} + # NetworkDevice's network interfaces list + self.physicalinterface_list = {} + # NetworkDevice's FC ports list + self.fiberinterfacelist_list = {} + # NetworkDevice's network devices list + self.networkdevice_list = {} + # NetworkDevice's SANs list + self.san_list = {} + # NetworkDevice's provider contracts list + self.providercontracts_list = {} + # NetworkDevice's services list + self.services_list = {} + # ConnectableCI's list + self.connectablecis_list = {} + +# Register as a subclass of Datacenter Device +ItopapiDatacenterDevice.register(ItopapiNetworkDevice) \ No newline at end of file diff --git a/itopapi/model/storageSystem.py b/itopapi/model/storageSystem.py new file mode 100644 index 0000000..04c24a8 --- /dev/null +++ b/itopapi/model/storageSystem.py @@ -0,0 +1,117 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes,invalid-name, too-many-statements +""" +ItopapiStorageSystem is an abstraction of StorageSystem representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.datacenterDevice import ItopapiDatacenterDevice +from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasLocation import HasLocation +from itopapi.model.features.hasBrand import HasBrand +from itopapi.model.features.hasModel import HasModel +from itopapi.model.features.hasRack import HasRack +from itopapi.model.features.hasEnclosure import HasEnclosure +from itopapi.model.features.hasPowerA import HasPowerA +from itopapi.model.features.hasPowerB import HasPowerB + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiStorageSystem(ItopapiDatacenterDevice, HasOrganization, HasLocation, HasBrand, HasModel, + HasRack, HasEnclosure, HasPowerA, HasPowerB): + """ + ItopapiStorageSystem is an object that represents a StorageSystem from iTop + """ + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'StorageSystem', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'status', 'business_criticity', 'managementip', + 'nb_u', 'serialnumber', 'asset_number', 'move2production', + 'purchase_date', 'end_of_warranty', 'description'], + 'foreign_keys': [ + HasOrganization.foreign_key, + HasLocation.foreign_key, + HasBrand.foreign_key, + HasModel.foreign_key, + HasRack.foreign_key, + HasEnclosure.foreign_key, + HasPowerA.foreign_key, + HasPowerB.foreign_key, + ], + 'list_types': { + 'contacts_list': 'Person', + }, + } + + @staticmethod + def find(key): + """ Retrieve one or mor instance of StorageSystem with the given key or criteria """ + return ItopapiPrototype.find(ItopapiStorageSystem, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiStorageSystem, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of StorageSystem """ + return ItopapiPrototype.find_all(ItopapiStorageSystem) + + def __init__(self, data=None): + super(ItopapiStorageSystem, self).__init__(data) + + # StorageSystem's status. Values within [implementation, obsolete, production, stock] + self.status = None + # StorageSystem's business criticity. Values within [high, medium, low] + self.business_criticity = None + self.managementip = None + # Rack units + self.nb_u = None + # StorageSystem's serial number + self.serialnumber = None + # StorageSystem's asset number + self.asset_number = None + # StorageSystem's move to production date + self.move2production = None + # StorageSystem's purchase date + self.purchase_date = None + # StorageSystem's end of warranty date + self.end_of_warranty = None + # StorageSystem's description, as a free text + self.description = None + + ############################## + # Lists # + ############################## + # StorageSystem's softwares list + self.softwares_list = {} + # StorageSystem's contacts list + self.contacts_list = {} + # StorageSystem's documents list + self.documents_list = {} + # StorageSystem's tickets list + self.tickets_list = {} + # StorageSystem's application solutions list + self.applicationsolution_list = {} + # StorageSystem's network interfaces list + self.physicalinterface_list = {} + # StorageSystem's FC ports list + self.fiberinterfacelist_list = {} + # StorageSystem's network devices list + self.networkdevice_list = {} + # StorageSystem's SANs list + self.san_list = {} + # StorageSystem's provider contracts list + self.providercontracts_list = {} + # StorageSystem's services list + self.services_list = {} + # LogicalVolume's list + self.logicalvolume_list = {} + +# Register as a subclass of Datacenter Device +ItopapiDatacenterDevice.register(ItopapiStorageSystem) \ No newline at end of file From a124014ae2ad29d897dd89502d3caf1f7b2703f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Feb 2016 15:10:40 +0100 Subject: [PATCH 102/104] Even more classes --- itopapi/model/__init__.py | 9 ++-- itopapi/model/features/__init__.py | 2 + itopapi/model/features/hasConnectableCI.py | 45 +++++++++++++++++++ itopapi/model/features/hasServiceFamily.py | 46 ++++++++++++++++++++ itopapi/model/osPatch.py | 50 ++++++++++++++++++++++ itopapi/model/patch.py | 42 ++++++++++++++++++ itopapi/model/physicalInterface.py | 5 ++- itopapi/model/service.py | 9 ++-- itopapi/model/serviceFamily.py | 45 +++++++++++++++++++ itopapi/model/softwarePatch.py | 50 ++++++++++++++++++++++ 10 files changed, 290 insertions(+), 13 deletions(-) create mode 100644 itopapi/model/features/hasConnectableCI.py create mode 100644 itopapi/model/features/hasServiceFamily.py create mode 100644 itopapi/model/osPatch.py create mode 100644 itopapi/model/patch.py create mode 100644 itopapi/model/serviceFamily.py create mode 100644 itopapi/model/softwarePatch.py diff --git a/itopapi/model/__init__.py b/itopapi/model/__init__.py index bd559a4..28daf0e 100644 --- a/itopapi/model/__init__.py +++ b/itopapi/model/__init__.py @@ -63,9 +63,13 @@ from itopapi.model.powerSource import ItopapiPowerSource from itopapi.model.pdu import ItopapiPDU from itopapi.model.service import ItopapiService +from itopapi.model.serviceFamily import ItopapiServiceFamily from itopapi.model.vlan import ItopapiVLAN from itopapi.model.subnet import ItopapiSubnet from itopapi.model.tape import ItopapiTape +from itopapi.model.patch import ItopapiPatch +from itopapi.model.osPatch import ItopapiOSPatch +from itopapi.model.softwarePatch import ItopapiSoftwarePatch from itopapi.model.incident import ItopapiIncident # TODO partial list of missing classes, with no particular order and along with their inheritance hierarchy : @@ -73,15 +77,10 @@ # DocumentFile # DocumentNote # DocumentWeb -# Patch -# OSPatch -# SoftwarePatch # Group # Contract # CustomerContract # ProviderContract -# ServiceFamily -# Service # ServiceSubcategory # SLA # SLT diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 3e04001..46324cf 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -35,3 +35,5 @@ from itopapi.model.features.hasPowerStart import HasPowerStart from itopapi.model.features.hasSystem import HasSystem from itopapi.model.features.hasTapeLibrary import HasTapeLibrary +from itopapi.model.features.hasServiceFamily import HasServiceFamily +from itopapi.model.features.hasConnectableCI import HasConnectableCI diff --git a/itopapi/model/features/hasConnectableCI.py b/itopapi/model/features/hasConnectableCI.py new file mode 100644 index 0000000..817d716 --- /dev/null +++ b/itopapi/model/features/hasConnectableCI.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasConnectableCI is a mixin representing the ConnectableCI attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasConnectableCI(object): + """ + HasConnectableCI represents the ConnectableCI attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'connectableci_id', 'name': 'connectableci_name', 'table': 'Person'} + + def __init__(self): + super(HasConnectableCI, self).__init__() + + # Object's connectableci id. Call find_connectableci to get the full information or just use connectableci_name + self.connectableci_id = None + # Object's connectableci id's friendly name. Not sure the difference with connectableci_name + self.connectableci_id_friendlyname = None + # Object's connectableci name + self.connectableci_name = None + + def find_connectableci(self): + """ + Retrieve the ItopapiConnectableCI related to this instance + """ + if self.connectableci_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.connectableci_id) + return None + + def set_connectableci(self, connectableci): + """ + Set the ItopapiPerson parameters + """ + self.connectableci_id = connectableci.instance_id + self.connectableci_id_friendlyname = connectableci.friendlyname + self.connectableci_name = connectableci.name diff --git a/itopapi/model/features/hasServiceFamily.py b/itopapi/model/features/hasServiceFamily.py new file mode 100644 index 0000000..051103b --- /dev/null +++ b/itopapi/model/features/hasServiceFamily.py @@ -0,0 +1,46 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasServiceFamily is a mixin representing the ServiceFamily attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasServiceFamily(object): + """ + HasServiceFamily represents the ServiceFamily attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'servicefamily_id', 'name': 'servicefamily_name', 'table': 'ServiceFamily'} + + def __init__(self): + super(HasServiceFamily, self).__init__() + + # Object's ServiceFamily id. Call find_servicefamily to get the full information or just use + # servicefamily_id_friendlyname and servicefamily_name + self.servicefamily_id = None + # Object's ServiceFamily id's friendly name. Not sure the difference with servicefamily_name + self.servicefamily_id_friendlyname = None + # Object's ServiceFamily name + self.servicefamily_name = None + + def find_servicefamily(self): + """ + Retrieve the ItopapiServiceFamily related to this instance + """ + if self.servicefamily_id is not None: + return ItopapiPrototype.get_itop_class('ServiceFamily').find(self.servicefamily_id) + return None + + def set_servicefamily(self, servicefamily): + """ + Set the ItopapiServiceFamily parameters + """ + self.servicefamily_id = servicefamily.instance_id + self.servicefamily_id_friendlyname = servicefamily.friendlyname + self.servicefamily_name = servicefamily.name diff --git a/itopapi/model/osPatch.py b/itopapi/model/osPatch.py new file mode 100644 index 0000000..573b825 --- /dev/null +++ b/itopapi/model/osPatch.py @@ -0,0 +1,50 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiOSPatch is an abstraction of OSPatch representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasOSVersion import HasOSVersion + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiOSPatch(ItopapiPrototype, HasOSVersion): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'OSPatch', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'description', 'size'], + 'foreign_keys': [ + HasOSVersion.foreign_key, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ApplicationSolution with the given key or criteria """ + return ItopapiPrototype.find(ItopapiOSPatch, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiOSPatch, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSFamily """ + return ItopapiPrototype.find_all(ItopapiOSPatch) + + """ + ItopapiOSPatch is an object that represents an Application Solution from iTop + """ + def __init__(self, data=None): + super(ItopapiOSPatch, self).__init__(data) + + self.description = None + # Lists + self.documents_list = {} + self.functionalcis_list = {} diff --git a/itopapi/model/patch.py b/itopapi/model/patch.py new file mode 100644 index 0000000..4010ade --- /dev/null +++ b/itopapi/model/patch.py @@ -0,0 +1,42 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiPatch is an abstraction of Patch representation on iTop +""" + +from abc import ABCMeta +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiPatch(ItopapiPrototype): + __metaclass__ = ABCMeta + + # Configuration specific to itop + itop = { + 'name': 'Patch', + 'save': [], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of Patch with the given key or criteria """ + return ItopapiPrototype.find(ItopapiPatch, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiPatch, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of Patch """ + return ItopapiPrototype.find_all(ItopapiPatch) + + """ + ItopapiPatch is an object that represents a Patch from iTop + """ + def __init__(self, data=None): + super(ItopapiPatch, self).__init__(data) diff --git a/itopapi/model/physicalInterface.py b/itopapi/model/physicalInterface.py index c8bb486..0d9a3da 100644 --- a/itopapi/model/physicalInterface.py +++ b/itopapi/model/physicalInterface.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.ipInterface import ItopapiIPInterface +from itopapi.model.features.hasConnectableCI import HasConnectableCI __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiPhysicalInterface(ItopapiIPInterface): +class ItopapiPhysicalInterface(ItopapiIPInterface, HasConnectableCI): # Configuration specific to itop itop = { @@ -20,7 +21,7 @@ class ItopapiPhysicalInterface(ItopapiIPInterface): # Define which fields to save when creating or updating from the python API 'save': ['name', 'ipaddress', 'macaddress', 'comment', 'ipgateway', 'ipmask', 'speed'], 'foreign_keys': [ - {'id': 'connectableci_id', 'name': 'connectableci_name', 'table': 'ConnectableCI'}, + HasConnectableCI.foreign_key, # TODO good for fetching, but not for saving since there is no "name" and "finalclass" in this list! # Find a solution # {'id': 'vlan_id', 'name': 'vlan_tag', 'table': 'VLAN'}, diff --git a/itopapi/model/service.py b/itopapi/model/service.py index 9129d5a..813a5d5 100644 --- a/itopapi/model/service.py +++ b/itopapi/model/service.py @@ -6,12 +6,13 @@ from itopapi.model.prototype import ItopapiPrototype from itopapi.model.features.hasOrganization import HasOrganization +from itopapi.model.features.hasServiceFamily import HasServiceFamily __version__ = '1.0' __authors__ = ['Julien Nauroy '] -class ItopapiService(ItopapiPrototype, HasOrganization): +class ItopapiService(ItopapiPrototype, HasOrganization, HasServiceFamily): # Configuration specific to itop itop = { @@ -21,7 +22,7 @@ class ItopapiService(ItopapiPrototype, HasOrganization): 'save': ['name', 'description', 'status'], 'foreign_keys': [ HasOrganization.foreign_key, - {'id': 'servicefamily_id', 'name': 'servicefamily_name', 'table': 'ServiceFamily'}, + HasServiceFamily.foreign_key, ], 'list_types': { 'functionalcis_list': 'functionalci_id_finalclass_recall', @@ -48,10 +49,6 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiService, self).__init__(data) - # Service Family - self.servicefamily_id = None - self.servicefamily_id_friendlyname = None - self.servicefamily_name = None # Description self.description = None # Service's status. Values within [implementation, obsolete, production] diff --git a/itopapi/model/serviceFamily.py b/itopapi/model/serviceFamily.py new file mode 100644 index 0000000..37abd00 --- /dev/null +++ b/itopapi/model/serviceFamily.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr + +""" +ItopapiServiceFamily is an abstraction of ServiceFamily representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiServiceFamily(ItopapiPrototype): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'ServiceFamily', + # Define which fields to save when creating or updating from the python API + 'save': ['name'], + 'foreign_keys': [] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ServiceFamily with the given key or criteria """ + return ItopapiPrototype.find(ItopapiServiceFamily, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiServiceFamily, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of ServiceFamily """ + return ItopapiPrototype.find_all(ItopapiServiceFamily) + + """ + ItopapiServiceFamily is an object that represents a ServiceFamily from iTop + """ + def __init__(self, data=None): + super(ItopapiServiceFamily, self).__init__(data) + + # Services which are part of the ServiceFamily + self.services_list = None diff --git a/itopapi/model/softwarePatch.py b/itopapi/model/softwarePatch.py new file mode 100644 index 0000000..01b1650 --- /dev/null +++ b/itopapi/model/softwarePatch.py @@ -0,0 +1,50 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=invalid-name +""" +ItopapiSoftwarePatch is an abstraction of SoftwarePatch representation on iTop +""" + +from itopapi.model.prototype import ItopapiPrototype +from itopapi.model.features.hasSoftware import HasSoftware + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class ItopapiSoftwarePatch(ItopapiPrototype, HasSoftware): + + # Configuration specific to itop + itop = { + # Name of the class in Itop + 'name': 'SoftwarePatch', + # Define which fields to save when creating or updating from the python API + 'save': ['name', 'description', 'size'], + 'foreign_keys': [ + HasSoftware.foreign_key, + ] + } + + @staticmethod + def find(key): + """ Retrieve one or more instance of ApplicationSolution with the given key or criteria """ + return ItopapiPrototype.find(ItopapiSoftwarePatch, key) + + @staticmethod + def find_by_name(name): + return ItopapiPrototype.find_by_name(ItopapiSoftwarePatch, name) + + @staticmethod + def find_all(): + """ Retrieve all instance of OSFamily """ + return ItopapiPrototype.find_all(ItopapiSoftwarePatch) + + """ + ItopapiSoftwarePatch is an object that represents an Application Solution from iTop + """ + def __init__(self, data=None): + super(ItopapiSoftwarePatch, self).__init__(data) + + self.description = None + # Lists + self.documents_list = {} + self.softwareinstances_list = {} From e4c5a8c99ed25b1423d4f31a107dd8bff017ed6f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Feb 2016 15:18:49 +0100 Subject: [PATCH 103/104] Now the VLAN should be fetched correctly from the PhysicalInterface --- itopapi/model/features/__init__.py | 1 + itopapi/model/features/hasVLAN.py | 45 ++++++++++++++++++++++++++++++ itopapi/model/physicalInterface.py | 8 ------ 3 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 itopapi/model/features/hasVLAN.py diff --git a/itopapi/model/features/__init__.py b/itopapi/model/features/__init__.py index 46324cf..8e342ea 100644 --- a/itopapi/model/features/__init__.py +++ b/itopapi/model/features/__init__.py @@ -37,3 +37,4 @@ from itopapi.model.features.hasTapeLibrary import HasTapeLibrary from itopapi.model.features.hasServiceFamily import HasServiceFamily from itopapi.model.features.hasConnectableCI import HasConnectableCI +from itopapi.model.features.hasVLAN import HasVLAN diff --git a/itopapi/model/features/hasVLAN.py b/itopapi/model/features/hasVLAN.py new file mode 100644 index 0000000..be7ca0f --- /dev/null +++ b/itopapi/model/features/hasVLAN.py @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*-fr +# pylint: disable=too-many-instance-attributes, invalid-name +""" +HasVLAN is a mixin representing the VLAN attached to some of the objects. +""" + +from itopapi.model.prototype import ItopapiPrototype + +__version__ = '1.0' +__authors__ = ['Julien Nauroy '] + + +class HasVLAN(object): + """ + HasVLAN represents the VLAN attached to some top-level objects. + """ + + """ Configuration specific to itop """ + foreign_key = {'id': 'vlan_id', 'name': 'vlan_tag', 'table': 'Person'} + + def __init__(self): + super(HasVLAN, self).__init__() + + # Object's vlan id. Call find_vlan to get the full information or just use vlan_name + self.vlan_id = None + # Object's vlan id's friendly name. Not sure the difference with vlan_name + self.vlan_id_friendlyname = None + # Object's vlan name + self.vlan_name = None + + def find_vlan(self): + """ + Retrieve the ItopapiVLAN related to this instance + """ + if self.vlan_id is not None: + return ItopapiPrototype.get_itop_class('Person').find(self.vlan_id) + return None + + def set_vlan(self, vlan): + """ + Set the ItopapiPerson parameters + """ + self.vlan_id = vlan.instance_id + self.vlan_id_friendlyname = vlan.friendlyname + self.vlan_name = vlan.name diff --git a/itopapi/model/physicalInterface.py b/itopapi/model/physicalInterface.py index 0d9a3da..4b403b3 100644 --- a/itopapi/model/physicalInterface.py +++ b/itopapi/model/physicalInterface.py @@ -22,9 +22,6 @@ class ItopapiPhysicalInterface(ItopapiIPInterface, HasConnectableCI): 'save': ['name', 'ipaddress', 'macaddress', 'comment', 'ipgateway', 'ipmask', 'speed'], 'foreign_keys': [ HasConnectableCI.foreign_key, - # TODO good for fetching, but not for saving since there is no "name" and "finalclass" in this list! - # Find a solution - # {'id': 'vlan_id', 'name': 'vlan_tag', 'table': 'VLAN'}, ], 'list_types': {'vlans_list': 'VLAN'}, } @@ -48,11 +45,6 @@ def find_all(): """ def __init__(self, data=None): super(ItopapiPhysicalInterface, self).__init__(data) - # CI the Physical Interface is connected to - self.connectableci_name = None - self.connectableci_id = None - self.connectableci_id_friendlyname = None - self.connectableci_id_finalclass_recall = None # IP address of the PhysicalInterface self.ipaddress = None # MAC address of the PhysicalInterface From 2927a557d767acc1925c3c429fd72dd27170e6db Mon Sep 17 00:00:00 2001 From: Julien Nauroy Date: Fri, 5 Feb 2016 12:42:42 +0100 Subject: [PATCH 104/104] Fixed wrong case in file names + executable files. --- itop2centreon.py | 0 itopapi/model/features/{hasVirtualhost.py => hasVirtualHost.py} | 0 itopapi/model/{FunctionalCI.py => functionalCI.py} | 0 itopapi/model/{othersoftware.py => otherSoftware.py} | 0 itopapi/model/{pcsoftware.py => pcSoftware.py} | 0 setup.py | 0 vcenter2itop.py | 0 7 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 itop2centreon.py rename itopapi/model/features/{hasVirtualhost.py => hasVirtualHost.py} (100%) rename itopapi/model/{FunctionalCI.py => functionalCI.py} (100%) rename itopapi/model/{othersoftware.py => otherSoftware.py} (100%) rename itopapi/model/{pcsoftware.py => pcSoftware.py} (100%) mode change 100644 => 100755 setup.py mode change 100644 => 100755 vcenter2itop.py diff --git a/itop2centreon.py b/itop2centreon.py old mode 100644 new mode 100755 diff --git a/itopapi/model/features/hasVirtualhost.py b/itopapi/model/features/hasVirtualHost.py similarity index 100% rename from itopapi/model/features/hasVirtualhost.py rename to itopapi/model/features/hasVirtualHost.py diff --git a/itopapi/model/FunctionalCI.py b/itopapi/model/functionalCI.py similarity index 100% rename from itopapi/model/FunctionalCI.py rename to itopapi/model/functionalCI.py diff --git a/itopapi/model/othersoftware.py b/itopapi/model/otherSoftware.py similarity index 100% rename from itopapi/model/othersoftware.py rename to itopapi/model/otherSoftware.py diff --git a/itopapi/model/pcsoftware.py b/itopapi/model/pcSoftware.py similarity index 100% rename from itopapi/model/pcsoftware.py rename to itopapi/model/pcSoftware.py diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 diff --git a/vcenter2itop.py b/vcenter2itop.py old mode 100644 new mode 100755