From 7cdc1a5e41edcc89c3ab705d4a7f6cdf16502144 Mon Sep 17 00:00:00 2001 From: raccoon-mh Date: Wed, 26 Nov 2025 15:13:43 +0900 Subject: [PATCH] feat: enhance GoogleCloudConnector with proxy support and update requirements - Added proxy support in GoogleCloudConnector to allow connections through an HTTP proxy. - Updated pip_requirements.txt to include PySocks for proxy functionality. - Improved logging in MonitoringService to indicate when a proxy is being used. --- pkg/pip_requirements.txt | 3 +- .../monitoring/libs/google_cloud_connector.py | 85 ++++++++++++++++--- .../monitoring/service/monitoring_service.py | 16 +++- 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/pkg/pip_requirements.txt b/pkg/pip_requirements.txt index 3da95af..1c43092 100644 --- a/pkg/pip_requirements.txt +++ b/pkg/pip_requirements.txt @@ -1,4 +1,5 @@ google-api-python-client schematics spaceone-api>=1.0.0,<2.0.0 -spaceone-core>=1.0.0,<2.0.0 \ No newline at end of file +spaceone-core>=1.0.0,<2.0.0 +PySocks # for proxy support \ No newline at end of file diff --git a/src/cloudforet/monitoring/libs/google_cloud_connector.py b/src/cloudforet/monitoring/libs/google_cloud_connector.py index 61052c3..c3520d6 100644 --- a/src/cloudforet/monitoring/libs/google_cloud_connector.py +++ b/src/cloudforet/monitoring/libs/google_cloud_connector.py @@ -1,17 +1,21 @@ import logging +import os + import google.oauth2.service_account import googleapiclient import googleapiclient.discovery -import logging +import httplib2 +import socks +from google_auth_httplib2 import AuthorizedHttp from spaceone.core.connector import BaseConnector -DEFAULT_SCHEMA = 'google_oauth_client_id' +DEFAULT_SCHEMA = "google_oauth_client_id" _LOGGER = logging.getLogger(__name__) class GoogleCloudConnector(BaseConnector): - google_client_service = 'compute' - version = 'v1' + google_client_service = "compute" + version = "v1" def __init__(self, *args, **kwargs): """ @@ -28,24 +32,77 @@ def __init__(self, *args, **kwargs): """ super().__init__(*args, **kwargs) - secret_data = kwargs.get('secret_data') - self.project_id = secret_data.get('project_id') - self.credentials = google.oauth2.service_account.Credentials.from_service_account_info(secret_data) - self.client = googleapiclient.discovery.build(self.google_client_service, - self.version, - credentials=self.credentials) + secret_data = kwargs.get("secret_data") + self.project_id = secret_data.get("project_id") + self.credentials = ( + google.oauth2.service_account.Credentials.from_service_account_info( + secret_data + ) + ) + proxy_http = self._create_http_client() + if proxy_http: + self.client = googleapiclient.discovery.build( + self.google_client_service, + self.version, + http=AuthorizedHttp( + self.credentials.with_scopes( + [ + "https://www.googleapis.com/auth/cloud-platform" + ] # FOR PROXY SCOPE SUPPORT + ), + http=proxy_http, + ), + ) + else: + self.client = googleapiclient.discovery.build( + self.google_client_service, + self.version, + credentials=self.credentials, + ) def verify(self, **kwargs): if self.client is None: self.set_connect(**kwargs) def generate_query(self, **query): - query.update({ - 'project': self.project_id, - }) + query.update( + { + "project": self.project_id, + } + ) return query def list_zones(self, **query): query = self.generate_query(**query) result = self.client.zones().list(**query).execute() - return result.get('items', []) + return result.get("items", []) + + def _create_http_client(self): + https_proxy = os.environ.get("HTTPS_PROXY") or os.environ.get("https_proxy") + + if https_proxy: + # _LOGGER.info( + # f"** Using proxy in environment variable HTTPS_PROXY/https_proxy: {https_proxy}" + # ) # TOO MANY LOGGING + try: + proxy_url = https_proxy.replace("http://", "").replace("https://", "") + if ":" in proxy_url: + proxy_host, proxy_port = proxy_url.split(":", 1) + proxy_port = int(proxy_port) + + proxy_info = httplib2.ProxyInfo( + proxy_host=proxy_host, + proxy_port=proxy_port, + proxy_type=socks.PROXY_TYPE_HTTP, + ) + + return httplib2.Http( + proxy_info=proxy_info, disable_ssl_certificate_validation=True + ) + except Exception as e: + _LOGGER.warning( + f"Failed to configure proxy. Using direct connection.: {e}. " + ) + return None + else: + return None diff --git a/src/cloudforet/monitoring/service/monitoring_service.py b/src/cloudforet/monitoring/service/monitoring_service.py index 96ae19e..bcbc8d0 100644 --- a/src/cloudforet/monitoring/service/monitoring_service.py +++ b/src/cloudforet/monitoring/service/monitoring_service.py @@ -1,5 +1,8 @@ import logging +import os + from spaceone.core.service import * + from cloudforet.monitoring.manager.monitoring_manager import MonitoringManager _LOGGER = logging.getLogger(__name__) @@ -13,10 +16,10 @@ def __init__(self, metadata): super().__init__(metadata) @transaction - @check_required(['options', 'secret_data', 'query', 'start', 'end']) - @change_timestamp_value(['start', 'end'], timestamp_format='iso8601') + @check_required(["options", "secret_data", "query", "start", "end"]) + @change_timestamp_value(["start", "end"], timestamp_format="iso8601") def list_logs(self, params): - """ Get quick list of resources + """Get quick list of resources Args: params (dict) { @@ -33,6 +36,13 @@ def list_logs(self, params): Returns: list of resources """ + + proxy_env = os.environ.get("HTTPS_PROXY") or os.environ.get("https_proxy") + if proxy_env: + _LOGGER.info( + f"** Using proxy in environment variable HTTPS_PROXY/https_proxy: {proxy_env}" + ) # src/cloudforet/monitoring/libs/google_cloud_connector.py _create_http_client + mon_manager = self.locator.get_manager(MonitoringManager) for logs in mon_manager.list_logs(params): yield logs