def wmSaveMyAccount(self): """ In this method, the values come from the browser in a jQuery serialized array of name/value pairs. """ user_id = uiCommon.GetSessionUserID() args = uiCommon.getAjaxArg("values") u = catouser.User() u.FromID(user_id) if u.ID: # if a password was provided... # these changes are done BEFORE we manipulate the user properties for update. new_pw = uiCommon.unpackJSON(args.get("my_password")) if new_pw: u.ChangePassword(new_password=new_pw) uiCommon.WriteObjectChangeLog(catocommon.CatoObjectTypes.User, u.ID, u.FullName, "Password changed.") # now the other values... u.Email = args.get("my_email") u.SecurityQuestion = args.get("my_question") u.SecurityAnswer = uiCommon.unpackJSON(args.get("my_answer")) if u.DBUpdate(): uiCommon.WriteObjectChangeLog(catocommon.CatoObjectTypes.User, u.ID, u.ID, "User updated.") return json.dumps({"result": "success"})
def wmSavePlan(self): iPlanID = uiCommon.getAjaxArg("iPlanID") sParameterXML = uiCommon.getAjaxArg("sParameterXML") iDebugLevel = uiCommon.getAjaxArg("iDebugLevel") """ * JUST AS A REMINDER: * There is no parameter 'merging' happening here. This is a Plan ... * it has ALL the parameters it needs to pass to the CE. * * """ if not iPlanID: uiCommon.log("Missing Action Plan ID.") # we encoded this in javascript before the ajax call. # the safest way to unencode it is to use the same javascript lib. # (sometimes the javascript and .net libs don't translate exactly, google it.) sParameterXML = uiCommon.unpackJSON(sParameterXML) # we gotta peek into the XML and encrypt any newly keyed values sParameterXML = task.Task.PrepareAndEncryptParameterXML(sParameterXML) sSQL = """update action_plan set parameter_xml = %s, debug_level = %s where plan_id = %s""" self.db.exec_db(sSQL, (sParameterXML, iDebugLevel if iDebugLevel > -1 else None, iPlanID)) return json.dumps({"result": "success"})
def wmUpdateDeploymentDetail(self): sDeploymentID = uiCommon.getAjaxArg("id") sColumn = uiCommon.getAjaxArg("column") sValue = uiCommon.getAjaxArg("value") sUserID = uiCommon.GetSessionUserID() if catocommon.is_guid(sDeploymentID) and catocommon.is_guid(sUserID): d = deployment.Deployment() d.FromID(sDeploymentID) # we encoded this in javascript before the ajax call. # the safest way to unencode it is to use the same javascript lib. # (sometimes the javascript and .net libs don't translate exactly, google it.) sValue = uiCommon.unpackJSON(sValue) # check for existing name if sColumn == "Name": if d.Name == sValue: return sValue + " exists, please choose another name." # cool, update the class attribute by name, using getattr! # python is so cool.. I don't even need to check if the attribute I wanna set exists. # just set it setattr(d, sColumn, sValue) d.DBUpdate() uiCommon.WriteObjectChangeLog(catocommon.CatoObjectTypes.Deployment, sDeploymentID, sColumn, sValue) return json.dumps({"result": "success"})
def wmRunRepeatedly(self): sTaskID = uiCommon.getAjaxArg("sTaskID") aMonths = uiCommon.getAjaxArg("sMonths") aDays = uiCommon.getAjaxArg("sDays") aHours = uiCommon.getAjaxArg("sHours") aMinutes = uiCommon.getAjaxArg("sMinutes") sDaysOrWeeks = uiCommon.getAjaxArg("sDaysOrWeeks") sParameterXML = uiCommon.getAjaxArg("sParameterXML") iDebugLevel = uiCommon.getAjaxArg("iDebugLevel") sAccountID = uiCommon.getAjaxArg("sAccountID") # we encoded this in javascript before the ajax call. # the safest way to unencode it is to use the same javascript lib. # (sometimes the javascript and .net libs don't translate exactly, google it.) sParameterXML = uiCommon.unpackJSON(sParameterXML) sched_def = { "Months": aMonths, "Days": aDays, "Hours": aHours, "Minutes": aMinutes, "DaysOrWeekdays": sDaysOrWeeks } t = task.Task() t.FromID(sTaskID) t.RunRepeatedly(sched_def, sParameterXML, iDebugLevel, sAccountID)
def wmCreateTemplate(self): name = uiCommon.getAjaxArg("name") version = uiCommon.getAjaxArg("version") desc = uiCommon.getAjaxArg("desc") template = uiCommon.getAjaxArg("template") t = deployment.DeploymentTemplate.DBCreateNew(name, version, uiCommon.unpackJSON(template), uiCommon.unpackJSON(desc)) if t is not None: # create matching tags... this template gets all the tags this user has. uiCommon.WriteObjectAddLog(catocommon.CatoObjectTypes.Deployment, t.ID, t.Name, "Deployment Template created.") return json.dumps({"template_id": t.ID})
def wmUpdateUser(self): """ Updates a user. Will only update the values passed to it. """ user_role = uiCommon.GetSessionUserRole() if user_role != "Administrator": raise Exception("Only Administrators can edit user accounts.") args = uiCommon.getAjaxArgs() u = catouser.User() u.FromID(args["ID"]) if u.ID: # these changes are done BEFORE we manipulate the user properties for update. new_pw = uiCommon.unpackJSON(args.get("Password")) random_pw = args.get("NewRandomPassword") # if a password was provided, or the random flag was set...exclusively if new_pw: # if the user requesting the change *IS* the user being changed... # set force_change to False force = True if u.ID == uiCommon.GetSessionUserID(): force = False u.ChangePassword(new_password=new_pw, force_change=force) uiCommon.WriteObjectChangeLog(catocommon.CatoObjectTypes.User, u.ID, u.FullName, "Password changed.") elif random_pw: u.ChangePassword(generate=random_pw) uiCommon.WriteObjectChangeLog(catocommon.CatoObjectTypes.User, u.ID, u.FullName, "Password reset.") # now we can change the properties u.LoginID = args.get("LoginID") u.FullName = args.get("FullName") u.Status = args.get("Status") u.AuthenticationType = args.get("AuthenticationType") u.ForceChange = args.get("ForceChange") u.Email = args.get("Email") u.Role = args.get("Role") u.FailedLoginAttempts = args.get("FailedLoginAttempts") u.Expires = args.get("Expires") u._Groups = args.get("Groups") if u.DBUpdate(): uiCommon.WriteObjectChangeLog(catocommon.CatoObjectTypes.User, u.ID, u.ID, "User updated.") return json.dumps({"result": "success"})
def wmRunLater(self): sTaskID = uiCommon.getAjaxArg("sTaskID") sRunOn = uiCommon.getAjaxArg("sRunOn") sParameterXML = uiCommon.getAjaxArg("sParameterXML") iDebugLevel = uiCommon.getAjaxArg("iDebugLevel") sAccountID = uiCommon.getAjaxArg("sAccountID") # we encoded this in javascript before the ajax call. # the safest way to unencode it is to use the same javascript lib. # (sometimes the javascript and .net libs don't translate exactly, google it.) sParameterXML = uiCommon.unpackJSON(sParameterXML) t = task.Task() t.FromID(sTaskID) t.RunLater(sRunOn, sParameterXML, iDebugLevel, sAccountID)
def wmSaveSchedule(self): sScheduleID = uiCommon.getAjaxArg("sScheduleID") aMonths = uiCommon.getAjaxArg("sMonths") aDays = uiCommon.getAjaxArg("sDays") aHours = uiCommon.getAjaxArg("sHours") aMinutes = uiCommon.getAjaxArg("sMinutes") sDaysOrWeeks = uiCommon.getAjaxArg("sDaysOrWeeks") sParameterXML = uiCommon.getAjaxArg("sParameterXML") iDebugLevel = uiCommon.getAjaxArg("iDebugLevel") """ * JUST AS A REMINDER: * There is no parameter 'merging' happening here. This is a Scheduled Plan ... * it has ALL the parameters it needs to pass to the CE. * * """ if not sScheduleID or not aMonths or not aDays or not aHours or not aMinutes or not sDaysOrWeeks: uiCommon.log("Missing Schedule ID or invalid timetable.") # we encoded this in javascript before the ajax call. # the safest way to unencode it is to use the same javascript lib. # (sometimes the javascript and .net libs don't translate exactly, google it.) sParameterXML = uiCommon.unpackJSON(sParameterXML) # we gotta peek into the XML and encrypt any newly keyed values sParameterXML = task.Task.PrepareAndEncryptParameterXML(sParameterXML) # whack all plans for this schedule, it's been changed sSQL = "delete from action_plan where schedule_id = '" + sScheduleID + "'" self.db.exec_db(sSQL) # figure out a label sLabel, sDesc = catocommon.GenerateScheduleLabel(aMonths, aDays, aHours, aMinutes, sDaysOrWeeks) sSQL = "update action_schedule set" \ " months = '" + ",".join([str(x) for x in aMonths]) + "'," \ " days = '" + ",".join([str(x) for x in aDays]) + "'," \ " hours = '" + ",".join([str(x) for x in aHours]) + "'," \ " minutes = '" + ",".join([str(x) for x in aMinutes]) + "'," \ " days_or_weeks = '" + sDaysOrWeeks + "'," \ " label = " + ("'" + sLabel + "'" if sLabel else "null") + "," \ " descr = " + ("'" + sDesc + "'" if sDesc else "null") + "," \ " parameter_xml = " + ("'" + catocommon.tick_slash(sParameterXML) + "'" if sParameterXML else "null") + "," \ " debug_level = " + (iDebugLevel if iDebugLevel > -1 else "null") + \ " where schedule_id = '" + sScheduleID + "'" self.db.exec_db(sSQL)
def wmSaveKeyPair(self): sKeypairID = uiCommon.getAjaxArg("sKeypairID") sCloudID = uiCommon.getAjaxArg("sCloudID") sName = uiCommon.getAjaxArg("sName") sPK = uiCommon.getAjaxArg("sPK") sPP = uiCommon.getAjaxArg("sPP") sPK = uiCommon.unpackJSON(sPK) c = cloud.Cloud() c.FromID(sCloudID) if not sKeypairID: # keypair_id not passed in, create a new one... c.AddKeyPair(sName, sPK, sPP) else: c.SaveKeyPair(sKeypairID, sName, sPK, sPP) return json.dumps({"result": "success"})
def wmUpdateTemplateDetail(self): sTemplateID = uiCommon.getAjaxArg("id") sColumn = uiCommon.getAjaxArg("column") sValue = uiCommon.getAjaxArg("value") dt = deployment.DeploymentTemplate() dt.FromID(sTemplateID) # we encoded this in javascript before the ajax call. # the safest way to unencode it is to use the same javascript lib. # (sometimes the javascript and .net libs don't translate exactly, google it.) sValue = uiCommon.unpackJSON(sValue) # cool, update the class attribute by name, using getattr! # python is so cool.. I don't even need to check if the attribute I wanna set exists. # just set it setattr(dt, sColumn, sValue) dt.DBUpdate() uiCommon.WriteObjectChangeLog(catocommon.CatoObjectTypes.DeploymentTemplate, sTemplateID, sColumn, sValue) return json.dumps({"result": "success"})
def wmCreateObjectFromXML(self): """Takes a properly formatted XML backup file, and imports each object.""" inputtext = uiCommon.getAjaxArg("import_text") inputtext = uiCommon.unpackJSON(inputtext) on_conflict = uiCommon.getAjaxArg("on_conflict") # the trick here is to return enough information back to the client # to best interact with the user. # what types of things were in this backup? what are their new ids? items = [] # parse it as a validation, and to find out what's in it. xd = None js = None try: xd = catocommon.ET.fromstring(inputtext) except catocommon.ET.ParseError: try: js = json.loads(inputtext) except: return json.dumps({"error": "Data is not properly formatted XML or JSON."}) if xd is not None: # so, what's in here? Tasks? # TASKS for xtask in xd.findall("task"): uiCommon.log("Importing Task [%s]" % xtask.get("name", "Unknown")) t = task.Task() t.FromXML(catocommon.ET.tostring(xtask), on_conflict) # NOTE: possible TODO # passing a db connection to task.DBSave will allow rollback of a whole # batch of task additions. # if it's determined that's necessary here, just create a db connection here # and pass it in result, err = t.DBSave() if result: # add security log uiCommon.WriteObjectAddLog(catocommon.CatoObjectTypes.Task, t.ID, t.Name, "Created by import.") items.append({"type": "task", "id": t.ID, "name": t.Name}) else: if err: items.append({"type": "task", "id": t.ID, "name": t.Name, "info": err}) else: items.append({"type": "task", "id": t.ID, "name": t.Name, "error": "Unable to create Task. No error available."}) # otherwise it might have been JSON elif js is not None: # if js isn't a list, bail... if not isinstance(js, list): js = [js] for jstask in js: uiCommon.log("Importing Task [%s]" % jstask.get("Name", "Unknown")) t = task.Task() t.FromJSON(json.dumps(jstask), on_conflict) result, err = t.DBSave() if result: # add security log uiCommon.WriteObjectAddLog(catocommon.CatoObjectTypes.Task, t.ID, t.Name, "Created by import.") items.append({"type": "task", "id": t.ID, "name": t.Name}) else: if err: items.append({"type": "task", "id": t.ID, "name": t.Name, "info": err}) else: items.append({"type": "task", "id": t.ID, "name": t.Name, "error": "Unable to create Task. No error available."}) else: items.append({"info": "Unable to create Task from backup JSON/XML."}) # TODO: for loop for Assets will go here, same logic as above # ASSETS return json.dumps({"items": items})
def wmAnalyzeImportXML(self): """Takes a properly formatted XML backup file, and replies with the existence/condition of each Task.""" inputtext = uiCommon.getAjaxArg("import_text") inputtext = uiCommon.unpackJSON(inputtext) on_conflict = uiCommon.getAjaxArg("on_conflict") # the trick here is to return enough information back to the client # to best interact with the user. # what types of things were in this backup? what are their new ids? items = [] # parse it as a validation, and to find out what's in it. xd = None js = None try: xd = catocommon.ET.fromstring(inputtext) except catocommon.ET.ParseError as ex: uiCommon.log("Data is not valid XML... trying JSON...") try: js = json.loads(inputtext) except Exception as ex: uiCommon.log(ex) return json.dumps({"error": "Data is not properly formatted XML or JSON."}) # if the submitted data was XML if xd is not None: # so, what's in here? Tasks? # TASKS for xtask in xd.findall("task"): t = task.Task() t.FromXML(catocommon.ET.tostring(xtask)) if t.DBExists and t.OnConflict == "cancel": msg = "Task exists - set 'on_conflict' attribute to 'replace', 'minor' or 'major'." elif t.OnConflict == "replace": msg = "Will be replaced." elif t.OnConflict == "minor" or t.OnConflict == "major": msg = "Will be versioned up." else: msg = "Will be created." items.append({"type": "task", "id": t.ID, "name": t.Name, "info": msg}) # otherwise it might have been JSON elif js is not None: # if js isn't a list, bail... if not isinstance(js, list): return json.dumps({"error": "JSON data must be a list of Tasks."}) for jstask in js: t = task.Task() t.FromJSON(json.dumps(jstask), on_conflict) if t.DBExists and t.OnConflict == "cancel": msg = "Task exists - set OnConflict to 'replace', 'minor' or 'major'." elif t.OnConflict == "replace": msg = "Will be replaced." elif t.OnConflict == "minor" or t.OnConflict == "major": msg = "Will be versioned up." else: msg = "Will be created." items.append({"type": "task", "id": t.ID, "name": t.Name, "info": msg}) else: items.append({"info": "Unable to create Task from backup JSON/XML."}) return json.dumps({"items": items})