File manager - Edit - /home/newsbmcs.com/public_html/static/img/logo/clouds.tar
Back
gcp.py 0000644 00000010106 15030505054 0005662 0 ustar 00 import base64 import json import logging import os from typing import Any, Dict, List, Optional # noqa: F401 from uaclient import exceptions, http, secret_manager, system, util from uaclient.clouds import AutoAttachCloudInstance LOG = logging.getLogger(util.replace_top_level_logger_name(__name__)) TOKEN_URL = ( "http://metadata/computeMetadata/v1/instance/service-accounts/" "default/identity?audience=contracts.canonical.com&" "format=full&licenses=TRUE" ) LICENSES_URL = ( "http://metadata.google.internal/computeMetadata/v1/instance/licenses/" "?recursive=true" ) WAIT_FOR_CHANGE = "&wait_for_change=true" LAST_ETAG = "&last_etag={etag}" DMI_PRODUCT_NAME = "/sys/class/dmi/id/product_name" GCP_PRODUCT_NAME = "Google Compute Engine" GCP_LICENSES = { "xenial": "8045211386737108299", "bionic": "6022427724719891830", "focal": "599959289349842382", "jammy": "2592866803419978320", "noble": "2176054482269786025", } class UAAutoAttachGCPInstance(AutoAttachCloudInstance): def __init__(self): # store ETAG # https://cloud.google.com/compute/docs/metadata/querying-metadata#etags # noqa self.etag = None # type: Optional[str] # mypy does not handle @property around inner decorators # https://github.com/python/mypy/issues/1362 @property # type: ignore @util.retry(exceptions.CloudMetadataError, retry_sleeps=[0.5, 1, 1]) def identity_doc(self) -> Dict[str, Any]: response = http.readurl( TOKEN_URL, headers={"Metadata-Flavor": "Google"}, timeout=1 ) if response.code == 200: secret_manager.secrets.add_secret(response.body) return {"identityToken": response.body} error_desc = response.json_dict.get("error_description") if error_desc and "service account" in error_desc.lower(): raise exceptions.GCPServiceAccountError( status_code=response.code, error_msg=error_desc ) raise exceptions.CloudMetadataError( code=response.code, body=response.body ) @property def cloud_type(self) -> str: return "gcp" @property def is_viable(self) -> bool: """This machine is a viable GCPInstance""" if os.path.exists(DMI_PRODUCT_NAME): product_name = system.load_file(DMI_PRODUCT_NAME) if GCP_PRODUCT_NAME == product_name.strip(): return True return False def get_licenses_from_identity(self) -> List[str]: """Get a list of licenses from the GCP metadata. Instance identity token (jwt) carries a list of licenses associated with the instance itself. Returns an empty list if licenses are not present in the metadata. """ token = self.identity_doc["identityToken"] identity = base64.urlsafe_b64decode(token.split(".")[1] + "===") identity_dict = json.loads(identity.decode("utf-8")) return ( identity_dict.get("google", {}) .get("compute_engine", {}) .get("license_id", []) ) def should_poll_for_pro_license(self) -> bool: series = system.get_release_info().series if series not in GCP_LICENSES: LOG.info("This series isn't supported for GCP auto-attach.") return False return True def is_pro_license_present(self, *, wait_for_change: bool) -> bool: url = LICENSES_URL if wait_for_change: url += WAIT_FOR_CHANGE if self.etag: url += LAST_ETAG.format(etag=self.etag) response = http.readurl(url, headers={"Metadata-Flavor": "Google"}) if response.code == 200: license_ids = [license["id"] for license in response.json_list] self.etag = response.headers.get("etag") series = system.get_release_info().series return GCP_LICENSES.get(series) in license_ids LOG.error(response.body) if response.code == 400: raise exceptions.CancelProLicensePolling() else: raise exceptions.DelayProLicensePolling() __pycache__/gcp.cpython-310.pyc 0000644 00000010500 15030505054 0012217 0 ustar 00 o �ϴfF � @ s� d dl Z d dlZd dlZd dlZd dlmZmZmZmZ d dl m Z mZmZm Z mZ d dlmZ e�e�e��ZdZdZdZdZd Zd Zddd ddd�ZG dd� de�ZdS )� N)�Any�Dict�List�Optional)� exceptions�http�secret_manager�system�util)�AutoAttachCloudInstancez�http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=contracts.canonical.com&format=full&licenses=TRUEzThttp://metadata.google.internal/computeMetadata/v1/instance/licenses/?recursive=truez&wait_for_change=truez&last_etag={etag}z/sys/class/dmi/id/product_namezGoogle Compute Engine�8045211386737108299�6022427724719891830�599959289349842382�2592866803419978320�2176054482269786025)�xenial�bionic�focal�jammy�noblec @ s� e Zd Zdd� Zeejejg d�d�de e ef fdd���Zede fdd ��Z edefd d��Zdee fdd �Zdefdd�Zdedefdd�ZdS )�UAAutoAttachGCPInstancec C s d | _ d S )N��etag��self� r �5/usr/lib/python3/dist-packages/uaclient/clouds/gcp.py�__init__% s z UAAutoAttachGCPInstance.__init__)g �?� r )�retry_sleeps�returnc C st t jtddidd�}|jdkrtj�|j� d|jiS |j� d�}|r1d|� � v r1tj|j|d ��tj |j|jd ��)N�Metadata-Flavor�Googler )�headers�timeout�� � identityToken�error_descriptionzservice account)�status_code� error_msg)�code�body)r �readurl� TOKEN_URLr* r �secrets� add_secretr+ � json_dict�get�lowerr �GCPServiceAccountError�CloudMetadataError)r �response� error_descr r r �identity_doc, s � ��z$UAAutoAttachGCPInstance.identity_docc C s dS )N�gcpr r r r r � cloud_type? s z"UAAutoAttachGCPInstance.cloud_typec C s* t j�t�rt�t�}t|�� krdS dS )z$This machine is a viable GCPInstanceTF)�os�path�exists�DMI_PRODUCT_NAMEr � load_file�GCP_PRODUCT_NAME�strip)r �product_namer r r � is_viableC s z!UAAutoAttachGCPInstance.is_viablec C sN | j d }t�|�d�d d �}t�|�d��}|�di ��di ��dg �S ) z�Get a list of licenses from the GCP metadata. Instance identity token (jwt) carries a list of licenses associated with the instance itself. Returns an empty list if licenses are not present in the metadata. r&