-
Notifications
You must be signed in to change notification settings - Fork 6
/
ams
executable file
·197 lines (164 loc) · 8.18 KB
/
ams
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/usr/bin/env python
# PYTHON_ARGCOMPLETE_OK
import argparse
import argcomplete
import pymysql.cursors
import inspect
import os
import logging
from amslib.core.version import DATABASE_VERSION
from amslib.core.completion import ArgumentCompletion
from amslib.ebs.volume import VolumeManager
from amslib.ebs.snapshot import SnapshotManager
from amslib.instance.instance import InstanceManager
from amslib.network.route53 import Route53Manager
from amslib.network.general import NetworkManager
from amslib.network.vpc import VpcManager
from amslib.core.config import Config
import pprint
settings = Config()
settings.register_module(VolumeManager(settings))
settings.register_module(SnapshotManager(settings))
settings.register_module(InstanceManager(settings))
settings.register_module(Route53Manager(settings))
settings.register_module(NetworkManager(settings))
settings.register_module(VpcManager(settings))
amsroot = os.path.realpath(os.path.abspath(inspect.getframeinfo(inspect.currentframe()).filename))
def upgrade_db(args):
dbconn = pymysql.connect(host=settings.TRACKING_DB['host'],
port=settings.TRACKING_DB['port'],
user=settings.TRACKING_DB['user'],
password=settings.TRACKING_DB['pass'],
db=settings.TRACKING_DB['dbname'])
db = dbconn.cursor()
pathstub = os.path.dirname(amsroot) + '/schema/versions/'
filename_stub = 'db-version-'
extension = '.sql'
if settings.DATABASE_VERSION == DATABASE_VERSION:
print "Database is up to date"
return
for i in range(settings.DATABASE_VERSION + 1, DATABASE_VERSION + 1):
print "Applying version {0}".format(i)
filename = pathstub + filename_stub + str(i) + extension
sqlfile = open(filename, "r")
sqlcontents = sqlfile.read()
statements = sqlcontents.split("\n\n--\n\n")
for sql in statements:
db.execute(sql)
dbconn.commit()
db.execute("insert into config set var=%s, value=%s on duplicate key update value=%s", ('DATABASE_VERSION', str(i), str(i)))
dbconn.commit()
db.execute("update config set `type`='int', `description`='Current version of the internal database tables', `configurable`=0 where `var`='DATABASE_VERSION'")
dbconn.commit()
def main():
ac = ArgumentCompletion(settings)
logger = logging.getLogger('ams')
parser = argparse.ArgumentParser(prog="ams")
parser.add_argument("-q", "--scriptable-output", action='store_true', help="removes human readability formatting for scripting purposes")
subparsers = parser.add_subparsers(title="type", dest='type')
# all of the operational command parsers should be in here to force internals tasks that need to be done
if settings.DATABASE_VERSION == DATABASE_VERSION:
for name, module in settings.modules.iteritems():
mparser = subparsers.add_parser(module.argparse_stub(), help=module.argparse_help_text())
module.build_argument_parser(mparser)
iparser = subparsers.add_parser("internals", help="AMS internal managament")
isubparser = iparser.add_subparsers(title="type", dest='type')
dbparser = isubparser.add_parser("database", help="Manage the AMS metadata database")
dbsubparser = dbparser.add_subparsers(title="action", dest='action')
if settings.DATABASE_VERSION == 0:
p = dbsubparser.add_parser("install", help="Create all the tables for an initial installation")
p.set_defaults(func=upgrade_db)
if settings.DATABASE_VERSION > 0:
p = dbsubparser.add_parser("upgrade", help="Upgrade the database to the current version for AMS")
p.set_defaults(func=upgrade_db)
if settings.DATABASE_VERSION == DATABASE_VERSION:
cparser = isubparser.add_parser("config", help="Manage database configuration")
csubparsers = cparser.add_subparsers(title="action", dest="action")
# ams internals config list
clistparser = csubparsers.add_parser("list", help="List current configuration variables")
clistparser.add_argument('-a', '--active', action='store_true', help="Show the full active config rather than the values that are in the database")
clistparser.set_defaults(func=command_config_list)
# ams internals config update
cupdateparser = csubparsers.add_parser("update", help="Modify current configuration variables in the database")
cupdateparser.add_argument('name', help="Config variable name to change setting for").completer = ac.config_name
cupdateparser.add_argument('value', nargs='?', help="New value for the config variable").completer = ac.config_value
cupdateparser.add_argument('--clear', action='store_true', help="Clear the value in the database for the config variable")
cupdateparser.set_defaults(func=command_config_update)
argcomplete.autocomplete(parser)
args = parser.parse_args()
if args.scriptable_output:
settings.HUMAN_OUTPUT = False
try:
args.func(args)
except Exception as e:
logger.critical(e.__class__.__name__ + ": " + str(e))
if getattr(settings, 'THROW_ERRORS', False):
raise
def command_config_update(args):
dbconn = pymysql.connect(host=settings.TRACKING_DB['host'],
port=settings.TRACKING_DB['port'],
user=settings.TRACKING_DB['user'],
password=settings.TRACKING_DB['pass'],
db=settings.TRACKING_DB['dbname'])
db = dbconn.cursor()
db.execute("select `value`, `type`, `configurable` from config where `var`=%s", (args.name, ))
row = db.fetchone()
if row:
val, tp, configurable = row
if args.clear:
db.execute("update config set `value`=NULL where `var`=%s", (args.name, ))
dbconn.commit()
else:
if not args.value:
print("Value required for update")
return
check_func = None
if tp == 'int':
check_func = int
elif tp == bool:
check_func = int
try:
new_value = args.value
if check_func:
new_value = check_func(new_value)
db.execute("update config set `value` = %s where `var` = %s", (new_value, args.name))
dbconn.commit()
except ValueError:
print("{0} does not match type '{1}' for {2}".format(args.value, tp, args.name))
return
setattr(args, 'active', False)
command_config_list(args)
else:
print("Config variable '{0}' not found".format(args.name))
def command_config_list(args):
dbconn = pymysql.connect(host=settings.TRACKING_DB['host'],
port=settings.TRACKING_DB['port'],
user=settings.TRACKING_DB['user'],
password=settings.TRACKING_DB['pass'],
db=settings.TRACKING_DB['dbname'])
db = dbconn.cursor()
db.execute("select `var`,`value`,`type`,`env_overrides`,`description`, if(`configurable`,'yes','no') from config")
rows = db.fetchall()
if not rows:
rows = []
headers = ['Variable', 'Value', 'Type', 'Environment Overrides', 'Description', 'Configurable']
results = []
for row in rows:
if args.active:
headers = ['Variable', 'Value', 'Type', 'Environment Overrides', 'Description', 'Configurable', 'Source']
title = "Active Configuration"
parts = row[0].split('.')
if len(parts) == 1:
source = settings._sources[row[0]]
val = getattr(settings, row[0], None)
elif len(parts) == 2:
source = settings._sources[parts[0]]
block = getattr(settings, parts[0], None)
val = block[parts[1]]
results.append([row[0], val, row[2], row[3], row[4], row[5], source])
else:
title = 'Database Configuration'
results.append([row[0], row[1], row[2], row[3], row[4], row[5]])
settings.modules['volume'].output_formatted(title, headers, results)
if __name__ == "__main__":
main()