WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-api

[Xen-API] [PATCH 13 of 21] CP-1841: add new api call vmpp.get_alerts

To: xen-api <xen-api@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-API] [PATCH 13 of 21] CP-1841: add new api call vmpp.get_alerts
From: Marcus Granado <marcus.granado@xxxxxxxxxx>
Date: Fri, 20 Aug 2010 17:52:32 +0100
Delivery-date: Fri, 20 Aug 2010 10:42:57 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1282323139@localhost>
List-help: <mailto:xen-api-request@lists.xensource.com?subject=help>
List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>
List-post: <mailto:xen-api@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1282323139@localhost>
Sender: xen-api-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.4.3
 ocaml/idl/datamodel.ml                |  12 ++++++
 ocaml/idl/ocaml_backend/rbac_audit.ml |  26 ++++---------
 ocaml/xapi/audit_log.ml               |  22 +++++++++--
 ocaml/xapi/xapi_vm_clone.ml           |   2 +-
 ocaml/xapi/xapi_vmpp.ml               |  64 +++++++++++++++++++++++++++++++++++
 scripts/mail-alarm                    |  28 ++++++++++++++-
 6 files changed, 129 insertions(+), 25 deletions(-)


# HG changeset patch
# User Marcus Granado <marcus.granado@xxxxxxxxxx>
# Date 1282322886 -3600
# Node ID 69e3ee3fb691d14532504fa5014451a9fad58be6
# Parent  f8298e1caacd3a2a5323388ac9d44a4ae12bf98d
CP-1841: add new api call vmpp.get_alerts

Signed-off-by: Marcus Granado <marcus.granado@xxxxxxxxxxxxx>

diff -r f8298e1caacd -r 69e3ee3fb691 ocaml/idl/datamodel.ml
--- a/ocaml/idl/datamodel.ml
+++ b/ocaml/idl/datamodel.ml
@@ -5875,6 +5875,17 @@
   ~allowed_roles:_R_VM_POWER_ADMIN
   ~result:(String, "An XMLRPC result")
   ()
