| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 #!/usr/bin/env python | 
|  | 2 # Copyright (c) 2009 Chris Moyer http://kopertop.blogspot.com/ | 
|  | 3 # | 
|  | 4 # Permission is hereby granted, free of charge, to any person obtaining a | 
|  | 5 # copy of this software and associated documentation files (the | 
|  | 6 # "Software"), to deal in the Software without restriction, including | 
|  | 7 # without limitation the rights to use, copy, modify, merge, publish, dis- | 
|  | 8 # tribute, sublicense, and/or sell copies of the Software, and to permit | 
|  | 9 # persons to whom the Software is furnished to do so, subject to the fol- | 
|  | 10 # lowing conditions: | 
|  | 11 # | 
|  | 12 # The above copyright notice and this permission notice shall be included | 
|  | 13 # in all copies or substantial portions of the Software. | 
|  | 14 # | 
|  | 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 
|  | 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | 
|  | 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | 
|  | 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | 
|  | 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
|  | 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 
|  | 21 | 
|  | 22 # | 
|  | 23 # Tools to dump and recover an SDB domain | 
|  | 24 # | 
|  | 25 VERSION = "%prog version 1.0" | 
|  | 26 import boto | 
|  | 27 import time | 
|  | 28 from boto import sdb | 
|  | 29 | 
|  | 30 # Allow support for JSON | 
|  | 31 try: | 
|  | 32     import simplejson as json | 
|  | 33 except: | 
|  | 34     try: | 
|  | 35         import json | 
|  | 36     except: | 
|  | 37         json = False | 
|  | 38 | 
|  | 39 def choice_input(options, default=None, title=None): | 
|  | 40     """ | 
|  | 41     Choice input | 
|  | 42     """ | 
|  | 43     if title == None: | 
|  | 44         title = "Please choose" | 
|  | 45     print title | 
|  | 46     objects = [] | 
|  | 47     for n, obj in enumerate(options): | 
|  | 48         print "%s: %s" % (n, obj) | 
|  | 49         objects.append(obj) | 
|  | 50     choice = int(raw_input(">>> ")) | 
|  | 51     try: | 
|  | 52         choice = objects[choice] | 
|  | 53     except: | 
|  | 54         choice = default | 
|  | 55     return choice | 
|  | 56 | 
|  | 57 def confirm(message="Are you sure?"): | 
|  | 58     choice = raw_input("%s [yN] " % message) | 
|  | 59     return choice and len(choice) > 0 and choice[0].lower() == "y" | 
|  | 60 | 
|  | 61 | 
|  | 62 def dump_db(domain, file_name, use_json=False): | 
|  | 63     """ | 
|  | 64     Dump SDB domain to file | 
|  | 65     """ | 
|  | 66     f = open(file_name, "w") | 
|  | 67     if use_json: | 
|  | 68         for item in domain: | 
|  | 69             data = {"name": item.name, "attributes": item} | 
|  | 70             print >> f, json.dumps(data) | 
|  | 71     else: | 
|  | 72         doc = domain.to_xml(f) | 
|  | 73 | 
|  | 74 def empty_db(domain): | 
|  | 75     """ | 
|  | 76     Remove all entries from domain | 
|  | 77     """ | 
|  | 78     for item in domain: | 
|  | 79         item.delete() | 
|  | 80 | 
|  | 81 def load_db(domain, file, use_json=False): | 
|  | 82     """ | 
|  | 83     Load a domain from a file, this doesn't overwrite any existing | 
|  | 84     data in the file so if you want to do a full recovery and restore | 
|  | 85     you need to call empty_db before calling this | 
|  | 86 | 
|  | 87     :param domain: The SDB Domain object to load to | 
|  | 88     :param file: The File to load the DB from | 
|  | 89     """ | 
|  | 90     if use_json: | 
|  | 91         for line in file.readlines(): | 
|  | 92             if line: | 
|  | 93                 data = json.loads(line) | 
|  | 94                 item = domain.new_item(data['name']) | 
|  | 95                 item.update(data['attributes']) | 
|  | 96                 item.save() | 
|  | 97 | 
|  | 98     else: | 
|  | 99         domain.from_xml(file) | 
|  | 100 | 
|  | 101 def create_db(domain_name, region_name): | 
|  | 102     """Create a new DB | 
|  | 103 | 
|  | 104     :param domain: Name of the domain to create | 
|  | 105     :type domain: str | 
|  | 106     """ | 
|  | 107     sdb = boto.sdb.connect_to_region(region_name) | 
|  | 108     return sdb.create_domain(domain_name) | 
|  | 109 | 
|  | 110 if __name__ == "__main__": | 
|  | 111     from optparse import OptionParser | 
|  | 112     parser = OptionParser(version=VERSION, usage="Usage: %prog [--dump|--load|--
     empty|--list|-l] [options]") | 
