def download(service_label, backup_id, filepath): settings = project.read_settings() session = client.acquire_session(settings) service_id = services.get_by_label(session, settings["environmentId"], service_label) job = jobs.retrieve(session, settings["environmentId"], service_id, backup_id) if job["type"] != "backup" or job["status"] != "finished": output.error("Only 'finished' 'backup' jobs may be downloaded with this command") output.write("Downloading backup %s" % (backup_id,)) url = services.get_temporary_url(session, settings["environmentId"], service_id, backup_id) r = requests.get(url, stream=True) basename = os.path.basename(filepath) dir = tempfile.mkdtemp() tmp_filepath = os.path.join(dir, basename) with open(tmp_filepath, 'wb+') as f: for chunk in r.iter_content(chunk_size=1024): if chunk: f.write(chunk) f.flush() output.write("Decrypting...") decryption = AESCrypto.Decryption(tmp_filepath, job["backup"]["key"], job["backup"]["iv"]) decryption.decrypt(filepath) os.remove(tmp_filepath) output.write("%s downloaded successfully to %s" % (service_label, filepath))
def metrics(service_label, format, stream, mins): """Print out metrics about a single service or all services in an environment.""" if stream and (format or mins != 1): output.error("--stream cannot be used with a custom format or multiple records.") if format is None: transformer = TextTransformer() elif format == "csv": transformer = CSVTransformer() elif format == "json": transformer = JSONTransformer() else: output.error("unrecognized format '%s'" % (format,)) settings = project.read_settings() session = client.acquire_session(settings) if service_label is None: transformer.set_group_mode() transformer.set_retriever(lambda: environments.retrieve_metrics(session, settings["environmentId"], mins)) else: service_id = services.get_by_label(session, settings["environmentId"], service_label) transformer.set_retriever( lambda: services.retrieve_metrics(session, settings["environmentId"], service_id, mins) ) transformer.process(stream)
def poll_until_complete(session, env_id, svc_id, job_id): while True: job = retrieve(session, env_id, svc_id, job_id) if job["status"] not in ["scheduled", "queued", "started", "running"]: if job["status"] == "finished": return job else: output.error("\nJob ended in status '%s'. Check log for details.") sys.exit(1) break sys.stdout.write(".") time.sleep(2)
def request_console(session, env_id, svc_id, command = None): route = "%s/v1/environments/%s/services/%s/console" % (config.paas_host, env_id, svc_id) body = {} if command is not None: body["command"] = command resp = session.post(route, body, verify = False) if resp.status_code == 404: output.error("This hosting environment does not yet support secure console.") elif not is_ok(resp): raise ClientError(resp) else: return resp.json()
def poll_status(session, env_id, task_id, exit_on_error=True): route = "%s/v1/environments/%s/tasks/%s" % (config.paas_host, env_id, task_id) while True: time.sleep(2) task = session.get(route, verify = True) if task["status"] not in ["scheduled", "queued", "started", "running"]: if task["status"] == "finished": return task else: output.write("") output.error("Error - ended in status '%s'." % (task["status"],), exit=exit_on_error) else: output.write(".", sameline = True)
def read_settings(required = True): if os.path.isdir("./.git"): if os.path.isfile(FILE_PATH): with open(FILE_PATH, 'r') as file: return json.load(file) else: if required: output.error("No Catalyze environment associated with this local repo. Run \"catalyze associate\" first.") return None elif required: output.error("No git repo found in the current directory.") else: return None
def set(variables): """Set or update one or more variables. Expects variables in the form <key>=<value>. Multiple variables can be set at once. Variable changes will not take effect in the application until it is redeployed (via either a push or 'catalyze redeploy').""" settings = project.read_settings() session = client.acquire_session(settings) body = {} for var in variables: pieces = var.split("=", 1) if len(pieces) != 2: output.error("Expected argument form: <key>=<value>") else: body[pieces[0]] = pieces[1] environment_variables.set(session, settings["environmentId"], settings["serviceId"], body)
def associate(env_label, service_label, remote): """Associates the git repository in the current directory. This means that the service and environment IDs are stored locally, and a git remote is created (default name = "catalyze") so that code can be pushed, built, and deployed.""" session = client.acquire_session() for env in environments.list(session): if env["data"]["name"] == env_label: settings = { "token": session.token, "user_id": session.user_id, "environmentId": env["environmentId"] } code_services = [svc for svc in services.list(session, env["environmentId"]) if svc["type"] == "code"] selected_service = None if len(code_services) == 0: output.error("No code service found for \"%s\" environment (%s)" % (env_label, env["environmentId"])) elif service_label: for svc in code_services: if svc["label"] == service_label: selected_service = svc break if selected_service is None: output.error("No code service found with label '%s'. Labels found: %s" % \ (service_label, ", ".join([svc["label"] for svc in code_services]))) elif len(code_services) > 1: output.error("Found multiple code services. Must pass one specifically to associate with. Labels found: " + \ ", ".join([svc["label"] for svc in code_services])) else: selected_service = code_services[0] if remote in git.remote_list(): git.remote_remove(remote) git.remote_add(remote, selected_service["source"]) settings["serviceId"] = selected_service["id"] project.save_settings(settings) output.write("\"%s\" remote added." % (remote,)) return output.error("No environment with label \"%s\" found." % (env_label,))
def metadata(session, pod_id): route = "%s/v1/pods/metadata" % (config.paas_host,) for pod in session.get(route, verify = True): if pod["id"] == pod_id: return pod output.error("Could not find the pod associated with this environment. Please contact Catalyze support. Please include your environment ID - found via \"catalyze support-ids\"")
def excepthook(exc_type, value, traceback): if exc_type in [AuthError, ClientError]: if type(value.message) is dict: if "errors" in value.message: errors = value.message["errors"] if len(errors) == 0: output.error("Unknown error") else: for error in errors: if "title" in error: output.error("%(title)s (%(description)s)" % error) else: output.error("%(message)s (%(code)d)" % error) elif "title" in value.message and "description" in value.message: output.error("%(title)s (%(description)s)" % value.message) else: output.error(value) else: output.error(value) else: previous_hook(exc_type, value, traceback)
def get_by_label(session, env_id, label): for service in list(session, env_id): if service["label"] == label: return service["id"] output.error("Could not find service with label '%s'" % (label,))