def deploy_system(name): """Deploy baremetal computer whose name is **name** :param string name: the unique name of baremetal computer """ log.debug("deploy_system_task recieved, host is {0}".format(name)) rest_api = CobblerRestAPI() result = rest_api.deploy_cobbler_system(name) log.info("deploy_system, deploy command result is: {0}".format(result))
def deploy_system(name): '''Deploy baremetal computer whose name is **name** :param string name: the unique name of baremetal computer ''' log.debug("deploy_system_task recieved, host is {0}".format(name)) rest_api = CobblerRestAPI() result = rest_api.deploy_cobbler_system(name) log.info("deploy_system, deploy command result is: {0}".format(result))
def power_system(name, flag_on): """Power ON/OFF baremetal computer whose name is **name** :param string name: the unique name of baremetal computer :param boolean flag_on: True means power ON, False means OFF """ log.debug("power_system_task recieved, host is {0}, flag is: {1}".format(name, "ON" if flag_on else "OFF")) rest_api = CobblerRestAPI() result = rest_api.power_cobbler_system(name, flag_on) log.info("power_system, power command result is: {0}".format(result))
def power_system(name, flag_on): '''Power ON/OFF baremetal computer whose name is **name** :param string name: the unique name of baremetal computer :param boolean flag_on: True means power ON, False means OFF ''' log.debug("power_system_task recieved, host is {0}, flag is: {1}".format( name, "ON" if flag_on else "OFF")) rest_api = CobblerRestAPI() result = rest_api.power_cobbler_system(name, flag_on) log.info("power_system, power command result is: {0}".format(result))
def __init__(self): self.rest_api = CobblerRestAPI() self.baremetal = BaremetalComputer() self.status = BaremetalStatus() self.policy = BaremetalPolicy()
class RainCobblerWrapper: """ provide API for CM rain command or Web Interface. """ def __init__(self): self.rest_api = CobblerRestAPI() self.baremetal = BaremetalComputer() self.status = BaremetalStatus() self.policy = BaremetalPolicy() def baremetal_computer_host_list(self): """list computers for baremetal provisioning provided for **rain admin baremetals** :return: a list of baremetal computers """ return self.baremetal.get_baremetal_computers() def baremetal_computer_host_on(self, raw_hosts): """Enable/ON computers for baremetal provisioning provided for **rain admin on HOSTS** :param string raw_hosts: ne or more hosts with the valid formation of hostlist :return: True means successfully, otherwise False """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.baremetal.enable_baremetal_computers(hosts) def baremetal_computer_host_off(self, raw_hosts): """Disable/OFF computers for baremetal provisioning provided for **rain admin off HOSTS** :param string raw_hosts: ne or more hosts with the valid formation of hostlist :return: True means successfully, otherwise False """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.baremetal.disable_baremetal_computers(hosts) def list_all_user_group_hosts(self, flag_user=True, flag_merge=False): """list all baremetal computers that can be used by each user/project. provided for **rain admin list users/projects** :param boolean flag_user: True means user, False means projects :return: a dict with the formation {"user1": "hostlist", "user2": "hostlist2"} """ if flag_user: return self.policy.get_all_user_policy(flag_merge) return self.policy.get_all_group_policy(flag_merge) def list_user_hosts(self, raw_users): """list all baremetal computers that can be used by each user. provided for **rain admin list hosts --user=USERS** :param string raw_users: one or more users with the valid formation of hostlist :return: a dict with the formation {"user1": "hostlist", "user2": "hostlist2"} """ return self.policy.get_policy_based_user(raw_users) def list_project_hosts(self, raw_projects): """list all baremetal computers that can be used by each project/group. provided for **rain admin list hosts --project=PROJECTS** :param string raw_projects: one or more projects with the valid formation of hostlist :return: a dict with the formation {"project1": "hostlist", "project2": "hostlist2"} """ return self.policy.get_policy_based_group(raw_projects) def get_policy_based_user_or_its_projects(self, user, projects): """get the merged policy based on the username and his/her related projects """ return self.policy.get_policy_based_user_or_its_projects( user, projects) def add_user_policy(self, raw_users, raw_hosts): """add a new policy for user provided for **rain admin policy --user=USERS -l HOSTS** :param string raw_users: one or more users with the valid formation of hostlist :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: None if add failed, otherwise the UUID of this policy :rtype: string """ return self.policy.add_user_policy(raw_users, raw_hosts) def add_project_policy(self, raw_projects, raw_hosts): """add a new policy for project provided for **rain admin policy --project=PROJECTS -l HOSTS** :param string raw_projects: one or more projects with the valid formation of hostlist :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: None if add failed, otherwise the UUID of this policy :rtype: string """ return self.policy.add_group_policy(raw_projects, raw_hosts) def get_status_short(self, raw_hosts=None): """get status of baremetal computer provided for **rain status --short [HOSTS]** :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: a dict of the formation {"host1": "deployed", "host2": "deploying", "host3": "failed"} """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.status.get_status_short(hosts) def get_status_summary(self, raw_hosts=None): """get status summary of baremetal computer provided for **rain status --summary [HOSTS]** :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: a dict of the formation {"deployed": 1, "deploying":2, "failed":2, "total": 5} """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.status.get_status_summary(hosts) def provision_host_with_profile(self, profile, hosts): """ baremetal provision host in raw_hosts with profile defined in cobbler. provided for **rain provision --profile=PROFILE HOSTS** :param string profile: the name of cobbler profile :param list hosts: a list of host ["host1", "host2",] :return: a dict, formation is {"result": True|False, "description": "details"} """ FIELD_DESC = "description" result_data = {"result": False, FIELD_DESC: ""} # check the exist of the profile profiles = self.rest_api.get_cobbler_profile_list() if profile in profiles: # hosts = expand_hostlist(raw_hosts) # log.debug("after expand, raw_hosts {0} is: {1}".format(raw_hosts, hosts)) systems = self.rest_api.get_cobbler_system_list() # check the system named host exist in cobbler or not not_exist_hosts = [h for h in hosts if h not in systems] already_exist_hosts = [h for h in hosts if h in systems] log.debug( "hosts is: {0}, systems is: {1}, not_exist_hosts is {2}, already_exist is {3}" .format(hosts, systems, not_exist_hosts, already_exist_hosts)) result = True # create system with profile for host in not_exist_hosts for host in not_exist_hosts: result = self.create_system_with_profile(host, profile) if not result: result_data[ FIELD_DESC] = "Create system for host {0} with profile {1} failed.".format( host, profile) if result: # update system with profile for host in already_exist_hosts for host in already_exist_hosts: result = self.update_system_with_profile(host, profile) if not result: result_data[ FIELD_DESC] = "Update system for host {0} with profile {1} failed.".format( host, profile) if result: # provision/deploy each host for host in hosts: log.info( "call celery deploy_system on host {0} ...".format( host)) deploy_system.apply_async([host], queue='cobbler') result_data["result"] = result else: result_data[ FIELD_DESC] = "profile {0} NOT exist in cobbler.".format( profile) return result_data def list_system_based_distro_kickstart(self, distro=None, kickstart=None): """list all possible systems/hosts based on distro and kickstart provided for **rain provision list (--distro=DISTRO|--kickstart=KICKSTART)** :param string distro: the name of cobbler distro :param string kickstart: the name of kickstart file (ONLY filename) :return: a list of systems/hosts name """ profiles = self.list_profile_based_distro_kickstart(distro, kickstart) systems = [] if profiles: for profile in profiles: result = self.rest_api.get_cobbler_profile_children(profile) if result: systems.extend(result) return systems def list_profile_based_distro_kickstart(self, distro=None, kickstart=None): """list all possible profiles based on distro and kickstart provided for **rain provision list --type=profile (--distro=DISTRO|--kickstart=KICKSTART)** :param string distro: the name of cobbler distro :param string kickstart: the name of kickstart file (ONLY filename) :return: a list of profiles name """ profiles = None if distro: profiles_distro = self.rest_api.get_cobbler_distro_children(distro) profiles_ks = None if kickstart: profiles_ks = self.rest_api.get_cobbler_profile_based_kickstart( kickstart) if profiles_distro and profiles_ks: profiles = [p for p in profiles_distro if p in profiles_ks] else: profiles = profiles_distro if profiles_distro else profiles_ks else: if kickstart: profiles = self.rest_api.get_cobbler_profile_based_kickstart( kickstart) else: profiles = self.rest_api.get_cobbler_profile_list() return profiles def provision_host_with_distro_kickstart(self, distro, kickstart, hosts): """ baremetal provision host in hosts with distro defined in cobbler and kickstart file. provided for **rain provision --distro=DITRO --kickstart=KICKSTART HOSTS** :param string distro: the name of cobbler distro :param string kickstart: the filename of kickstart :param list hosts: a list of host ["host1", "host2",] :return: a dict, formation is {"result": True|False, "description": "details"} """ # step 1, try to find an existed profile matching distro and kickstart profiles = self.list_profile_based_distro_kickstart(distro, kickstart) if profiles: profile = profiles[0] # step 2, create a new profile based on distro and kickstart else: # create a temporary name for profile profile_name = "pt_{0}".format(self.get_current_time_str()) data = { "name": profile_name, "distro": distro, "kickstart": kickstart, } result = self.rest_api.add_cobbler_profile(data) profile = profile_name if result else None if profile: return self.provision_host_with_profile(profile, hosts) return { "result": False, "description": "create profile with distro and kickstart failed.", } def add_profile_based_distro_kickstart(self, distro_url, kickstart, name): """add/create a new profile based a url of distro and a kickstart file provided for **rain provision add (--distro=URL|--kickstart=kickstart) NAME** :param string distro_url: the url for the user specified iso :param string kickstart: the absolute filename of kickstart in local computer :param string name: the name of destination profile :return: True means add/create profile successfully, otherwise failed """ result = False # step 1, upload local kickstart file to cobbler ks_name = self.upload_kickstart_to_cobbler(kickstart, name) if ks_name: # step 2, add distro to cobbler distro_data = self.rest_api.add_cobbler_distro({ "name": name, "url": distro_url, }) if distro_data: # remove the original profile result = self.rest_api.remove_cobbler_profile( distro_data["profile"]) if result: # create a new profile result = self.rest_api.add_cobbler_profile({ "name": name, "distro": distro_data["distro"], "kickstart": ks_name, }) return result def power_host(self, hosts, flag_on=True): """power ON/OFF hosts provided for **rain provision power [--off] HOSTS** :param list hosts: a list of host ["host1", "host2",] :param boolean flag_on: True means power ON, False means OFF :return: a dict of {"host1": True, "host2": False}, in which True means send power command, False means hosts MUST deploy before power """ result = {} for host in hosts: result[host] = False hosts_status = self.status.get_status_short(hosts) for host in hosts_status: if hosts_status[host] == "deployed": result[host] = True # self.rest_api.power_cobbler_system(host, flag_on) power_system.apply_async([host, flag_on], queue='cobbler') return result def monitor_host(self, hosts): """monitor the progress of deploying/powering ON/OFF of hosts provided for **rain provision monitor HOSTS** :param list hosts: a list of host ["host1", "host2",] :return: a dict of {"host1": {"status": "deploying", "progress": 25, }, "host2": {"status": "poweron", "progress": 100,}, "host3": {"status": "poweroff", "progress": 10,},} """ result = {} for host in hosts: result[host] = self.status.get_host_progress(host) return result def upload_kickstart_to_cobbler(self, filename, name=None): """add a local kickstart file to cobbler :param string filename: the local filename of kickstart file, please use the absolute path :param string name: the destination name of kickstart in cobbler :return: the name of kickstart in cobbler if added success, otherwise None """ if not name: name = filename.split("/")[-1] ext = name.split(".")[-1] if ext not in ["ks", "seed"]: name += ".ks" # read from local kickstart with open(filename) as f: lines = [line.rstrip("\n") for line in f] return self.save_kickstart_to_cobbler(lines, name) def save_kickstart_to_cobbler(self, contents, name): """save a list of string as a kickstart file to cobbler :param list contents: list of string, the conent of a kickstart file, ["line1", "line2"] :param string name: the destination name of kickstart in cobbler :return: the name of kickstart in cobbler if added success, otherwise None """ data = { "name": name, "contents": contents, } result = self.rest_api.add_cobbler_kickstart(data) return name if result else None def create_system_with_profile(self, name, profile): """ create a new system in cobbler with host information stored in inventory and profile :param string name: the unique name of host :param string profile: the profile name in cobbler, the profile MUST be exist :return:: True means create system sucefully, False means failed. """ # get all the necessary host information stored in inventory host_info = self.baremetal.get_host_info(name) if host_info: host_info["profile"] = profile return self.rest_api.add_cobbler_system(host_info) return False def update_system_with_profile(self, name, profile): """ update profile in a system :param string name: the unique name of host :param string profile: the profile name in cobbler, the profile MUST be exist :return:: True means update system sucefully, False means failed. """ data = {"name": name, "profile": profile} return self.rest_api.update_cobbler_system(data) def get_current_time_str(self): """current time, format is YYYYMMDDHHmmSSfffff """ t = datetime.now() return t.strftime("%Y%m%d%H%M%S%f")
class RainCobblerWrapper: """ provide API for CM rain command or Web Interface. """ def __init__(self): self.rest_api = CobblerRestAPI() self.baremetal = BaremetalComputer() self.status = BaremetalStatus() self.policy = BaremetalPolicy() def baremetal_computer_host_list(self): """list computers for baremetal provisioning provided for **rain admin baremetals** :return: a list of baremetal computers """ return self.baremetal.get_baremetal_computers() def baremetal_computer_host_on(self, raw_hosts): """Enable/ON computers for baremetal provisioning provided for **rain admin on HOSTS** :param string raw_hosts: ne or more hosts with the valid formation of hostlist :return: True means successfully, otherwise False """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.baremetal.enable_baremetal_computers(hosts) def baremetal_computer_host_off(self, raw_hosts): """Disable/OFF computers for baremetal provisioning provided for **rain admin off HOSTS** :param string raw_hosts: ne or more hosts with the valid formation of hostlist :return: True means successfully, otherwise False """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.baremetal.disable_baremetal_computers(hosts) def list_all_user_group_hosts(self, flag_user=True, flag_merge=False): """list all baremetal computers that can be used by each user/project. provided for **rain admin list users/projects** :param boolean flag_user: True means user, False means projects :return: a dict with the formation {"user1": "hostlist", "user2": "hostlist2"} """ if flag_user: return self.policy.get_all_user_policy(flag_merge) return self.policy.get_all_group_policy(flag_merge) def list_user_hosts(self, raw_users): """list all baremetal computers that can be used by each user. provided for **rain admin list hosts --user=USERS** :param string raw_users: one or more users with the valid formation of hostlist :return: a dict with the formation {"user1": "hostlist", "user2": "hostlist2"} """ return self.policy.get_policy_based_user(raw_users) def list_project_hosts(self, raw_projects): """list all baremetal computers that can be used by each project/group. provided for **rain admin list hosts --project=PROJECTS** :param string raw_projects: one or more projects with the valid formation of hostlist :return: a dict with the formation {"project1": "hostlist", "project2": "hostlist2"} """ return self.policy.get_policy_based_group(raw_projects) def get_policy_based_user_or_its_projects(self, user, projects): """get the merged policy based on the username and his/her related projects """ return self.policy.get_policy_based_user_or_its_projects(user, projects) def add_user_policy(self, raw_users, raw_hosts): """add a new policy for user provided for **rain admin policy --user=USERS -l HOSTS** :param string raw_users: one or more users with the valid formation of hostlist :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: None if add failed, otherwise the UUID of this policy :rtype: string """ return self.policy.add_user_policy(raw_users, raw_hosts) def add_project_policy(self, raw_projects, raw_hosts): """add a new policy for project provided for **rain admin policy --project=PROJECTS -l HOSTS** :param string raw_projects: one or more projects with the valid formation of hostlist :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: None if add failed, otherwise the UUID of this policy :rtype: string """ return self.policy.add_group_policy(raw_projects, raw_hosts) def get_status_short(self, raw_hosts=None): """get status of baremetal computer provided for **rain status --short [HOSTS]** :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: a dict of the formation {"host1": "deployed", "host2": "deploying", "host3": "failed"} """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.status.get_status_short(hosts) def get_status_summary(self, raw_hosts=None): """get status summary of baremetal computer provided for **rain status --summary [HOSTS]** :param string raw_hosts: one or more hosts with the valid formation of hostlist :return: a dict of the formation {"deployed": 1, "deploying":2, "failed":2, "total": 5} """ hosts = expand_hostlist(raw_hosts) if raw_hosts else None return self.status.get_status_summary(hosts) def provision_host_with_profile(self, profile, hosts): """ baremetal provision host in raw_hosts with profile defined in cobbler. provided for **rain provision --profile=PROFILE HOSTS** :param string profile: the name of cobbler profile :param list hosts: a list of host ["host1", "host2",] :return: a dict, formation is {"result": True|False, "description": "details"} """ FIELD_DESC = "description" result_data = {"result": False, FIELD_DESC: ""} # check the exist of the profile profiles = self.rest_api.get_cobbler_profile_list() if profile in profiles: #hosts = expand_hostlist(raw_hosts) #log.debug("after expand, raw_hosts {0} is: {1}".format(raw_hosts, hosts)) systems = self.rest_api.get_cobbler_system_list() # check the system named host exist in cobbler or not not_exist_hosts = [h for h in hosts if h not in systems] already_exist_hosts = [h for h in hosts if h in systems] log.debug("hosts is: {0}, systems is: {1}, not_exist_hosts is {2}, already_exist is {3}".format( hosts, systems, not_exist_hosts, already_exist_hosts)) result = True # create system with profile for host in not_exist_hosts for host in not_exist_hosts: result = self.create_system_with_profile(host, profile) if not result: result_data[FIELD_DESC] = "Create system for host {0} with profile {1} failed.".format( host, profile) if result: # update system with profile for host in already_exist_hosts for host in already_exist_hosts: result = self.update_system_with_profile(host, profile) if not result: result_data[FIELD_DESC] = "Update system for host {0} with profile {1} failed.".format( host, profile) if result: # provision/deploy each host for host in hosts: log.info( "call celery deploy_system on host {0} ...".format(host)) deploy_system.apply_async([host], queue='cobbler') result_data["result"] = result else: result_data[ FIELD_DESC] = "profile {0} NOT exist in cobbler.".format(profile) return result_data def list_system_based_distro_kickstart(self, distro=None, kickstart=None): """list all possible systems/hosts based on distro and kickstart provided for **rain provision list (--distro=DISTRO|--kickstart=KICKSTART)** :param string distro: the name of cobbler distro :param string kickstart: the name of kickstart file (ONLY filename) :return: a list of systems/hosts name """ profiles = self.list_profile_based_distro_kickstart(distro, kickstart) systems = [] if profiles: for profile in profiles: result = self.rest_api.get_cobbler_profile_children(profile) if result: systems.extend(result) return systems def list_profile_based_distro_kickstart(self, distro=None, kickstart=None): """list all possible profiles based on distro and kickstart provided for **rain provision list --type=profile (--distro=DISTRO|--kickstart=KICKSTART)** :param string distro: the name of cobbler distro :param string kickstart: the name of kickstart file (ONLY filename) :return: a list of profiles name """ profiles = None if distro: profiles_distro = self.rest_api.get_cobbler_distro_children(distro) profiles_ks = None if kickstart: profiles_ks = self.rest_api.get_cobbler_profile_based_kickstart( kickstart) if profiles_distro and profiles_ks: profiles = [p for p in profiles_distro if p in profiles_ks] else: profiles = profiles_distro if profiles_distro else profiles_ks else: if kickstart: profiles = self.rest_api.get_cobbler_profile_based_kickstart( kickstart) else: profiles = self.rest_api.get_cobbler_profile_list() return profiles def provision_host_with_distro_kickstart(self, distro, kickstart, hosts): """ baremetal provision host in hosts with distro defined in cobbler and kickstart file. provided for **rain provision --distro=DITRO --kickstart=KICKSTART HOSTS** :param string distro: the name of cobbler distro :param string kickstart: the filename of kickstart :param list hosts: a list of host ["host1", "host2",] :return: a dict, formation is {"result": True|False, "description": "details"} """ # step 1, try to find an existed profile matching distro and kickstart profiles = self.list_profile_based_distro_kickstart(distro, kickstart) if profiles: profile = profiles[0] # step 2, create a new profile based on distro and kickstart else: # create a temporary name for profile profile_name = "pt_{0}".format(self.get_current_time_str()) data = { "name": profile_name, "distro": distro, "kickstart": kickstart, } result = self.rest_api.add_cobbler_profile(data) profile = profile_name if result else None if profile: return self.provision_host_with_profile(profile, hosts) return {"result": False, "description": "create profile with distro and kickstart failed.", } def add_profile_based_distro_kickstart(self, distro_url, kickstart, name): """add/create a new profile based a url of distro and a kickstart file provided for **rain provision add (--distro=URL|--kickstart=kickstart) NAME** :param string distro_url: the url for the user specified iso :param string kickstart: the absolute filename of kickstart in local computer :param string name: the name of destination profile :return: True means add/create profile successfully, otherwise failed """ result = False # step 1, upload local kickstart file to cobbler ks_name = self.upload_kickstart_to_cobbler(kickstart, name) if ks_name: # step 2, add distro to cobbler distro_data = self.rest_api.add_cobbler_distro( {"name": name, "url": distro_url, }) if distro_data: # remove the original profile result = self.rest_api.remove_cobbler_profile( distro_data["profile"]) if result: # create a new profile result = self.rest_api.add_cobbler_profile( {"name": name, "distro": distro_data["distro"], "kickstart": ks_name, }) return result def power_host(self, hosts, flag_on=True): """power ON/OFF hosts provided for **rain provision power [--off] HOSTS** :param list hosts: a list of host ["host1", "host2",] :param boolean flag_on: True means power ON, False means OFF :return: a dict of {"host1": True, "host2": False}, in which True means send power command, False means hosts MUST deploy before power """ result = {} for host in hosts: result[host] = False hosts_status = self.status.get_status_short(hosts) for host in hosts_status: if hosts_status[host] == "deployed": result[host] = True #self.rest_api.power_cobbler_system(host, flag_on) power_system.apply_async([host, flag_on], queue='cobbler') return result def monitor_host(self, hosts): """monitor the progress of deploying/powering ON/OFF of hosts provided for **rain provision monitor HOSTS** :param list hosts: a list of host ["host1", "host2",] :return: a dict of {"host1": {"status": "deploying", "progress": 25, }, "host2": {"status": "poweron", "progress": 100,}, "host3": {"status": "poweroff", "progress": 10,},} """ result = {} for host in hosts: result[host] = self.status.get_host_progress(host) return result def upload_kickstart_to_cobbler(self, filename, name=None): """add a local kickstart file to cobbler :param string filename: the local filename of kickstart file, please use the absolute path :param string name: the destination name of kickstart in cobbler :return: the name of kickstart in cobbler if added success, otherwise None """ if not name: name = filename.split("/")[-1] ext = name.split(".")[-1] if ext not in ["ks", "seed"]: name += ".ks" # read from local kickstart with open(filename) as f: lines = [line.rstrip("\n") for line in f] return self.save_kickstart_to_cobbler(lines, name) def save_kickstart_to_cobbler(self, contents, name): """save a list of string as a kickstart file to cobbler :param list contents: list of string, the conent of a kickstart file, ["line1", "line2"] :param string name: the destination name of kickstart in cobbler :return: the name of kickstart in cobbler if added success, otherwise None """ data = {"name": name, "contents": contents, } result = self.rest_api.add_cobbler_kickstart(data) return name if result else None def create_system_with_profile(self, name, profile): """ create a new system in cobbler with host information stored in inventory and profile :param string name: the unique name of host :param string profile: the profile name in cobbler, the profile MUST be exist :return:: True means create system sucefully, False means failed. """ # get all the necessary host information stored in inventory host_info = self.baremetal.get_host_info(name) if host_info: host_info["profile"] = profile return self.rest_api.add_cobbler_system(host_info) return False def update_system_with_profile(self, name, profile): """ update profile in a system :param string name: the unique name of host :param string profile: the profile name in cobbler, the profile MUST be exist :return:: True means update system sucefully, False means failed. """ data = {"name": name, "profile": profile} return self.rest_api.update_cobbler_system(data) def get_current_time_str(self): """current time, format is YYYYMMDDHHmmSSfffff """ t = datetime.now() return t.strftime("%Y%m%d%H%M%S%f")