Beispiel #1
0
 def check_credentials(self):
     try:
         self.check_connection(False)
     except ldap.INVALID_CREDENTIALS:
         Config.error("Invalid credentials")
     except Exception as e:
         Config.error("Unknown exception: %s" % repr(e))
Beispiel #2
0
class OsVmsEndpointConfig(BaseOsEndpointConfig):

    instance_id = Config.string(label="Live-Image", order=2,
        validate=lambda self: \
            self.novaclient().servers.get(self.instance_id)._info['status'] == 'BLESSED' or \
            Config.error("Server is not in BLESSED state."),
        description="The live-image to use.")
Beispiel #3
0
 def check_credentials(self):
     try:
         self.check_connection(False)
     except ldap.INVALID_CREDENTIALS:
         Config.error("Invalid credentials")
     except Exception as e:
         Config.error("Unknown exception: %s" % repr(e))
Beispiel #4
0
 def validate_image(self):
     if self.validate_connection_params(False):
         avail = [image._info['id'] for image in self.novaclient().images.list()]
         if self.image_id in avail:
             return True
         else:
             Config.error("Image %s not found" % self.image_id)
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #5
0
 def check_connection(self, hostcheck=True):
     try:
         self.try_connection()
     except ldap.SERVER_DOWN:
         if hostcheck:
             Config.error("Could not connect to host")
     except Exception as e:
         # If we're not just validating the host, propagate
         if not hostcheck:
             raise e
Beispiel #6
0
 def validate_flavor(self):
     if self.validate_connection_params(False):
         avail = [flavor._info['id'] for flavor in self.novaclient().flavors.list()]
         if self.flavor_id in avail:
             return True
         else:
             Config.error("Flavor %s not found" % self.flavor_id)
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #7
0
 def validate_floating_ips(self):
     if self.validate_connection_params(False):
         avail = map(lambda x: x._info['ip'], self.novaclient().floating_ips.list())
         bad_ips = list(set(self.floating_ips).difference(set(avail)))
         if len(bad_ips) > 0:
             Config.error("Floating IPs not found: %s" % str(bad_ips))
         return True
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #8
0
 def check_connection(self, hostcheck=True):
     try:
         self.try_connection()
     except ldap.SERVER_DOWN:
         if hostcheck:
             Config.error("Could not connect to host")
     except Exception as e:
         # If we're not just validating the host, propagate
         if not hostcheck:
             raise e
Beispiel #9
0
 def validate_floating_ips(self):
     if self.validate_connection_params(False):
         avail = map(lambda x: x._info['ip'],
                     self.novaclient().floating_ips.list())
         bad_ips = list(set(self.floating_ips).difference(set(avail)))
         if len(bad_ips) > 0:
             Config.error("Floating IPs not found: %s" % str(bad_ips))
         return True
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #10
0
class DnsmasqManagerConfig(Config):

    pid_file = Config.string(label="Pid file",
                             default="/var/run/dnsmasq/dnsmasq.pid",
                             description="The dnsmasq pid file.")

    config_path = Config.string(label="Configuration Path", default="/etc/dnsmasq.d", \
        description="The configuration directory to insert base configuration.")

    hosts_path = Config.string(label="Site Config Path", default="/etc/hosts.reactor", \
        description="The directory in which to generate site configurations.")
Beispiel #11
0
 def validate_image(self):
     if self.validate_connection_params(False):
         avail = [
             image._info['id'] for image in self.novaclient().images.list()
         ]
         if self.image_id in avail:
             return True
         else:
             Config.error("Image %s not found" % self.image_id)
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #12
0
 def validate_keyname(self):
     if self.key_name is None:
         # No keyname provided.
         return True
     elif self.validate_connection_params(False):
         avail = [key._info['keypair']['name'] for key in self.novaclient().keypairs.list()]
         if self.key_name in avail:
             return True
         else:
             Config.error("Keyname %s not found" % self.key_name)
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #13
0
 def validate_flavor(self):
     if self.validate_connection_params(False):
         avail = [
             flavor._info['id']
             for flavor in self.novaclient().flavors.list()
         ]
         if self.flavor_id in avail:
             return True
         else:
             Config.error("Flavor %s not found" % self.flavor_id)
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #14
0
class NginxManagerConfig(Config):

    pid_file = Config.string(label="Pid file",
                             default="/var/run/nginx.pid",
                             description="The nginx pid file.")

    config_path = Config.string(
        label="Configuration path",
        default="/etc/nginx/conf.d",
        description="The configuration directory for nginx.")

    site_path = Config.string(label="Sites-enabled path",
                              default="/etc/nginx/sites-enabled",
                              description="The site path for nginx.")
