class HaproxyEndpointConfig(Config): balance = Config.select( label="Loadbalancing mode", default="roundrobin", options=[("Roundrobin", "roundrobin"), ("URI-based", "uri"), ("Source-based", "source")], description="The loadbalancing mode used to choose backends.") sticky = Config.boolean(label="Sticky mode", default=True, description="Whether sessions should be sticky.") check_url = Config.string( label="Check URL", default="", description="If using HTTP, the URL used to check the backend.") errorloc = Config.string( label="Error location", default="", description="An error location used as ${errorloc}/${code}.") contimeout = Config.integer(label="Connection timeout", default=5000, description="A generic connection timeout.") srvtimeout = Config.integer(label="Server timeout", default=50000, description="Server connection timeout.")
class TcpEndpointConfig(Config): exclusive = Config.boolean( label="One VM per connection", default=True, description= "Each Instance is used exclusively to serve a single connection.") disposable = Config.boolean(label="Kill on Disconnect", default=False, validate=lambda self: self.exclusive or not(self.disposable) or \ Config.error("Kill on Disconnect requires One VM per connection."), description="Discard backend instances on disconnect. Requires" \ + " 'One VM per connection'.") dispose_min = Config.integer(label="Minimum session time", default=30, validate=lambda self: self.dispose_min >= 0 or \ Config.error("Minimum session time must be non-negative."), description="Minimum session time (in seconds) before a session is" \ + " killed on disconnect.") reconnect = Config.integer(label="Reconnect Timeout", default=60, validate=lambda self: self.reconnect >= 0 or \ Config.error("The reconnect must be non-negative."), description="Amount of time a disconnected client has to reconnect before" \ + " the VM is returned to the pool.") client_subnets = Config.list( label="Client Subnets", order=7, description="Only allow connections from these client subnets.")
class HaproxyManagerConfig(Config): config_file = Config.string( label="Configuration path", default="/etc/haproxy/haproxy.cfg", description="The configuration file for HAProxy.") pid_file = Config.string(label="Pid file", default="/var/run/haproxy.pid", description="The HAProxy pid file.") stats_path = Config.string(label="Stats socket path", default="/var/run/haproxy.sock", description="The stats socket path.") stats_mode = Config.string(label="Stats socket mode", default="0666", description="The stats permission mode.") global_opts = Config.list(label="Other global configuration options", default=[ "log 127.0.0.1 local0", "log 127.0.0.1 local1 notice", "user haproxy", "group haproxy", ]) maxconn = Config.integer( label="Maximum connection", default=5000, description="Maximum number of simultaneous connections.") clitimeout = Config.integer(label="Client timeout", default=50000, description="Client connection timeout.")
class NginxEndpointConfig(Config): sticky_sessions = Config.boolean( label="Use Sticky Sessions", default=False, description="Enables nginx sticky sessions.") keepalive = Config.integer(label="Keepalive Connections", default=0, validate=lambda self: self.keepalive >= 0 or \ Config.error("Keepalive must be non-negative."), description="Number of backend connections to keep alive.") ssl = Config.boolean(label="Use SSL", default=False, description="Configures nginx to handle SSL.") ssl_certificate = Config.text( label="SSL Certificate", default=None, description="An SSL certification in PEM format.") ssl_key = Config.text(label="SSL Key", default=None, description="An SSL key (not password protected).") redirect = Config.string( label="Redirect", default=None, description="A 301 redirect to use when no backends are available.")
class DockerManagerConfig(Config): # Cached client. _client = None slots = Config.integer(label="Scheduler slots", default=1000, order=0, validate=lambda self: self.slots >= 0 or \ Config.error("Slots must be greater than or equal to zero."), description="Number of available scheduler slots on this host.") def client(self): if self._client == None: import docker self._client = docker.client.Client() return self._client
class BaseOsEndpointConfig(Config): # Cached client. _client = None def __init__(self, *args, **kwargs): super(BaseOsEndpointConfig, self).__init__(*args, **kwargs) # Last refresh for the cache. self._last_refresh = None # Initialize our list cache. self._list_cache = [] # Initialize our floating IP cache. self._float_cache = {} # Common authentication elements. auth_url = Config.string( label="OpenStack Auth URL", default="http://localhost:5000/v2.0/", order=0, validate=lambda self: self.validate_connection_params(), alternates=["authurl"], description="The OpenStack authentication URL (OS_AUTH_URL).") username = Config.string( label="OpenStack User", default="admin", order=1, alternates=["user"], description="The user for authentication (OS_USERNAME).") password = Config.password( label="OpenStack Password", default="admin", order=2, alternates=["apikey"], description="The api key or password (OS_PASSWORD).") tenant_name = Config.string( "OpenStack Tenant/Project", default="admin", order=3, alternates=["project"], description="The project or tenant (OS_TENANT_NAME).") region_name = Config.string(label="Region Name", order=4, description="The region (OS_REGION_NAME).") list_rate_limit = Config.integer(label="Rate limit", default=120, order=1, validate=lambda self: self.list_rate_limit >= 0 or \ Config.error("Rate limit must be non-negative."), description="Limit list requests to this often.") # Elements common to launching and booting. security_groups = Config.list( label="Security Groups", order=5, description="Security groups for new instances.") availability_zone = Config.string( label="Availability Zone", order=5, description="Availability zone for new instances.") user_data = Config.text( "User Data", order=6, description="Script or cloud-config for new instances.") filter_instances = Config.boolean( "Filter Instances", default=False, order=7, description="Use only instances that match image, flavor, etc.") floating_ips = Config.list( label="Floating IPs", order=7, validate=lambda self: self.validate_floating_ips(), description="Floating IPs to distribute.") def novaclient(self): from novaclient import shell from novaclient.v1_1.client import Client as NovaClient if self._client is None: extensions = shell.OpenStackComputeShell()._discover_extensions( "1.1") self._client = NovaClient(self.username, self.password, self.tenant_name, self.auth_url, region_name=self.region_name, service_type="compute", extensions=extensions) return self._client def validate_connection_params(self, throwerror=True): import novaclient.exceptions try: self.novaclient().authenticate() except Exception, e: if throwerror: # If we got an unathorized exception, propagate. if isinstance(e, novaclient.exceptions.Unauthorized): Config.error(e.message) elif isinstance(e, novaclient.exceptions.EndpointNotFound): Config.error( "Problem connecting to cloud endpoint. Bad Region?") else: Config.error( "Could not connect to OpenStack cloud. Bad URL?") else: return False return True
class DockerEndpointConfig(Config): slots = Config.integer(label="Scheduler slots", default=10, order=0, validate=lambda self: self.slots >= 0 or \ Config.error("Slots must be greater than or equal to zero."), description="Slots required on a host in order to run.") image = Config.string(label="Image", default="", order=1, validate=lambda self: self.image or \ Config.error("No image provided."), description="The docker image to use.") command = Config.string(label="Command", default="", order=1, validate=lambda self: self.command or \ Config.error("No command provided."), description="The command to run inside the container.") user = Config.string(label="User", default="", order=2, description="The user used to run the command.") environment = Config.list(label="Environment", default=[], order=3, validate=lambda self: self.get_environment(), description="The environment for the command.") def get_environment(self): if self.environment: # Return as a dictionary of key=value pairs. return dict( map(lambda x: map(lambda y: y.strip(), x.split("=", 1)), self.environment)) else: return {} mem_limit = Config.integer(label="Memory limit", default=0, order=3, validate=lambda self: self.mem_limit >= 0 or \ Config.error("Memory limit must be non-negative."), description="The container memory limit.") dns = Config.string(label="DNS Sever", default="", order=4, description="The DNS server for the container.") hostname = Config.string(label="Hostname", default="", order=4, description="The hostname for the container.") def port(self): # Extract the port from the endpoint. from reactor.endpoint import EndpointConfig endpoint_config = EndpointConfig(obj=self) return endpoint_config.port