Example #1
0
    def get_cluster():
        """Return a handle to the single compute cluster that is
           connected to this compute service
        """
        if not Cluster._is_running_service():
            raise PermissionError(
                "You can only call 'get_cluster' on the compute service")

        from Acquire.ObjectStore import ObjectStore as _ObjectStore
        from Acquire.Service import get_service_account_bucket \
            as _get_service_account_bucket

        bucket = _get_service_account_bucket()
        key = "compute/cluster"

        try:
            data = _ObjectStore.get_object_from_json(bucket, key)
        except:
            data = None

        if data is None:
            from Acquire.Service import ServiceError
            raise ServiceError(
                "You have not set the cluster that will be used to actually "
                "run the compute jobs!")

        return Cluster.from_data(data)
Example #2
0
 def _fail(self):
     """This is called by all functions as this Service
        has failed to be initialised
     """
     if self._failed:
         from Acquire.Service import ServiceError
         raise ServiceError("Cannot do anything with a null service")
    def get_trusted_storage_service(self):
        """Return a trusted storage service

            Returns:
                :obj:`dict`: containing the first storage
                device on the trusted service

        """
        from Acquire.Service import get_trusted_services \
            as _get_trusted_services

        services = _get_trusted_services()

        try:
            return services["storage"][0]
        except:
            from Acquire.Service import ServiceError
            raise ServiceError(
                "There is no trusted storage service known to this access "
                "service")
Example #4
0
    def accounting_service(self):
        """Return the accounting service that will honour this cheque.
           Note that this will only return the service if it is trusted
           by the service on which this function is called

           Returns:
                Service: Trusted accounting service

        """
        from Acquire.Service import get_this_service as _get_this_service
        service = _get_this_service()
        accounting_service = service.get_trusted_service(
                                            self.accounting_service_url())

        if not accounting_service.is_accounting_service():
            from Acquire.Service import ServiceError
            raise ServiceError(
                "The service that is supposed to honour the cheque (%s) "
                "does not appear to be a valid accounting service" %
                (str(accounting_service)))

        return accounting_service
def get_trusted_registry_service(registry_uid=None,
                                 service_uid=None,
                                 service_url=None):
    """Return the trusted service info for the registry with specified
       registry_uid, or get any trusted registry service using either
       'service_uid' or 'service_url' as a starting hint to
       locate a suitable registry
    """
    if service_uid is not None:
        # for the moment, just try to get one registry. Eventually we should
        # try to get several in case this one is down
        registry_uid = get_primary_registry_uid(service_uid)
        return get_trusted_registry_service(registry_uid=registry_uid)

    if service_url is not None:
        if service_url.find(".") != -1:
            # try the main acquire registry first
            return get_trusted_registry_service(registry_uid="a0-a0")
        else:
            # this must be testing...
            return get_trusted_registry_service(registry_uid="Z9-Z9")

    if registry_uid is None:
        raise PermissionError(
            "You must specify one of registry_uid, service_uid "
            "or service_url")

    from Acquire.Service import get_trusted_service as _get_trusted_service

    try:
        registry_service = _get_trusted_service(service_uid=registry_uid,
                                                autofetch=False)
    except:
        registry_service = None

    if registry_service is not None:
        if not registry_service.is_registry_service():
            from Acquire.Service import ServiceError
            raise ServiceError("The requested service (%s) for %s is NOT a "
                               "registry service!" %
                               (registry_service, registry_uid))

        if registry_service.uid() != registry_uid:
            from Acquire.Service import ServiceError
            raise ServiceError(
                "Disagreement of UID (%s) is NOT the right registry service!" %
                registry_service)

        # everything is ok - we have seen this registry before
        return registry_service

    # boostrapping
    from Acquire.Registry import get_registry_details \
        as _get_registry_details

    details = _get_registry_details(registry_uid)

    from Acquire.Service import call_function as _call_function
    from Acquire.Service import Service as _Service
    from Acquire.Crypto import get_private_key as _get_private_key
    from Acquire.Crypto import PrivateKey as _PrivateKey
    from Acquire.Crypto import PublicKey as _PublicKey
    from Acquire.ObjectStore import bytes_to_string as _bytes_to_string
    from Acquire.ObjectStore import string_to_bytes as _string_to_bytes

    privkey = _get_private_key(key="registry")

    pubkey = _PublicKey.from_data(details["public_key"])
    pubcert = _PublicKey.from_data(details["public_certificate"])

    # ask the registry to return to us their latest details - use
    # a challenge-response to make sure that the response is
    # properly returned
    challenge = _PrivateKey.random_passphrase()
    encrypted_challenge = _bytes_to_string(pubkey.encrypt(challenge))
    args = {
        "challenge": encrypted_challenge,
        "fingerprint": pubkey.fingerprint()
    }

    result = _call_function(service_url=details["canonical_url"],
                            function=None,
                            args=args,
                            args_key=pubkey,
                            response_key=privkey,
                            public_cert=pubcert)

    if result["response"] != challenge:
        from Acquire.Service import ServiceError
        raise ServiceError(
            "The requested service (%s) failed to respond to the challenge!" %
            registry_service)

    registry_service = _Service.from_data(result["service_info"])

    if not registry_service.is_registry_service():
        from Acquire.Service import ServiceError
        raise ServiceError(
            "The requested service (%s) is NOT a registry service!" %
            registry_service)

    if registry_service.uid() != details["uid"]:
        from Acquire.Service import ServiceError
        raise ServiceError(
            "Disagreement of UID (%s) is NOT the right registry service!" %
            registry_service)

    # ok - we've got the registry - add this to the set of
    # trusted services so that we don't need to bootstrap from
    # the registry details again
    from Acquire.Service import trust_service as _trust_service
    _trust_service(registry_service)

    return registry_service