Beispiel #15
0
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.")
Beispiel #16
0
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
Beispiel #17
0
    def validate_network_conf(self):
        if self.validate_connection_params(False):
            # Parse netspecs into objects.
            try:
                networks = OsApiEndpointConfig.parse_netspecs(self.network_conf)
            except Exception as ex:
                Config.error("Failed to parse network conf: %s" % str(ex))

            known_networks = [nw._info["id"] for nw in self.novaclient().networks.list()]
            for network in networks:
                if (network["net-id"] is not None) and \
                        (network["net-id"] not in known_networks):
                    Config.error("Network '%s' not found" % network)
        else:
            # Can't connect to cloud, ignore this param for now
            return True
Beispiel #18
0
 def validate_keyname(self):
     if self.key_name is None:
         # No keyname provided.
         return True
     elif self.validate_connection_params(False):
         avail = [
             key._info['keypair']['name']
             for key in self.novaclient().keypairs.list()
         ]
         if self.key_name in avail:
             return True
         else:
             Config.error("Keyname %s not found" % self.key_name)
     else:
         # Can't connect to cloud, ignore this param for now
         return True
Beispiel #19
0
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.")
Beispiel #20
0
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.")
Beispiel #21
0
    def validate_network_conf(self):
        if self.validate_connection_params(False):
            # Parse netspecs into objects.
            try:
                networks = OsApiEndpointConfig.parse_netspecs(
                    self.network_conf)
            except Exception as ex:
                Config.error("Failed to parse network conf: %s" % str(ex))

            known_networks = [
                nw._info["id"] for nw in self.novaclient().networks.list()
            ]
            for network in networks:
                if (network["net-id"] is not None) and \
                        (network["net-id"] not in known_networks):
                    Config.error("Network '%s' not found" % network)
        else:
            # Can't connect to cloud, ignore this param for now
            return True
Beispiel #22
0
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.")
Beispiel #23
0
 def validate_connection_params(self, throwerror=True):
     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
Beispiel #24
0
 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
Beispiel #25
0
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
Beispiel #26
0
class RdpEndpointConfig(TcpEndpointConfig):
    def __init__(self, *args, **kwargs):
        super(RdpEndpointConfig, self).__init__(*args, **kwargs)
        self._connection = None

    domain = Config.string(
        label="Active Directory Domain",
        order=0,
        validate=lambda self: self.check_credentials(),
        description="Fully-qualified name of the Active Directory domain for "
        + "the VM machine accounts.")

    username = Config.string(label="Active Directory Username",
                             order=1,
                             description="An Administrator within the domain.")

    password = Config.password(label="Active Directory Password",
                               order=2,
                               description="The Administrator password.")

    orgunit = Config.string(
        label="Active Directory Orginational Unit",
        order=3,
        description="The orgunit for new machines. The master machine account "
        + "must be in the same orgunit prior to live-imaging.")

    template = Config.string(label="Machine Name Template",
        default="windowsVM######", order=4,
        validate=lambda self: len(self.template) == 15 or \
            Config.error("Template must be 15 characters long."),
        description="The template machine name for new machines.")

    host = Config.string(
        label="Domain Controller",
        order=5,
        validate=lambda self: self.check_connection(),
        description=
        "The network address (hostname or IP) of the AD server to contact.")

    def ldap_connection(self):
        if not (self.domain):
            return None
        if self._connection is None:
            self._connection = LdapConnection(self.domain,
                                              self.username,
                                              self.password,
                                              orgunit=self.orgunit,
                                              host=self.host)
        return self._connection

    def check_credentials(self):
        try:
            self.check_connection(False)
        except ldap.INVALID_CREDENTIALS:
            Config.error("Invalid credentials")
        except Exception as e:
            Config.error("Unknown exception: %s" % repr(e))

    def check_connection(self, hostcheck=True):
        try:
            self.try_connection()
        except ldap.SERVER_DOWN:
            if hostcheck:
                Config.error("Could not connect to host")
        except Exception as e:
            # If we're not just validating the host, propagate
            if not hostcheck:
                raise e

    def try_connection(self):
        conn = self.ldap_connection()
        self._connection = None
        if conn:
            # If we have a connection (i.e. the user has
            # specified a windows domain in their config)
            # then we ensure that we can connect.
            conn.open()
