Esempio n. 1
0
    def prepare(self):
        report = StateReport()

        report.name = nexus.core.info.pdid

        report.osVersion = system_info.getOSVersion()

        # We can get the paradrop version from the installed python package.
        report.paradropVersion = system_info.getPackageVersion('paradrop')

        # TODO: Get pdinstall version - we will have to work with snappy or
        # devise some other mechanism, since it installs as a completely
        # separate snap.

        report.chutes = []
        chuteStore = ChuteStorage()
        chutes = chuteStore.getChuteList()
        allocation = resource.computeResourceAllocation(chutes)

        for chute in chutes:
            container = ChuteContainer(chute.name)

            report.chutes.append({
                'name':
                chute.name,
                'desired':
                chute.state,
                'state':
                container.getStatus(),
                'warning':
                chute.warning,
                'version':
                getattr(chute, 'version', None),
                'allocation':
                allocation.get(chute.name, None),
                'environment':
                getattr(chute, 'environment', None),
                'external':
                getattr(chute, 'external', None),
                'resources':
                getattr(chute, 'resources', None)
            })

        report.devices = devices.listSystemDevices()
        report.hostConfig = hostconfig.prepareHostConfig(write=False)

        client = SnapdClient()
        report.snaps = client.listSnaps()

        report.zerotierAddress = zerotier.getAddress()
        report.dmi = system_info.getDMI()

        # Add CPU, memory, disk, and network interface information.  This gives
        # the controller useful debugging information such as high memory or
        # disk utilization and IP addresses.
        status_source = SystemStatus()
        report.status = status_source.getStatus(max_age=None)

        return report.__dict__
Esempio n. 2
0
    def get_chute(self, request, chute):
        """
        Get information about an installed chute.

        **Example request**:

        .. sourcecode:: http

           GET /api/v1/chutes/hello-world

        **Example response**:

        .. sourcecode:: http

           HTTP/1.1 200 OK
           Content-Type: application/json

           {
             "environment": {},
             "name": "hello-world",
             "allocation": {
               "cpu_shares": 1024,
               "prioritize_traffic": false
             },
             "state": "running",
             "version": "x1511808778",
             "resources": null
           }
        """
        cors.config_cors(request)
        request.setHeader('Content-Type', 'application/json')

        try:
            chute_obj = ChuteStorage.chuteList[chute]
            service = chute_obj.get_default_service()
            container = ChuteContainer(service.get_container_name())
        except KeyError:
            request.setResponseCode(404)
            return "{}"

        if not chute_access_allowed(request, chute_obj):
            return permission_denied(request)

        chuteStorage = ChuteStorage()
        allocation = resource.computeResourceAllocation(
            chuteStorage.getChuteList())

        # TODO Return information about all of the chute's services.
        result = {
            'name': chute,
            'state': container.getStatus(),
            'version': getattr(chute_obj, 'version', None),
            'allocation': allocation.get(chute, None),
            'environment': getattr(chute_obj, 'environment', None),
            'resources': getattr(chute_obj, 'resources', None)
        }

        return json.dumps(result, cls=ChuteEncoder)
Esempio n. 3
0
    def get_chutes(self, request):
        """
        List installed chutes.

        **Example request**:

        .. sourcecode:: http

           GET /api/v1/chutes/

        **Example response**:

        .. sourcecode:: http

           HTTP/1.1 200 OK
           Content-Type: application/json

           [
             {
               "environment": {},
               "name": "hello-world",
               "allocation": {
                 "cpu_shares": 1024,
                 "prioritize_traffic": false
               },
               "state": "running",
               "version": "x1511808778",
               "resources": null
             }
           ]
        """
        cors.config_cors(request)
        request.setHeader('Content-Type', 'application/json')

        chuteStorage = ChuteStorage()
        chutes = chuteStorage.getChuteList()
        allocation = resource.computeResourceAllocation(chutes)

        result = []
        for chute in chutes:
            service = chute.get_default_service()
            container = ChuteContainer(service.get_container_name())

            # TODO Return information about all of the chute's services.
            result.append({
                'name': chute.name,
                'owner': chute.get_owner(),
                'state': container.getStatus(),
                'version': getattr(chute, 'version', None),
                'allocation': allocation.get(chute.name, None),
                'environment': getattr(chute, 'environment', None),
                'resources': getattr(chute, 'resources', None)
            })

        return json.dumps(result, cls=ChuteEncoder)
