From 84aa635bb32a9bbcb26752a67e20df649c776c76 Mon Sep 17 00:00:00 2001 From: bra-fsn Date: Wed, 14 Aug 2024 22:52:55 +0200 Subject: [PATCH] Sentry support --- pyproject.toml | 4 ++- src/sc_runner/cloud_meta.py | 49 +++++++++++++++++++++++++++++++++++++ src/sc_runner/runner.py | 21 ++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/sc_runner/cloud_meta.py diff --git a/pyproject.toml b/pyproject.toml index 9a3b27a..c13b369 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,13 +4,15 @@ build-backend = "setuptools.build_meta" [project] name = "sparecores-runner" -version = "0.0.21" +version = "0.0.22" requires-python = ">= 3.9" dependencies = [ "click", "pulumi", "pulumi-aws", "pulumi-gcp", + "requests", + "sentry-sdk", "sparecores-crawler>=0.2.1", "sparecores-data>=0.2.1", "sqlmodel", diff --git a/src/sc_runner/cloud_meta.py b/src/sc_runner/cloud_meta.py new file mode 100644 index 0000000..f9b8f69 --- /dev/null +++ b/src/sc_runner/cloud_meta.py @@ -0,0 +1,49 @@ +import requests + +# Define metadata service endpoints for each cloud provider +CLOUD_METADATA_ENDPOINTS = { + "aws": "http://169.254.169.254/latest/meta-data/instance-id", + "azure": "http://169.254.169.254/metadata/instance/compute/vmId?api-version=2021-02-01", + "gcp": "http://metadata.google.internal/computeMetadata/v1/instance/id", + "alibaba": "http://100.100.100.200/latest/meta-data/instance-id", + "digitalocean": "http://169.254.169.254/metadata/v1/id", + "oracle": "http://169.254.169.254/opc/v1/instance/id", + "openstack": "http://169.254.169.254/openstack/latest/meta_data.json", +} + +# Headers required for specific cloud providers +CLOUD_METADATA_HEADERS = { + "gcp": {"Metadata-Flavor": "Google"}, + "azure": {"Metadata": "true"}, +} + + +def check_endpoint(url, headers=None): + try: + response = requests.get(url, headers=headers, timeout=1) + if response.status_code == 200: + return response + except requests.exceptions.RequestException: + pass + return None + +def get_instance_id(): + for cloud, url in CLOUD_METADATA_ENDPOINTS.items(): + headers = CLOUD_METADATA_HEADERS.get(cloud, {}) + response = check_endpoint(url, headers) + if response: + if cloud == "openstack": + # OpenStack returns JSON, extract instance ID accordingly + data = response.json() + return data.get("uuid"), "openstack" + else: + return response.text.strip(), cloud + return None, None + +if __name__ == "__main__": + instance_id, cloud_provider = get_instance_id() + if instance_id: + print(f"Cloud Provider: {cloud_provider.upper()}") + print(f"Instance ID: {instance_id}") + else: + print("Could not determine the cloud environment or fetch the instance ID.") diff --git a/src/sc_runner/runner.py b/src/sc_runner/runner.py index 923b4ed..93bc5f8 100644 --- a/src/sc_runner/runner.py +++ b/src/sc_runner/runner.py @@ -1,5 +1,7 @@ from . import DefaultOpt from . import resources +from .cloud_meta import get_instance_id +from importlib.metadata import version, PackageNotFoundError from pulumi.automation import LocalWorkspaceOptions from pulumi.automation import ProjectBackend from pulumi.automation import ProjectSettings @@ -7,6 +9,18 @@ from typing import Annotated, Callable, get_type_hints import click import os +import sentry_sdk + + +def get_installed_package_version(package_name: str) -> str: + try: + return version(package_name) + except PackageNotFoundError: + return f"Package '{package_name}' is not installed." + +instance_id, cloud_provider = get_instance_id() +sentry_sdk.set_context("cloud_metadata", {"instance-id": instance_id, "cloud-provider": cloud_provider}) +sentry_sdk.init(release=get_installed_package_version("sparecores-runner")) def get_stack_name(vendor: str, func: Callable, resource_opts: dict) -> str: @@ -31,6 +45,13 @@ def pulumi_stack( click.Option(["--stack-name"], type=str, help="Pulumi stack name, defaults to {vendor}.{region}.{zone}.{instance_id} or similar")] = os.environ.get("PULUMI_STACK_NAME", ""), ): + sentry_sdk.set_context("pulumi", { + "project_name": project_name, + "work_dir": work_dir, + "pulumi_home": pulumi_home, + "pulumi_backend_url": pulumi_backend_url, + "stack_name": stack_name, + }) stack = create_or_select_stack( stack_name=stack_name, project_name=project_name,