Beispiel #27
0
class OsApiEndpointConfig(BaseOsEndpointConfig):

    instance_name = Config.string(label="Instance Name", order=2,
        validate=lambda self: self.instance_name or \
            Config.error("Must provide an instance name."),
        description="The name given to new instances.")

    flavor_id = Config.string(label="Flavor",
                              order=2,
                              validate=lambda self: self.validate_flavor(),
                              description="The flavor to use.")

    image_id = Config.string(label="Image",
                             order=2,
                             validate=lambda self: self.validate_image(),
                             description="The image ID to boot.")

    key_name = Config.string(label="Key Name",
                             order=2,
                             validate=lambda self: self.validate_keyname(),
                             description="The key_name (for injection).")

    network_conf = Config.list(
        label="Network Configuration",
        default=[],
        order=2,
        validate=lambda self: self.validate_network_conf(),
        description="Network configuration for scaled instances. " +
        "This is identical to the --nic parameter in novaclient. " +
        "One network configuration per line.")

    def validate_flavor(self):
        if self.validate_connection_params(False):
            avail = [
                flavor._info['id']
                for flavor in self.novaclient().flavors.list()
            ]
            if self.flavor_id in avail:
                return True
            else:
                Config.error("Flavor %s not found" % self.flavor_id)
        else:
            # Can't connect to cloud, ignore this param for now
            return True

    def validate_image(self):
        if self.validate_connection_params(False):
            avail = [
                image._info['id'] for image in self.novaclient().images.list()
            ]
            if self.image_id in avail:
                return True
            else:
                Config.error("Image %s not found" % self.image_id)
        else:
            # Can't connect to cloud, ignore this param for now
            return True

    def validate_keyname(self):
        if self.key_name is None:
            # No keyname provided.
            return True
        elif self.validate_connection_params(False):
            avail = [
                key._info['keypair']['name']
                for key in self.novaclient().keypairs.list()
            ]
            if self.key_name in avail:
                return True
            else:
                Config.error("Keyname %s not found" % self.key_name)
        else:
            # Can't connect to cloud, ignore this param for now
            return True

    def validate_network_conf(self):
        if self.validate_connection_params(False):
            # Parse netspecs into objects.
            try:
                networks = OsApiEndpointConfig.parse_netspecs(
                    self.network_conf)
            except Exception as ex:
                Config.error("Failed to parse network conf: %s" % str(ex))

            known_networks = [
                nw._info["id"] for nw in self.novaclient().networks.list()
            ]
            for network in networks:
                if (network["net-id"] is not None) and \
                        (network["net-id"] not in known_networks):
                    Config.error("Network '%s' not found" % network)
        else:
            # Can't connect to cloud, ignore this param for now
            return True

    @staticmethod
    def parse_netspecs(netspecs):
        parsed_specs = []
        for spec in netspecs:
            res = {"net-id": None, "v4-fixed-ip": None, "port-id": None}
            for keyval in spec.split(","):
                kv = keyval.split("=", 1)
                if len(kv) < 2:
                    raise ValueError("No value given for key '%s'" %
                                     str(kv[0]))
                key = kv[0]
                value = kv[1]

                if key not in res:
                    raise KeyError("'%s' is not a valid nic keyword" %
                                   str(key))
                res[key] = value
            parsed_specs.append(res)
        return parsed_specs
Beispiel #28
0
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