def FromVersionResource(cls, version, service): """Convert appengine_<API-version>_messages.Version into wrapped Version.""" project, service_id, _ = re.match(cls._VERSION_NAME_PATTERN, version.name).groups() traffic_split = service and service.split.get(version.id, 0.0) last_deployed = None try: if version.createTime: last_deployed_dt = times.ParseDateTime( version.createTime).replace(microsecond=0) last_deployed = times.LocalizeDateTime(last_deployed_dt) except ValueError: pass if version.env == 'flexible': env = util.Environment.FLEX elif version.vm: env = util.Environment.MANAGED_VMS else: env = util.Environment.STANDARD return cls(project, service_id, version.id, traffic_split=traffic_split, last_deployed_time=last_deployed, environment=env, version_resource=version)
def _SSHKeyExpiration(ssh_key): """Returns a datetime expiration time for an ssh key entry from metadata. Args: ssh_key: A single ssh key entry. Returns: None if no expiration set or a datetime object of the expiration (in UTC). Raises: ValueError: If the ssh key entry could not be parsed for expiration (invalid format, missing expected entries, etc). dateutil.DateTimeSyntaxError: The found expiration could not be parsed. dateutil.DateTimeValueError: The found expiration could not be parsed. """ # Valid format of a key with expiration is: # <user>:<protocol> <key> google-ssh {... "expireOn": "<iso-8601>" ...} # 0 1 2 json @ 3+ key_parts = ssh_key.split() if len(key_parts) < 4 or key_parts[2] != 'google-ssh': return None expiration_json = ' '.join(key_parts[3:]) expiration = json.loads(expiration_json) try: expireon = times.ParseDateTime(expiration['expireOn']) except KeyError: raise ValueError('Unable to find expireOn entry') return times.LocalizeDateTime(expireon, times.UTC)
def _PrepareSSHKeysValue(ssh_keys): """Returns a string appropriate for the metadata. Expired SSH keys are always removed. Then Values are taken from the tail until either all values are taken or _MAX_METADATA_VALUE_SIZE_IN_BYTES is reached, whichever comes first. The selected values are then reversed. Only values at the head of the list will be subject to removal. Args: ssh_keys: A list of keys. Each entry should be one key. Returns: A new-line-joined string of SSH keys. """ keys = [] bytes_consumed = 0 now = times.LocalizeDateTime(times.Now(), times.UTC) for key in reversed(ssh_keys): try: expiration = _SSHKeyExpiration(key) expired = expiration is not None and expiration < now if expired: continue except (ValueError, times.DateTimeSyntaxError, times.DateTimeValueError) as exc: # Unable to get expiration, so treat it like it is unexpiring. log.warning( 'Treating {0!r} as unexpiring, since unable to parse: {1}'. format(key, exc)) num_bytes = len(key + '\n') if bytes_consumed + num_bytes > constants.MAX_METADATA_VALUE_SIZE_IN_BYTES: prompt_message = ( 'The following SSH key will be removed from your ' 'project because your SSH keys metadata value has ' 'reached its maximum allowed size of {0} bytes: {1}') prompt_message = prompt_message.format( constants.MAX_METADATA_VALUE_SIZE_IN_BYTES, key) console_io.PromptContinue(message=prompt_message, cancel_on_no=True) else: keys.append(key) bytes_consumed += num_bytes keys.reverse() return '\n'.join(keys)
def FromVersionResource(cls, version, service): """Convert a appengine_v1beta4_messages.Version into a wrapped Version.""" project, service_id, _ = re.match(cls._VERSION_NAME_PATTERN, version.name).groups() traffic_split = service and service.split.get(version.id, 0.0) last_deployed = None try: if version.creationTime: last_deployed_dt = times.ParseDateTime(version.creationTime).replace( microsecond=0) last_deployed = times.LocalizeDateTime(last_deployed_dt) except ValueError: pass return cls(project, service_id, version.id, traffic_split=traffic_split, last_deployed_time=last_deployed, version_resource=version)
def _TokenExpiresWithinWindow(expiry_window, token_expiry_time, max_window_seconds=3600): """Determines if token_expiry_time is within expiry_window_duration. Calculates the amount of time between utcnow() and token_expiry_time and returns true, if that amount is less thank the provided duration window. All calculations are done in number of seconds for consistency. Args: expiry_window: string, Duration representing the amount of time between now and token_expiry_time to compare against. token_expiry_time: datetime, The time when token expires. max_window_seconds: int, Maximum size of expiry window, in seconds. Raises: ValueError: If expiry_window is invalid or can not be parsed. Returns: True if token is expired or will expire with in the provided window, False otherwise. """ try: min_expiry = times.ParseDuration(expiry_window, default_suffix='s') if min_expiry.total_seconds > max_window_seconds: raise ValueError('Invalid expiry window duration [{}]: ' 'Must be between 0s and 1h'.format(expiry_window)) except times.Error as e: message = six.text_type(e).rstrip('.') raise ValueError('Error Parsing expiry window duration ' '[{}]: {}'.format(expiry_window, message)) token_expiry_time = times.LocalizeDateTime(token_expiry_time, tzinfo=dateutil.tz.tzutc()) window_end = times.GetDateTimePlusDuration( times.Now(tzinfo=dateutil.tz.tzutc()), min_expiry) return token_expiry_time <= window_end