# HG changeset patch
# User Dejan Muhamedagic <dejan@hello-penguin.com>
# Date 1314872213 -7200
# Node ID 9b07d41c73b456e8189fea757a5c3d9e5b32512d
# Parent  825cb3e79d7bc1c4ac30468f8c028c9129d00541
High: Shell: geo-cluster support commands

diff --git a/doc/crm.8.txt b/doc/crm.8.txt
--- a/doc/crm.8.txt
+++ b/doc/crm.8.txt
@@ -1133,6 +1133,31 @@ Example:
         status-attr node_1 show pingd
 ...............
 
+[[cmdhelp_site,site support]]
+=== `site`
+
+A cluster may consist of two or more subclusters in different and
+distant locations. This set of commands supports such setups.
+
+[[cmdhelp_site_ticket,manage site tickets]]
+==== `ticket`
+
+Tickets are cluster-wide attributes. They can be managed at the
+site where this command is executed.
+
+It is then possible to constrain resources depending on the
+ticket availability (see the <<cmdhelp_configure_rsc_ticket,`rsc_ticket`>> command
+for more details).
+
+Usage:
+...............
+        ticket {grant|revoke|show|time|delete} <ticket>
+...............
+Example:
+...............
+        ticket grant ticket1
+...............
+
 [[cmdhelp_options,user preferences]]
 === `options`
 
@@ -1652,6 +1677,8 @@ resource (or resources) if the ticket is
 either `stop` or `demote` depending on whether a resource is
 multi-state.
 
+See also the <<cmdhelp_site_ticket,`site`>> set of commands.
+
 Usage:
 ...............
         rsc_ticket <id> <ticket_id>: <rsc>[:<role>] [<rsc>[:<role>] ...]
diff --git a/shell/modules/completion.py b/shell/modules/completion.py
--- a/shell/modules/completion.py
+++ b/shell/modules/completion.py
@@ -173,6 +173,10 @@ def report_pe_list_peinputs(idx,delimite
     if delimiter:
         return ' '
     return crm_report.peinputs_list() + ["v"]
+def ticket_cmd_list(idx,delimiter = False):
+    if delimiter:
+        return ' '
+    return ["grant","revoke","show","time","delete"]
 
 #
 # completion for primitives including help for parameters
@@ -488,6 +492,9 @@ completer_lists = {
         "peinputs" : (report_pe_list_peinputs,loop),
         "transition" : (report_pe_list_transition,),
     },
+    "site" : {
+        "ticket" : (ticket_cmd_list,),
+    },
 }
 def get_completer_list(level,cmd):
     'Return a list of completer functions.'
diff --git a/shell/modules/ui.py.in b/shell/modules/ui.py.in
--- a/shell/modules/ui.py.in
+++ b/shell/modules/ui.py.in
@@ -1938,6 +1938,61 @@ Examine Pacemaker's history: node and re
             crm_report.show_transition_log(f)
         return rc
 
+class Site(UserInterface):
+    '''
+    The site class
+    '''
+    lvl_name = "site"
+    desc_short = "Geo-cluster support"
+    desc_long = """
+The site level.
+
+Geo-cluster related management.
+"""
+    crm_ticket =  {
+        'grant': "crm_ticket -t '%s' -v true",
+        'revoke': "crm_ticket -t '%s' -v false",
+        'delete': "crm_ticket -t '%s' -D",
+        'show': "crm_ticket -t '%s' -G",
+        'time': "crm_ticket -t '%s' -T",
+    }
+    def __init__(self):
+        UserInterface.__init__(self)
+        self.cmd_table["ticket"] = (self.ticket,(2,2),1,0)
+    def ticket(self, cmd, subcmd, ticket):
+        "usage: ticket {grant|revoke|show|time|delete} <ticket>"
+        try:
+            attr_cmd = self.crm_ticket[subcmd]
+        except:
+            bad_usage(cmd,'%s %s' % (subcmd, ticket))
+            return False
+        if not is_name_sane(ticket):
+            return False
+        if subcmd not in ("show", "time"):
+            return ext_cmd(attr_cmd % ticket) == 0
+        l = stdout2list(attr_cmd % ticket)
+        try:
+            val = l[0].split('=')[3]
+        except:
+            common_warn("apparently nothing to show for ticket %s" % ticket)
+            return False
+        if subcmd == "show":
+            if val == "false":
+                print "ticket %s is revoked" % ticket
+            elif val == "true":
+                print "ticket %s is granted" % ticket
+            else:
+                common_warn("unexpected value for ticket %s: %s" % (ticket, val))
+                return False
+        else: # time
+            if not is_int(val):
+                common_warn("unexpected value for ticket %s: %s" % (ticket, val))
+                return False
+            if val == "-1":
+                print "%s: no such ticket" % ticket
+                return False
+            print "ticket %s last time granted on %s" % (ticket, time.ctime(int(val)))
+
 class TopLevel(UserInterface):
     '''
     The top level.
@@ -1959,6 +2014,7 @@ class TopLevel(UserInterface):
         self.cmd_table['node'] = NodeMgmt
         self.cmd_table['options'] = CliOptions
         self.cmd_table['history'] = History
+        self.cmd_table['site'] = Site
         self.cmd_table['status'] = (self.status,(0,5),0,0)
         self.cmd_table['ra'] = RA
         setup_aliases(self)