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)
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")
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
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
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