Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ keywords = [
]
requires-python = ">=3.9"
dependencies = [
"pyopenssl==24.2.1",
"azure-storage-common>=1.0",
"azure==4.0.0",
"boto",
Expand All @@ -49,11 +48,11 @@ dependencies = [
"dateparser",
"fauxfactory",
"google-api-python-client",
"google-auth",
"google-compute-engine",
"inflection",
"lxml",
"miq-version",
"oauth2client",
"openshift==0.3.4",
"ovirt-engine-sdk-python~=4.3",
"packaging",
Expand Down
49 changes: 35 additions & 14 deletions wrapanapi/systems/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
import httplib2
import iso8601
import pytz
from google.oauth2 import service_account
from googleapiclient import errors
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from oauth2client.service_account import ServiceAccountCredentials
from wait_for import wait_for

from wrapanapi.entities import Instance, Template, TemplateMixin, VmMixin, VmState
Expand Down Expand Up @@ -469,24 +469,45 @@ def __init__(self, project=None, zone=None, file_type=None, **kwargs):
cache_discovery = kwargs.get("cache_discovery", False)

if "service_account" in kwargs:
service_account = kwargs.get("service_account").copy()
service_account["private_key"] = service_account["private_key"].replace("\\n", "\n")
service_account["type"] = service_account.get("type", "service_account") # default it
credentials = ServiceAccountCredentials.from_json_keyfile_dict(
service_account, scopes=scope
service_account_info = kwargs.get("service_account").copy()
service_account_info["private_key"] = service_account_info["private_key"].replace(
"\\n", "\n"
)
service_account_info["type"] = service_account_info.get(
"type", "service_account"
) # default it
credentials = service_account.Credentials.from_service_account_info(
service_account_info, scopes=scope
)
elif file_type == "json":
file_path = kwargs.get("file_path", None)
credentials = ServiceAccountCredentials.from_json_keyfile_name(file_path, scopes=scope)
if not file_path:
raise ValueError("file_path is required when file_type='json'")
credentials = service_account.Credentials.from_service_account_file(
file_path, scopes=scope
)
elif file_type == "p12":
file_path = kwargs.get("file_path", None)
client_email = kwargs.get("client_email", None)
credentials = ServiceAccountCredentials.from_p12_keyfile(
client_email, file_path, scopes=scope
# P12 format is not directly supported by google-auth library
# Users should convert P12 files to JSON format for compatibility
raise NotImplementedError(
"P12 keyfile format is no longer supported with google-auth library. "
"Please convert your P12 file to JSON format. You can use the Google Cloud Console "
"or gcloud CLI to generate a new JSON service account key."
)
else:
raise ValueError(
"Must provide either 'service_account' dict or 'file_path' with file_type='json'"
)
http_auth = credentials.authorize(httplib2.Http())
self._compute = build("compute", "v1", http=http_auth, cache_discovery=cache_discovery)
self._storage = build("storage", "v1", http=http_auth, cache_discovery=cache_discovery)

# Create authorized HTTP transport
# Note: http_auth variable kept for compatibility but not used with newer API
http_auth = credentials # noqa: F841
self._compute = build(
"compute", "v1", credentials=credentials, cache_discovery=cache_discovery
)
self._storage = build(
"storage", "v1", credentials=credentials, cache_discovery=cache_discovery
)
self._instances = self._compute.instances()
self._forwarding_rules = self._compute.forwardingRules()
self._buckets = self._storage.buckets()
Expand Down