Esempio n. 4
0
    def prepare(self):
        chuteStore = ChuteStorage()
        chutes = chuteStore.getChuteList()

        # All network interfaces: we will divide these into chute-specific
        # interfaces and system-wide interfaces.
        network = SystemStatus.getNetworkInfo()
        system_interfaces = set(network.keys())

        report = {
            'chutes': [],
            'network': [],
            'system': SystemStatus.getSystemInfo(),
            'time': time.time()
        }

        for chute in chutes:
            container = ChuteContainer(chute.name)

            chute_info = {
                'name': chute.name,
                'state': container.getStatus(),
                'network': []
            }

            try:
                pid = container.getPID()
                chute_info['process'] = SystemStatus.getProcessInfo(pid)
            except Exception as error:
                chute_info['process'] = None

            interfaces = chute.getCache('networkInterfaces')
            for iface in interfaces:
                ifname = iface['externalIntf']
                if ifname in network:
                    ifinfo = network[ifname]
                    ifinfo['name'] = ifname
                    ifinfo['type'] = iface.get('type', 'wifi')
                    chute_info['network'].append(ifinfo)
                    system_interfaces.remove(ifname)

            report['chutes'].append(chute_info)

        for ifname in system_interfaces:
            ifinfo = network[ifname]
            ifinfo['name'] = ifname
            ifinfo['type'] = None
            report['network'].append(ifinfo)

        return report
Esempio n. 5
0
    def get_chute(self, request, chute):
        """
        Get information about an installed chute.

        **Example request**:

        .. sourcecode:: http

           GET /api/v1/chutes/hello-world

        **Example response**:

        .. sourcecode:: http

           HTTP/1.1 200 OK
           Content-Type: application/json

           {
             "environment": {},
             "name": "hello-world",
             "allocation": {
               "cpu_shares": 1024,
               "prioritize_traffic": false
             },
             "state": "running",
             "version": "x1511808778",
             "resources": null
           }
        """
        cors.config_cors(request)

        request.setHeader('Content-Type', 'application/json')

        chute_obj = ChuteStorage.chuteList[chute]
        container = ChuteContainer(chute)

        chuteStorage = ChuteStorage()
        allocation = resource.computeResourceAllocation(
            chuteStorage.getChuteList())

        result = {
            'name': chute,
            'state': container.getStatus(),
            'version': getattr(chute_obj, 'version', None),
            'allocation': allocation.get(chute, None),
            'environment': getattr(chute_obj, 'environment', None),
            'resources': getattr(chute_obj, 'resources', None)
        }

        return json.dumps(result)
Esempio n. 6
0
    def prepare(self):
        chuteStore = ChuteStorage()
        chutes = chuteStore.getChuteList()

        # All network interfaces: we will divide these into chute-specific
        # interfaces and system-wide interfaces.
        network = SystemStatus.getNetworkInfo()
        system_interfaces = set(network.keys())

        report = {
            'chutes': [],
            'network': [],
            'system': SystemStatus.getSystemInfo(),
            'time': time.time()
        }

        for chute in chutes:
            container = ChuteContainer(chute.name)

            chute_info = {
                'name': chute.name,
                'state': container.getStatus(),
                'network': []
            }

            try:
                pid = container.getPID()
                chute_info['process'] = SystemStatus.getProcessInfo(pid)
            except Exception:
                chute_info['process'] = None

            interfaces = chute.getCache('networkInterfaces')
            for iface in interfaces:
                ifname = iface['externalIntf']
                if ifname in network:
                    ifinfo = network[ifname]
                    ifinfo['name'] = ifname
                    ifinfo['type'] = iface.get('type', 'wifi')
                    chute_info['network'].append(ifinfo)
                    system_interfaces.remove(ifname)

            report['chutes'].append(chute_info)

        for ifname in system_interfaces:
            ifinfo = network[ifname]
            ifinfo['name'] = ifname
            ifinfo['type'] = None
            report['network'].append(ifinfo)

        return report
