forked from eljrax/autoscale_setup
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create_config.py
236 lines (207 loc) · 10.2 KB
/
create_config.py
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
""" This module checks the config for missing keys, and offers
prompts to write them out to the file.
Invoked by --create-config
"""
import utils
from colors import bcolors, print_msg
from jinja2 import Environment
import os
def write_config(config, pyrax):
""" Prompt for missing keys in the config file and writes a new one out """
config.parse_config()
try:
if config.lc_config.validate() and \
config.as_config.validate() and \
config.as_config.id:
utils.print_msg(
"Config defined in %s passes validation."
" Checking for misconfiguration and missing"
" optional keys.." % (
config.config_file), bcolors.OKGREEN)
except AttributeError:
pass
##
# Write [autoscale] config
##
if not config.as_config.id:
group = utils.get_object_from_list(
pyrax.autoscale, "group", create_new_option=True)
if group is not None:
config.set_config_option('autoscale', 'id', group)
if not config.as_config.name:
group_name = utils.ask_str("Name of autoscale_group: ")
config.set_config_option('autoscale', 'name', group_name)
if not isinstance(config.as_config.scale_up, int):
scale_up = utils.ask_integer(
"Number of servers to scale up by when triggered: ")
config.set_config_option('autoscale', 'scale_up', scale_up)
if not isinstance(config.as_config.scale_down, int):
scale_down = utils.ask_integer(
"Number of servers to scale down by when triggered: ")
config.set_config_option('autoscale', 'scale_down', scale_down)
if not isinstance(config.as_config.max_entities, int):
max_entities = utils.ask_integer(
"Max number of servers to scale up to (max_entities): ")
config.set_config_option('autoscale', 'max_entities', max_entities)
if not isinstance(config.as_config.min_entities, int):
max_entities = config.as_config.max_entities
min_entities = utils.ask_integer(
"Never scale down below this number of servers (min_entities): ")
if min_entities > max_entities:
print_msg("min_entities must be smaller than or equal"
"to max_entities (%d)" %
max_entities, bcolors.FAIL)
min_entities = utils.ask_integer("Never scale down below this "
"number of servers"
" (min_entities): ",
allowed_input=xrange(0,
max_entities))
config.set_config_option('autoscale', 'min_entities', min_entities)
if not isinstance(config.as_config.cooldown, int):
cooldown = utils.ask_integer(
"Do not process scale event more frequent than"
" this (cooldown, seconds): ")
config.set_config_option('autoscale', 'cooldown', cooldown)
##
# Write [launch-config] config
##
if not config.lc_config.image:
image = utils.get_object_from_list(pyrax.images, "image")
config.set_config_option('launch-configuration', 'image', image)
if not config.lc_config.flavor:
flavor = utils.get_object_from_list(
pyrax.cloudservers.flavors, "flavor")
config.set_config_option('launch-configuration', 'flavor', flavor)
if not config.lc_config.key_name:
key_name = utils.get_object_from_list(
pyrax.cloudservers.keypairs, "ssh-key to add to"
" /root/.ssh/authorized_keys on"
" the servers",
create_new_option=True)
if key_name is None:
key_name = utils.add_new_key(pyrax)
config.set_config_option('launch-configuration', 'key_name', key_name)
if not config.lc_config.name:
name = utils.ask_str(
"Server name (note that an 11 character suffix"
" will be added to this name): ")
config.set_config_option('launch-configuration', 'name', name)
if config.get('launch-configuration', 'cloud_init') is None:
print("When servers are booted up, the contents of the cloud-init"
" script will be executed on the server. This is a way to"
" install and configure the software the machine needs"
" in order to serve its purpose.\n"
"To use the default - input: templates/cloud-init.yml.j2")
cloud_init = utils.ask_file("Path to cloud-init script: ")
config.set_config_option(
'launch-configuration', 'cloud_init', cloud_init)
if not isinstance(config.lc_config.networks, list):
networks = []
utils.print_msg("Supply one or more networks you wish to"
"attach the cloud servers to", bcolors.QUESTION)
while True:
network = utils.get_object_from_list(
pyrax.cloud_networks, "network", quit_option=True)
if network and network not in networks:
networks.append(str(network))
elif network:
pass
else:
break
config.set_config_option('launch-configuration', 'networks', networks)
if not config.get('launch-configuration', 'skip_default_networks'):
print ("By default, the launch config will contain the default"
" networks (PublicNet and ServiceNet). You can optionally"
" disable these, but some Rackspace services will not function"
" properly without them, and they are obligatory on Managed"
" service levels")
keep = utils.ask_str("Keep default networks? (y/n): ", yesno=True)
if keep:
config.set_config_option(
'launch-configuration', 'skip_default_networks', False)
else:
config.set_config_option(
'launch-configuration', 'skip_default_networks', True)
if not config.get('launch-configuration', 'disk_config'):
disk_config = utils.ask_str("Disk config method (AUTO or MANUAL): ",
allowed_input=['AUTO', 'MANUAL',
'auto', 'manual'])
config.set_config_option(
'launch-configuration', 'disk_config', disk_config.upper())
##
# Write [rax-autoscaler] config
##
if not isinstance(config.ras_config.load_balancers, list):
load_balancers = []
utils.print_msg("Supply one or more load balancers you wish to"
" attach the cloud servers to", bcolors.QUESTION)
while True:
load_balancer = utils.get_object_from_list(
pyrax.cloud_loadbalancers, "load balancer", quit_option=True)
if load_balancer and load_balancer not in load_balancers:
load_balancers.append(load_balancer)
elif load_balancer:
pass
else:
break
config.set_config_option(
'rax-autoscaler', 'load_balancers', load_balancers)
if not isinstance(config.ras_config.num_static_servers, int):
num_static_servers = utils.ask_integer(
"How many nodes in the load balancer are"
" not part of the scaling group? (0 for none): ")
config.set_config_option('rax-autoscaler', 'num_static_servers',
num_static_servers)
if not isinstance(config.ras_config.private_key, str) or \
not utils.is_readable(config.ras_config.private_key):
print("When scaled up, the servers need to log in to the admin server"
" in order to download the playbook, or perform other tasks as"
" laid out in the cloud-init template.\nSupply a private key"
" which can be used to log in as the user 'autoscale' on the"
" admin server")
private_key = utils.ask_file("Private key to inject"
" into /root/.ssh/id_rsa on servers: ")
config.set_config_option('rax-autoscaler', 'private_key', private_key)
if not isinstance(config.ras_config.admin_server, str):
admin_server = utils.ask_str("IP or host-name of admin server to"
" download playbook from: ")
config.set_config_option('rax-autoscaler', 'admin_server',
admin_server)
# Re-parse the file on-disk and validate
config.parse_config()
config.validate()
def generate_rax_as_config(config):
input_template = os.getcwd() + '/templates/rax-autoscaler.json.j2'
output_file = os.getcwd() + '/rax-autoscaler-config.json'
try:
with open(input_template, 'r') as fp:
j2_env = Environment().from_string(fp.read())
except IOError as ex:
print_msg("Failed to open rax-autoscaler config template: %s" % ex,
bcolors.FAIL)
exit(1)
scale_up_policy = config.cfg.get('rax-autoscaler',
'scale_up_policy').strip("'")
scale_down_policy = config.cfg.get('rax-autoscaler',
'scale_down_policy').strip("'")
load_balancers = config.cfg.get('rax-autoscaler',
'load_balancers').strip("'")
autoscale_group = config.as_config.id.strip("'")
num_static_servers = config.cfg.get('rax-autoscaler',
'num_static_servers')
t = j2_env.render(username=config.username,
api_key=config.api_key,
region=config.region,
autoscale_group=autoscale_group,
scale_up_policy=scale_up_policy,
scale_down_policy=scale_down_policy,
load_balancers=load_balancers,
num_static_servers=num_static_servers)
try:
with open(output_file, 'w+') as fp:
fp.write(t)
print_msg("Wrote rax-autoscaler to file %s" % output_file,
bcolors.OKGREEN)
except IOError as ex:
print_msg("Failed to write rax-autoscaler config: %s" % ex,
bcolors.FAIL)