def register_topic(self, name, func, kwargs): topic = kwargs["topic"] kwargs = kwargs.pop("kwargs") attributes = kwargs.get("attributes", {}) project = kwargs.get("project", get_default_project()) deploy_type = "trigger" if (kwargs.get("use_subscription") or project != get_default_project() or self.backend == "cloudrun"): deploy_type = "subscription" if self.resources.get(topic): self.resources[topic][deploy_type][name] = { "func": func, "attributes": attributes, "project": project, } else: self.resources[topic] = {"trigger": {}, "subscription": {}} self.resources[topic][deploy_type] = { name: { "func": func, "attributes": attributes, "project": project } }
def deploy(project, location, stage, skip_function, only_function, config, force): """ You can set the project and location using environment variable GOOGLE_PROJECT and GOOGLE_LOCATION Note: Allowed GOOGLE_LOCATION values for API GATEWAY are: asia-east1, europe-west1, us-eastl1 and us-central1. Note: Make sure api-gateway, cloudfunctions, and storage are enabled in your project """ try: _project = project or get_default_project() if not _project: click.echo( "Project not found. Set --project flag or add to gcloud by using gcloud config set project PROJECT" ) os.environ["GOOGLE_PROJECT"] = _project os.environ["GOOGLE_LOCATION"] = location if stage: os.environ["STAGE"] = stage if config: config = json.loads(config) app = get_goblet_app(GConfig().main_file or "main.py") # Deployer({"name": app.function_name}).deploy( # app, # skip_function=skip_function, # only_function=only_function, # config=config, # force=force, # ) app.deploy(skip_function, only_function, config=config, force=False) except FileNotFoundError as not_found: click.echo( f"Missing {not_found.filename}. Make sure you are in the correct directory and this file exists" )
def destroy_cloudfunction_artifacts(name): """Destroys all images stored in cloud storage that are related to the function.""" client = Client("cloudresourcemanager", "v1", calls="projects") resp = client.execute("get", parent_key="projectId", parent_schema=get_default_project()) project_number = resp["projectNumber"] region = get_default_location() if not region: raise Exception("Missing Region") bucket_name = f"gcf-sources-{project_number}-{get_default_location()}" http = client.http or google_auth_httplib2.AuthorizedHttp( get_credentials()) resp = http.request( f"https://storage.googleapis.com/storage/v1/b/{bucket_name}/o?prefix={name}" ) objects = json.loads(resp[1]) if not objects.get("items"): log.info("Artifacts already deleted") return for storage in objects["items"]: log.info(f"Deleting artifact {storage['name']}") resp = http.request( f"https://storage.googleapis.com/storage/v1/b/{bucket_name}/o/{quote_plus(storage['name'])}", method="DELETE", )
def create_cloudbuild(client, req_body): """Creates a cloudbuild based on req_body""" defaultProject = get_default_project() defaultLocation = "global" try: resp = client.execute( "create", parent_key="projectId", parent_schema=defaultProject, params={ "body": req_body, "parent": f"projects/{defaultProject}/locations/{defaultLocation}", }, ) log.info("creating cloudbuild") except HttpError as e: raise e cloudbuild_config = GConfig().cloudbuild or {} timeout_seconds = cloudbuild_config.get("timeout", "600s") if "s" not in timeout_seconds: log.info( "Not a valid timeout. Needs to be a duration that ends is 's'. Defaulting to 600s" ) timeout = 600 else: timeout = int(timeout_seconds.split("s")[0]) client.wait_for_operation(resp["name"], calls="operations", timeout=timeout)
def create_cloudrun(self, client, config={}): """Creates http cloudfunction""" config = GConfig(config=config) cloudrun_configs = config.cloudrun or {} if not cloudrun_configs.get("no-allow-unauthenticated") or cloudrun_configs.get( "allow-unauthenticated" ): cloudrun_configs["no-allow-unauthenticated"] = None cloudrun_options = [] for k, v in cloudrun_configs.items(): cloudrun_options.append(f"--{k}") if v: cloudrun_options.append(v) base_command = [ "gcloud", "run", "deploy", self.name, "--project", get_default_project(), "--region", get_default_location(), "--source", get_dir(), "--command", "functions-framework,--target=goblet_entrypoint", "--port", "8080", ] base_command.extend(cloudrun_options) try: if not os.path.exists(get_dir() + "/Dockerfile") and not os.path.exists( get_dir() + "/Procfile" ): log.info( "No Dockerfile or Procfile found for cloudrun backend. Writing default Dockerfile" ) write_dockerfile() subprocess.check_output(base_command, env=os.environ) except subprocess.CalledProcessError: log.error( "Error during cloudrun deployment while running the following command" ) log.error((" ").join(base_command)) sys.exit(1) # Set IAM Bindings if config.bindings: log.info(f"adding IAM bindings for cloudrun {self.name}") policy_bindings = {"policy": {"bindings": config.bindings}} client.execute( "setIamPolicy", parent_key="resource", parent_schema=self.run_name, params={"body": policy_bindings}, )
def getArtifact(self): defaultProject = get_default_project() buildClient = self.versioned_clients.cloudbuild resp = buildClient.execute("list", parent_key="projectId", parent_schema=defaultProject, params={}) latestBuildId = resp["builds"][0]["id"] resp = buildClient.execute( "get", parent_key="projectId", parent_schema=defaultProject, params={"id": latestBuildId}, ) self.latestArtifact = (resp["results"]["images"][0]["name"] + "@" + resp["results"]["images"][0]["digest"])
def _checksum(self): versioned_clients = VersionedClients(self.app.client_versions) resp = versioned_clients.cloudbuild.execute( "list", parent_key="projectId", parent_schema=get_default_project(), params={}, ) latest_build_source = resp["builds"][0]["source"] bucket = latest_build_source["storageSource"]["bucket"] obj = latest_build_source["storageSource"]["object"] client = Client("cloudresourcemanager", "v1", calls="projects") http = client.http or google_auth_httplib2.AuthorizedHttp( get_credentials()) resp = http.request( f"https://storage.googleapis.com/storage/v1/b/{bucket}/o/{quote_plus(obj)}?alt=media", ) try: return resp[0]["x-goog-hash"].split(",")[-1].split("=", 1)[-1] except KeyError: return 0
def destroy(project, location, stage, all): """ Deletes all resources in gcp that are defined the current deployment The --all flag removes cloudfunction artifacts in cloud storage as well """ try: _project = project or get_default_project() if not _project: click.echo( "Project not found. Set --project flag or add to gcloud by using gcloud config set project PROJECT" ) os.environ["GOOGLE_PROJECT"] = _project os.environ["GOOGLE_LOCATION"] = location if stage: os.environ["STAGE"] = stage app = get_goblet_app(GConfig().main_file or "main.py") app.destroy(all) except FileNotFoundError as not_found: click.echo( f"Missing {not_found.filename}. Make sure you are in the correct directory and this file exists" )
def sync(project, location, stage, dryrun): """ Syncs resources that are deployed with current app configuration. This command will delete resources based on naming convention that are no longer in the app configuration. Use --dryrun flag to see what resources are flagged as being deleted. """ try: _project = project or get_default_project() if not _project: click.echo( "Project not found. Set --project flag or add to gcloud by using gcloud config set project PROJECT" ) os.environ["GOOGLE_PROJECT"] = _project os.environ["GOOGLE_LOCATION"] = location if stage: os.environ["STAGE"] = stage app = get_goblet_app(GConfig().main_file or "main.py") app.sync(dryrun) except FileNotFoundError as not_found: click.echo( f"Missing {not_found.filename}. Make sure you are in the correct directory and this file exists" )