|  | 113 | 
|  | 114     # Commands | 
|  | 115     parser.add_option("--dump", help="Dump domain to file", dest="dump", default
     =False, action="store_true") | 
|  | 116     parser.add_option("--load", help="Load domain contents from file", dest="loa
     d", default=False, action="store_true") | 
|  | 117     parser.add_option("--empty", help="Empty all contents of domain", dest="empt
     y", default=False, action="store_true") | 
|  | 118     parser.add_option("-l", "--list", help="List All domains", dest="list", defa
     ult=False, action="store_true") | 
|  | 119     parser.add_option("-c", "--create", help="Create domain", dest="create", def
     ault=False, action="store_true") | 
|  | 120 | 
|  | 121     parser.add_option("-a", "--all-domains", help="Operate on all domains", acti
     on="store_true", default=False, dest="all_domains") | 
|  | 122     if json: | 
|  | 123         parser.add_option("-j", "--use-json", help="Load/Store as JSON instead o
     f XML", action="store_true", default=False, dest="json") | 
|  | 124     parser.add_option("-d", "--domain", help="Do functions on domain (may be mor
     e then one)", action="append", dest="domains") | 
|  | 125     parser.add_option("-f", "--file", help="Input/Output file we're operating on
     ", dest="file_name") | 
|  | 126     parser.add_option("-r", "--region", help="Region (e.g. us-east-1[default] or
      eu-west-1)", default="us-east-1", dest="region_name") | 
|  | 127     (options, args) = parser.parse_args() | 
|  | 128 | 
|  | 129     if options.create: | 
|  | 130         for domain_name in options.domains: | 
|  | 131             create_db(domain_name, options.region_name) | 
|  | 132         exit() | 
|  | 133 | 
|  | 134     sdb = boto.sdb.connect_to_region(options.region_name) | 
|  | 135     if options.list: | 
|  | 136         for db in sdb.get_all_domains(): | 
|  | 137             print db | 
|  | 138         exit() | 
|  | 139 | 
|  | 140     if not options.dump and not options.load and not options.empty: | 
|  | 141             parser.print_help() | 
|  | 142             exit() | 
|  | 143 | 
|  | 144 | 
|  | 145 | 
|  | 146 | 
|  | 147     # | 
|  | 148     # Setup | 
|  | 149     # | 
|  | 150     if options.domains: | 
|  | 151         domains = [] | 
|  | 152         for domain_name in options.domains: | 
|  | 153             domains.append(sdb.get_domain(domain_name)) | 
|  | 154     elif options.all_domains: | 
|  | 155         domains = sdb.get_all_domains() | 
|  | 156     else: | 
|  | 157         domains = [choice_input(options=sdb.get_all_domains(), title="No domain 
     specified, please choose one")] | 
|  | 158 | 
|  | 159 | 
|  | 160     # | 
|  | 161     # Execute the commands | 
|  | 162     # | 
|  | 163     stime = time.time() | 
|  | 164     if options.empty: | 
|  | 165         if confirm("WARNING!!! Are you sure you want to empty the following doma
     ins?: %s" % domains): | 
|  | 166             stime = time.time() | 
|  | 167             for domain in domains: | 
|  | 168                 print "--------> Emptying %s <--------" % domain.name | 
|  | 169                 empty_db(domain) | 
|  | 170         else: | 
|  | 171             print "Canceling operations" | 
|  | 172             exit() | 
|  | 173 | 
|  | 174     if options.dump: | 
|  | 175         for domain in domains: | 
|  | 176             print "--------> Dumping %s <---------" % domain.name | 
|  | 177             if options.file_name: | 
|  | 178                 file_name = options.file_name | 
|  | 179             else: | 
|  | 180                 file_name = "%s.db" % domain.name | 
|  | 181             dump_db(domain, file_name, options.json) | 
|  | 182 | 
|  | 183     if options.load: | 
|  | 184         for domain in domains: | 
|  | 185             print "---------> Loading %s <----------" % domain.name | 
|  | 186             if options.file_name: | 
|  | 187                 file_name = options.file_name | 
|  | 188             else: | 
|  | 189                 file_name = "%s.db" % domain.name | 
|  | 190             load_db(domain, open(file_name, "rb"), options.json) | 
|  | 191 | 
|  | 192 | 
|  | 193     total_time = round(time.time() - stime, 2) | 
|  | 194     print "--------> Finished in %s <--------" % total_time | 
| OLD | NEW | 
|---|