+let vmpp_get_alerts = call ~flags:[`Session]
+  ~name:"get_alerts"
+  ~in_oss_since:None
+  ~in_product_since:rel_cowley
+  ~params:[Ref _vmpp, "vmpp", "The protection policy";
+    DateTime, "since", "oldest record to fetch";
+  ]
+  ~doc:"This call fetches a history of alerts for a given protection policy"
+  ~allowed_roles:_R_POOL_OP
+  ~result:(Set (String), "A list of alerts encoded in xml")
+  ()
 let vmpp_backup_type = Enum ("vmpp_backup_type",
   [
     "snapshot", "The backup is a snapshot";
@@ -6105,6 +6116,7 @@
     ~messages:[
       vmpp_protect_now;
       vmpp_archive_now;
+      vmpp_get_alerts;
       vmpp_set_is_backup_running;
       vmpp_set_is_archive_running;
       vmpp_set_backup_frequency;
diff -r f8298e1caacd -r 69e3ee3fb691 ocaml/idl/ocaml_backend/rbac_audit.ml
--- a/ocaml/idl/ocaml_backend/rbac_audit.ml
+++ b/ocaml/idl/ocaml_backend/rbac_audit.ml
@@ -81,26 +81,14 @@
 let get_subject_name __context session_id =
        get_subject_common ~__context ~session_id
                ~fnname:"get_subject_name"
-               ~fn_if_local_session:(fun()->"")
-               ~fn_if_local_superuser:(fun()->"")
+               ~fn_if_local_session:(fun()->
+                               DB_Action.Session.get_auth_user_name ~__context 
~self:session_id
+               )
+               ~fn_if_local_superuser:(fun()->
+                               DB_Action.Session.get_auth_user_name ~__context 
~self:session_id
+               )
                ~fn_if_subject:(fun()->
                                DB_Action.Session.get_auth_user_name ~__context 
~self:session_id
-                       (*
-                       let sid =
-                               DB_Action.Session.get_auth_user_sid ~__context 
~self:session_id
-                       in
-                       let subjs = DB_Action.Subject.get_records_where 
~__context
-                               ~expr:(Eq(Field "subject_identifier", Literal 
(sid)))
-                       in
-                       if List.length subjs > 1 then
-                               failwith (Printf.sprintf
-                                       "More than one subject for 
subject_identifier %s"sid
-                               );
-                       let (subj_id,subj) = List.hd subjs in
-                       List.assoc
-                               "subject-name" 
(*Auth_signature.subject_information_field_subject_name*)
-                               subj.API.subject_other_config
-                       *)
                )
 
 (*given a ref-value, return a human-friendly value associated with that ref*)
@@ -209,6 +197,8 @@
                ("host.enable_external_auth",["service_name";"auth_type"]);
                ("subject.create",["subject_identifier";"other_config"]);
                ("subject.create.other_config",["subject-name"]);
+    (* used for VMPP alert logs *)
+    ("message.create",["name";"body"]);
        ]
 
 (* manual ref getters *)
diff -r f8298e1caacd -r 69e3ee3fb691 ocaml/xapi/audit_log.ml
--- a/ocaml/xapi/audit_log.ml
+++ b/ocaml/xapi/audit_log.ml
@@ -26,7 +26,16 @@
 let timestamp_index line = 
        try ((String.index line '[') + 1) with Not_found -> 0
 
-let write_line line fd since =
+let went_through ?filter line =
+       match filter with
+       |None->true
+       |Some fs->
+                List.fold_left
+                        (fun acc f->acc&&(String.has_substr line f))
+                        true
+       fs
+
+let write_line line fd ?filter since =
        if String.length line >
                (line_timestamp_length + (timestamp_index line))
        then
@@ -35,10 +44,12 @@
        in
        if since="" or ((String.compare line_timestamp since) >= 0)
        then
+       if went_through ?filter line
+  then
        let len = String.length line in
        ignore(Unix.write fd line 0 len)
 
-let transfer_audit_file _path compression fd_out since =
+let transfer_audit_file _path compression fd_out ?filter since =
        let path = Unixext.resolve_dot_and_dotdot _path in
        let in_whitelist = (String.startswith audit_log_whitelist_prefix path) 
in
        if in_whitelist then
@@ -50,7 +61,7 @@
                        if compression="" (* uncompressed *)
                        then begin
                                Unixext.readfile_line
-                                       (fun line -> write_line (line^"\n") 
fd_out since)
+                                       (fun line -> write_line (line^"\n") 
fd_out ?filter since)
                                        path
                        end
                        else if compression="gz"
@@ -63,7 +74,7 @@
                                                                try
                                                                        while 
true do
                                                                                
let line = input_line cin in
-                                                                               
write_line (line^"\n") fd_out since
+                                                                               
write_line (line^"\n") fd_out ?filter since
                                                                        done
                                                                with 
End_of_file -> () (* ok, expected *)
                                                        )
@@ -79,7 +90,7 @@
                end
        end
 
-let transfer_all_audit_files fd_out since =
+let transfer_all_audit_files fd_out ?filter since =
        let atransfer _infix _suffix =
                let infix = if _infix="" then "" else "."^_infix in
                let suffix = if _suffix="" then "" else "."^_suffix in
@@ -87,6 +98,7 @@
                        (audit_log_whitelist_prefix^infix^suffix)
                        _suffix
                        fd_out
+                       ?filter
                        since
        in
        let atransfer_try_gz infix =
diff -r f8298e1caacd -r 69e3ee3fb691 ocaml/xapi/xapi_vm_clone.ml
--- a/ocaml/xapi/xapi_vm_clone.ml
+++ b/ocaml/xapi/xapi_vm_clone.ml
@@ -254,7 +254,7 @@
       (let session = Context.get_session_id __context in
        let uname = Db.Session.get_auth_user_name ~__context ~self:session in
        let is_lsu = Db.Session.get_is_local_superuser ~__context ~self:session 
in
-       is_lsu && (uname = "__dom0__vmpr")
+       is_lsu && (uname = Xapi_vmpp.vmpr_username)
       )
                with e ->
       debug "Error obtaining is_snapshot_from_vmpp: %s" (Printexc.to_string e);
diff -r f8298e1caacd -r 69e3ee3fb691 ocaml/xapi/xapi_vmpp.ml
--- a/ocaml/xapi/xapi_vmpp.ml
+++ b/ocaml/xapi/xapi_vmpp.ml
@@ -15,6 +15,7 @@
 open D
 
 let vmpr_plugin = "vmpr"
+let vmpr_username = "__dom0__vmpr"
 
 let protect_now ~__context ~vmpp = 
   let vmpp_uuid = Db.VMPP.get_uuid ~__context ~self:vmpp in
@@ -34,6 +35,69 @@
     "archive_now"
     args
 
+let add_alert ~__context ~vmpp ~name ~priority ~body =
+  ()
+
+let get_alerts ~__context ~vmpp ~since =
+  let vmpp_uuid = Db.VMPP.get_uuid ~__context ~self:vmpp in
+  let filter=["unix-RPC|message.create";vmpr_username;vmpp_uuid] in
+  let tmp_filename = Filename.temp_file "vmpp-alerts-" ".dat" in
+  let fd = Unix.openfile tmp_filename [Unix.O_RDWR] 0o600 in
+  let since = Date.to_string since in
+  let messages=Audit_log.transfer_all_audit_files fd ~filter since in
+  let cout = Unix.out_channel_of_descr fd in
+  flush cout;
+  let cin = Unix.in_channel_of_descr fd in
+  seek_in cin 0;
+  let lines = ref [] in
+  let i = ref 0 in (* hard limit on maximum number of lines to parse *)
+  (try while !i<1000 do let line = input_line cin in lines:=line::!lines; 
i:=!i+1 done with End_of_file->());
+       let lines = !lines in
+  Unix.close fd;
+  Sys.remove tmp_filename;
+  let alerts = List.map (fun line->
+    let sexpr_init = try (String.index line ']')+1 with Not_found -> -1 in
+    if sexpr_init>=0 && sexpr_init<(String.length line) then (
+                       let sexpr_str = Stringext.String.sub_to_end line 
sexpr_init in
+                       let (sroot:SExpr.t) = 
+        (try SExpr_TS.of_string sexpr_str
+        with e->
+          debug "error %s parsing sexpr: %s"
+            (ExnHelper.string_of_exn e) sexpr_str
+          ;
+          (SExpr.Node [])
+        )
+      in
+      match sroot with
+                       |SExpr.Node (SExpr.String _::SExpr.String 
_::SExpr.String _::SExpr.String _::SExpr.String _::SExpr.String _::SExpr.String 
_::SExpr.Node params::[])->(
+        let kvs = List.fold_right (fun (sexpr:SExpr.t) acc ->
+        match sexpr with
+                                 |SExpr.Node (SExpr.String name::SExpr.String 
value::SExpr.String _::SExpr.String _::[]) when name="name" or name="body"->
+            (name,value)::acc
+          |_->acc
+        ) params []
+        in
+        if kvs=[] then None else Some kvs
+                       )
+                       |_->None
+               )
+    else None
+       ) lines
+  in
+  let alerts = List.fold_right (fun a acc->match a with None->acc|Some 
a->a::acc) alerts [] in
+  let inside_data_tag str =
+    let tag_begin="<data>" and tag_end="</data>" in
+    let tag_begin_idx=try List.hd (Stringext.String.find_all tag_begin str) 
with _-> -1 in
+    let tag_end_idx=try List.hd (List.rev (Stringext.String.find_all tag_end 
str)) with _-> -1 in
+    try
+      let start=(tag_begin_idx+(String.length tag_begin)) in
+      let len=tag_end_idx - start in
+      Some (String.sub str start len)
+    with _->None
+  in
+  let alerts = List.fold_right (fun a acc->if List.mem_assoc "body" a then 
(let data=inside_data_tag(List.assoc "body" a) in match data with 
None->acc|Some data->data::acc) else acc) alerts [] in
+  alerts
+
 let set_is_backup_running ~__context ~self ~value =
   Db.VMPP.set_is_backup_running ~__context ~self ~value
 
diff -r f8298e1caacd -r 69e3ee3fb691 scripts/mail-alarm
--- a/scripts/mail-alarm
+++ b/scripts/mail-alarm
@@ -17,6 +17,7 @@
 import traceback
 import syslog
 from xml.dom import minidom
+from xml.sax.saxutils import unescape
 from xml.parsers.expat import ExpatError
 from socket import getfqdn
 
@@ -286,6 +287,29 @@
             'This alarm is set to be triggered when a host belonging to a high 
availability pool fails.' \
             '\n' % self.text
 
+class VmppETG(EmailTextGenerator):
+    def __init__(self, msg):
+        self.msg = msg
+
+    def generate_subject(self):
+        msg = self.msg
+        return "[%s] XenServer Message: %s %s %s" % (msg.pool_name, msg.cls, 
msg.obj_uuid, msg.name)
+
+    def generate_body(self):
+        msg = self.msg
+        msg_body = unescape(msg.body)
+        try:
+            xmldoc = minidom.parseString(msg_body)
+            body_message = xmldoc.getElementsByTagName('message')[0]
+            email_message = 
body_message.getElementsByTagName('email')[0].firstChild.data
+            return \
+            
"Field\t\tValue\n-----\t\t-----\nName:\t\t%s\nPriority:\t%s\nClass:\t\t%s\n" \
+            "Object UUID:\t%s\nTimestamp:\t%s\nMessage UUID:\t%s\nPool 
name:\t%s\nBody:\t\t%s\n" % \
+            
(msg.name,msg.priority,msg.cls,msg.obj_uuid,msg.timestamp,msg.uuid,msg.pool_name,email_message)
+        except:
+            log_err("Badly formatted XML, or missing field")
+            sys.exit(1)
+
 class XapiMessage:
     def __init__(self, xml):
         "Parse message XML"
@@ -322,7 +346,9 @@
         if hasattr(self,'cached_etg'):
             return self.cached_etg
 
-        if self.name == 'ALARM':
+        if self.cls == 'VMPP':
+            etg = VmppETG(self)
+        elif self.name == 'ALARM':
             # Extract the current level of the variable
             # (this will raise an exception if the 1st line of <body> is not 
in the correct format, namely "value: %f\n")
             value_line = self.body.split("\n",2)[0]

Attachment: xen-api.hg-13.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api