Example #6
0
    def get_service(self, service=None, service_url=None, service_uid=None,
                    service_type=None, autofetch=True):
        """Return the service at either 'service_url', or that
           has UID 'service_uid'. This will return the
           cached service if it exists, or will add a new service if
           we are able to validate it from a trusted registry
        """
        from Acquire.ObjectStore import string_to_safestring \
            as _string_to_safestring
        from Acquire.Service import Service as _Service

        if service is not None:
            s = _Service.resolve(service, fetch=False)

            if s["service"] is not None:
                self.add_service(s["service"])
                return s["service"]

            service_uid = s["service_uid"]
            service_url = s["service_url"]

        service = None
        import glob as _glob

        if service_url is None:
            if service_uid is None:
                raise PermissionError(
                    "You need to specify one of service_uid or service_url")

            # we need to look up the name...
            service_dir = Wallet._get_service_dir(service_uid)
            service_files = _glob.glob("%s/service_*.json" % service_dir)

            for service_file in service_files:
                s = _read_service(service_file)
                if s.uid() == service_uid:
                    service = s
                    break
        else:
            from Acquire.Service import Service as _Service
            service_url = _Service.get_canonical_url(service_url,
                                                     service_type=service_type)

            service_files = _glob.glob("%s/*/service_%s.json" % (
                                       self._wallet_dir,
                                       _string_to_safestring(service_url)))

            for service_file in service_files:
                s = _read_service(service_file)
                if s.canonical_url() == service_url:
                    service = s
                    break

        must_write = False

        if service is None:
            if not autofetch:
                from Acquire.Service import ServiceError
                raise ServiceError("No service at %s:%s" %
                                   (service_url, service_uid))

            # we need to look this service up from the registry
            service = self._get_service_from_registry(service_url=service_url,
                                                      service_uid=service_uid)
            must_write = True

        # check if the keys need rotating - if they do, load up
        # the new keys and save them to the service file...
        elif service.should_refresh_keys():
            try:
                service.refresh_keys()
                must_write = True
            except:
                # something went wrong refreshing keys - go back to the
                # registry...
                _output("Something went wrong refreshing keys...")
                _output("Refreshing service from the registry.")
                service = self._get_service_from_registry(
                                                service_url=service_url,
                                                service_uid=service_uid)
                must_write = True

        if service_uid is not None:
            if service.uid() != service_uid:
                raise PermissionError(
                    "Disagreement over the service UID for '%s' (%s)" %
                    (service, service_uid))

        if must_write:
            self.add_service(service)

        return service
Example #7
0
    def get_service(self, service_url=None, service_uid=None,
                    service_type=None, autofetch=True):
        """Return the service at either 'service_url', or that
           has UID 'service_uid'. This will return the
           cached service if it exists, or will add a new service if
           we are able to validate it from a trusted registry
        """
        from Acquire.ObjectStore import string_to_safestring \
            as _string_to_safestring

        service = None

        if service_url is None:
            if service_uid is None:
                raise PermissionError(
                    "You need to specify one of service_uid or service_url")

            # we need to look up the name...
            import glob as _glob
            service_files = _glob.glob("%s/service_*" % self._wallet_dir)

            for service_file in service_files:
                s = _read_service(service_file)
                if s.uid() == service_uid:
                    service = s
                    break
        else:
            from Acquire.Service import Service as _Service
            service_url = _Service.get_canonical_url(service_url,
                                                     service_type=service_type)

            service_file = "%s/service_%s" % (
                self._wallet_dir,
                _string_to_safestring(service_url))

            try:
                service = _read_service(service_file)
            except:
                pass

        must_write = False

        if service is None:
            if not autofetch:
                from Acquire.Service import ServiceError
                raise ServiceError("No service at %s:%s" %
                                   (service_url, service_uid))

            # we need to look this service up from the registry
            from Acquire.Registry import get_trusted_registry_service \
                as _get_trusted_registry_service

            _output("Connecting to registry...")
            _flush_output()

            registry = _get_trusted_registry_service(service_uid=service_uid,
                                                     service_url=service_url)

            _output("...connected to registry %s" % registry)
            _flush_output()

            # ensure we cache this registry...
            registry_file = "%s/service_%s" % (
                self._wallet_dir,
                _string_to_safestring(registry.canonical_url()))
            _write_service(service=registry, filename=registry_file)

            if service_url is not None:
                _output("Securely fetching keys for %s..." % service_url)
                _flush_output()
            else:
                _output("Securely fetching keys for UID %s..." % service_uid)
                _flush_output()

            service = registry.get_service(service_url=service_url,
                                           service_uid=service_uid)

            _output("...success.\nFetched %s" % service)
            _flush_output()

            must_write = True

        # check if the keys need rotating - if they do, load up
        # the new keys and save them to the service file...
        if service.should_refresh_keys():
            service.refresh_keys()
            must_write = True

        if service_uid is not None:
            if service.uid() != service_uid:
                raise PermissionError(
                    "Disagreement over the service UID for '%s' (%s)" %
                    (service, service_uid))

        if must_write:
            service_file = "%s/service_%s" % (
                self._wallet_dir,
                _string_to_safestring(service.canonical_url()))
            _write_service(service=service, filename=service_file)

        return service