Esempio n. 7
0
def generateConfigSections():
    sections = []

    sections.append({
        "header": "global",
        "lines": [
            "daemon",
            "maxconn 256",
        ]
    })

    sections.append({
        "header": "defaults",
        "lines": [
            "mode http",
            "timeout connect 5000ms",
            "timeout client 50000ms",
            "timeout server 50000ms"
        ]
    })

    sections.append({
        "header": "backend portal",
        "lines": [
            "server pd_portal 127.0.0.1:8080 maxconn 256"
        ]
    })

    # Custom variables:
    # - req.querymarker: will be set to the literal "?" if the original request
    # contains a query string.  We will use this to construct a redirect with a
    # query string only if needed.
    # - req.subpath: will be set to the remainder of the path, if anything,
    # after removing /chutes/<chutename>, e.g. "/chutes/hello-world/index.html"
    # becomes "/index.html".  This does not include the query string.
    frontend = {
        "header": "frontend http-in",
        "lines": [
            "bind *:80",
            "default_backend portal",
            "http-request set-var(req.querymarker) str(?) if { query -m found }",
            "http-request set-var(req.subpath) path,regsub(^/chutes/[^/]+,)"
        ]
    }
    sections.append(frontend)

    chuteStore = ChuteStorage()
    chutes = chuteStore.getChuteList()
    for chute in chutes:
        port, service = chute.get_web_port_and_service()
        if port is None or service is None:
            continue

        container = ChuteContainer(service.get_container_name())
        if not container.isRunning():
            continue

        # Generate a rule that matches HTTP host header to chute name.
        frontend['lines'].append("acl host_{} hdr(host) -i {}.chute.paradrop.org".format(
            chute.name, chute.name))
        frontend['lines'].append("use_backend {} if host_{}".format(
            chute.name, chute.name))

        # Generate rules that matches the beginning of the URL.
        # We need to be careful and either have an exact match
        # or make sure there is a slash or question mark after the chute name
        # to avoid mix-ups, e.g. "sticky-board" and "sticky-board-new".
        frontend['lines'].append("acl path_{} url /chutes/{}".format(
            chute.name, chute.name))
        frontend['lines'].append("acl path_{} url_beg /chutes/{}/".format(
            chute.name, chute.name))
        frontend['lines'].append("acl path_{} url_beg /chutes/{}?".format(
            chute.name, chute.name))

        # Try to find a host binding for the web port to redirect:
        # http://<host addr>/chutes/<chute>/<path> ->
        # http://<host addr>:<chute port>/<path>
        #
        # We need to do a lookup because the host port might be dynamically
        # assigned by Docker.
        #
        # Use HTTP code 302 for the redirect, which will not be cached by the
        # web browser.  The port portion of the URL can change whenever the
        # chute restarts, so we don't want web browsers to cache it.  Browsers
        # will cache a 301 (Moved Permanently) response.
        portconf = container.getPortConfiguration(port, "tcp")
        if len(portconf) > 0:
            # TODO: Are there other elements in the list?
            binding = portconf[0]
            frontend['lines'].append("http-request replace-value Host (.*):(.*) \\1")
            frontend['lines'].append("http-request redirect location http://%[req.hdr(host)]:{}%[var(req.subpath)]%[var(req.querymarker)]%[query] code 302 if path_{}".format(
                binding['HostPort'], chute.name))

        # Add a server at the chute's IP address.
        sections.append({
            "header": "backend {}".format(chute.name),
            "lines": [
                "server {} {}:{} maxconn 256".format(chute.name,
                    container.getIP(), port)
            ]
        })

    return sections
Esempio n. 8
0
def generateConfigSections():
    sections = []

    sections.append({
        "header": "global",
        "lines": [
            "daemon",
            "maxconn 256",
        ]
    })

    sections.append({
        "header":
        "defaults",
        "lines": [
            "mode http", "timeout connect 5000ms", "timeout client 50000ms",
            "timeout server 50000ms"
        ]
    })

    sections.append({
        "header": "backend portal",
        "lines": ["server pd_portal 127.0.0.1:8080 maxconn 256"]
    })

    # Custom variables:
    # - req.querymarker: will be set to the literal "?" if the original request
    # contains a query string.  We will use this to construct a redirect with a
    # query string only if needed.
    # - req.subpath: will be set to the remainder of the path, if anything,
    # after removing /chutes/<chutename>, e.g. "/chutes/hello-world/index.html"
    # becomes "/index.html".  This does not include the query string.
    frontend = {
        "header":
        "frontend http-in",
        "lines": [
            "bind *:80", "default_backend portal",
            "http-request set-var(req.querymarker) str(?) if { query -m found }",
            "http-request set-var(req.subpath) path,regsub(^/chutes/[^/]+,)"
        ]
    }
    sections.append(frontend)

    chuteStore = ChuteStorage()
    chutes = chuteStore.getChuteList()
    for chute in chutes:
        port, service = chute.get_web_port_and_service()
        if port is None or service is None:
            continue

        container = ChuteContainer(service.get_container_name())
        if not container.isRunning():
            continue

        # Generate a rule that matches HTTP host header to chute name.
        frontend['lines'].append(
            "acl host_{} hdr(host) -i {}.chute.paradrop.org".format(
                chute.name, chute.name))
        frontend['lines'].append("use_backend {} if host_{}".format(
            chute.name, chute.name))

        # Generate rules that matches the beginning of the URL.
        # We need to be careful and either have an exact match
        # or make sure there is a slash or question mark after the chute name
        # to avoid mix-ups, e.g. "sticky-board" and "sticky-board-new".
        frontend['lines'].append("acl path_{} url /chutes/{}".format(
            chute.name, chute.name))
        frontend['lines'].append("acl path_{} url_beg /chutes/{}/".format(
            chute.name, chute.name))
        frontend['lines'].append("acl path_{} url_beg /chutes/{}?".format(
            chute.name, chute.name))

        # Try to find a host binding for the web port to redirect:
        # http://<host addr>/chutes/<chute>/<path> ->
        # http://<host addr>:<chute port>/<path>
        #
        # We need to do a lookup because the host port might be dynamically
        # assigned by Docker.
        #
        # Use HTTP code 302 for the redirect, which will not be cached by the
        # web browser.  The port portion of the URL can change whenever the
        # chute restarts, so we don't want web browsers to cache it.  Browsers
        # will cache a 301 (Moved Permanently) response.
        portconf = container.getPortConfiguration(port, "tcp")
        if len(portconf) > 0:
            # TODO: Are there other elements in the list?
            binding = portconf[0]
            frontend['lines'].append(
                "http-request redirect location http://%[req.hdr(host)]:{}%[var(req.subpath)]%[var(req.querymarker)]%[query] code 302 if path_{}"
                .format(binding['HostPort'], chute.name))

        # Add a server at the chute's IP address.
        sections.append({
            "header":
            "backend {}".format(chute.name),
            "lines": [
                "server {} {}:{} maxconn 256".format(chute.name,
                                                     container.getIP(), port)
            ]
        })

    return sections
