127
131
#------------------------------------------------------------------------------
128
132
def create_haproxy_defaults():
129
133
config_data = config_get()
130
default_options = config_data['default_options'].split(',')
131
default_timeouts = config_data['default_timeouts'].split(',')
134
default_options = comma_split(config_data['default_options'])
135
default_timeouts = comma_split(config_data['default_timeouts'])
132
136
haproxy_defaults = []
133
137
haproxy_defaults.append("defaults")
134
138
haproxy_defaults.append(" log %s" % config_data['default_log'])
286
290
server_line = " server %s %s:%s" % \
287
291
(server_name, server_ip, server_port)
288
292
if server_options is not None:
289
server_line += " %s" % " ".join(server_options)
293
if isinstance(server_options, basestring):
294
server_line += " " + server_options
296
server_line += " " + " ".join(server_options)
290
297
service_config.append(server_line)
291
298
return '\n'.join(service_config)
331
338
def get_config_services():
332
339
config_data = config_get()
334
for service in yaml.safe_load(config_data['services']):
341
return parse_services_yaml(services, config_data['services'])
344
def parse_services_yaml(services, yaml_data):
345
for service in yaml.safe_load(yaml_data):
335
346
service_name = service["service_name"]
337
348
# 'None' is used as a marker for the first service defined, which
338
349
# is used as the default service if a proxied server doesn't
339
350
# specify which service it is bound to.
340
351
services[None] = {"service_name": service_name}
341
if is_proxy(service_name) and ("option forwardfor" not in
342
service["service_options"]):
343
service["service_options"].append("option forwardfor")
345
if isinstance(service["server_options"], basestring):
346
service["server_options"] = service["server_options"].split()
348
services[service_name] = service
353
if "service_options" in service:
354
if isinstance(service["service_options"], basestring):
355
service["service_options"] = comma_split(
356
service["service_options"])
358
if is_proxy(service_name) and ("option forwardfor" not in
359
service["service_options"]):
360
service["service_options"].append("option forwardfor")
362
if (("server_options" in service and
363
isinstance(service["server_options"], basestring))):
364
service["server_options"] = comma_split(service["server_options"])
366
services[service_name] = merge_service(
367
services.get(service_name, {}), service)
371
def merge_service(old_service, new_service):
372
# Stomp over all but servers
373
for key in new_service:
374
if key not in ("services",):
375
old_service[key] = new_service[key]
377
# Stomp over duplicate server definitions.
378
if old_service.get("servers") and new_service.get("servers"):
380
for service in (old_service, new_service):
381
for server_name, host, port, options in service.get("servers", ()):
382
servers[(host, port)] = (server_name, options)
384
old_service["servers"] = [
385
(server_name, host, port, options)
386
for (host, port), (server_name, options) in sorted(
387
servers.iteritems())]
392
def ensure_service_host_port(services):
393
config_data = config_get()
396
for service, options in sorted(services.iteritems()):
397
if not "service_host" in options:
398
missing.append(options)
400
if not "service_port" in options:
401
missing.append(options)
403
seen.append((options["service_host"], int(options["service_port"])))
406
last_port = seen and seen[-1][1] or int(config_data["monitoring_port"])
407
for options in missing:
409
options["service_host"] = "0.0.0.0"
410
options["service_port"] = last_port
370
432
#------------------------------------------------------------------------------
371
433
def create_services():
372
434
services_dict = get_config_services()
436
# Augment services_dict with service definitions from relation data.
437
relation_data = relations_of_type("reverseproxy")
438
for relation_info in relation_data:
439
if "services" in relation_info:
440
services_dict = parse_services_yaml(services_dict,
441
relation_info['services'])
373
443
if len(services_dict) == 0:
374
444
log("No services configured, exiting.")
379
449
for relation_info in relation_data:
380
450
unit = relation_info['__unit__']
452
if "services" in relation_info:
453
log("Unit '%s' overrides 'services', "
454
"skipping further processing." % unit)
381
457
juju_service_name = unit.rpartition('/')[0]
383
459
relation_ok = True
384
for required in ("port", "private-address", "hostname"):
460
for required in ("port", "private-address"):
385
461
if not required in relation_info:
386
462
log("No %s in relation data for '%s', skipping." %
387
463
(required, unit))