Esempio n. 9
0
    def prepare(self):
        report = StateReport()

        report.name = nexus.core.info.pdid

        report.osVersion = system_info.getOSVersion()

        # We can get the paradrop version from the installed python package.
        report.paradropVersion = system_info.getPackageVersion('paradrop')

        report.chutes = []
        chuteStore = ChuteStorage()
        chutes = chuteStore.getChuteList()
        allocation = resource.computeResourceAllocation(chutes)

        for chute in chutes:
            service_info = {}
            for service in chute.get_services():
                container_name = service.get_container_name()
                container = ChuteContainer(container_name)

                service_info[service.name] = {
                    'allocation': allocation.get(container_name, None),
                    'state': container.getStatus()
                }

            # Use the default service (e.g. "main") to report the chute's
            # current state.
            service = chute.get_default_service()
            container = ChuteContainer(service.get_container_name())

            report.chutes.append({
                'name':
                chute.name,
                'desired':
                chute.state,
                'state':
                container.getStatus(),
                'services':
                service_info,
                'warning':
                None,
                'version':
                getattr(chute, 'version', None),
                'allocation':
                None,  # deprecated
                'environment':
                getattr(chute, 'environment', None),
                'external':
                getattr(chute, 'external', None),
                'resources':
                getattr(chute, 'resources', None)
            })

        report.devices = devices.listSystemDevices()
        report.hostConfig = hostconfig.prepareHostConfig(write=False)

        if GovernorClient.isAvailable():
            client = GovernorClient()
            report.snaps = client.listSnaps()

        report.zerotierAddress = zerotier.getAddress()
        report.dmi = system_info.getDMI()

        # Add CPU, memory, disk, and network interface information.  This gives
        # the controller useful debugging information such as high memory or
        # disk utilization and IP addresses.
        status_source = SystemStatus()
        report.status = status_source.getStatus(max_age=None)

        return report.__dict__
Esempio n. 10
0
    def prepare(self):
        report = StateReport()

        report.name = nexus.core.info.pdid

        report.osVersion = system_info.getOSVersion()

        # We can get the paradrop version from the installed python package.
        report.paradropVersion = system_info.getPackageVersion('paradrop')

        report.chutes = []
        chuteStore = ChuteStorage()
        chutes = chuteStore.getChuteList()
        allocation = resource.computeResourceAllocation(chutes)

        for chute in chutes:
            service_info = {}
            for service in chute.get_services():
                container_name = service.get_container_name()
                container = ChuteContainer(container_name)

                service_info[service.name] = {
                    'allocation': allocation.get(container_name, None),
                    'state': container.getStatus()
                }

            # Use the default service (e.g. "main") to report the chute's
            # current state.
            service = chute.get_default_service()
            container = ChuteContainer(service.get_container_name())

            report.chutes.append({
                'name': chute.name,
                'desired': chute.state,
                'state': container.getStatus(),
                'services': service_info,
                'warning': None,
                'version': getattr(chute, 'version', None),
                'allocation': None,  # deprecated
                'environment': getattr(chute, 'environment', None),
                'external': getattr(chute, 'external', None),
                'resources': getattr(chute, 'resources', None)
            })

        report.devices = devices.listSystemDevices()
        report.hostConfig = hostconfig.prepareHostConfig(write=False)

        if GovernorClient.isAvailable():
            client = GovernorClient()
            report.snaps = client.listSnaps()

        report.zerotierAddress = zerotier.getAddress()
        report.dmi = system_info.getDMI()

        # Add CPU, memory, disk, and network interface information.  This gives
        # the controller useful debugging information such as high memory or
        # disk utilization and IP addresses.
        status_source = SystemStatus()
        report.status = status_source.getStatus(max_age=None)

        return report.__dict__