def SetUp(self): properties.VALUES.core.project.Set('my-project') self.StartPatch('time.sleep') # To speed up tests with polling self.mocked_cloudbuild_v1 = mock.Client( core_apis.GetClientClass('cloudbuild', 'v1')) self.mocked_cloudbuild_v1.Mock() self.addCleanup(self.mocked_cloudbuild_v1.Unmock) self.build_msg = core_apis.GetMessagesModule('cloudbuild', 'v1') self._step_statuses = self.build_msg.BuildStep.StatusValueValuesEnum self._statuses = self.build_msg.Build.StatusValueValuesEnum self._sub_options = self.build_msg.BuildOptions.SubstitutionOptionValueValuesEnum self.mocked_storage_v1 = mock.Client( core_apis.GetClientClass('storage', 'v1')) self.mocked_storage_v1.Mock() self.addCleanup(self.mocked_storage_v1.Unmock) self.storage_msg = core_apis.GetMessagesModule('storage', 'v1') self.frozen_time = '2019-07-29T00:05:00.000000Z' frozen_time = times.ParseDateTime(self.frozen_time) frozen_uuid = uuid.uuid4() self.frozen_tgz_filename = '{frozen_time}-{frozen_uuid}.tgz'.format( frozen_time=times.GetTimeStampFromDateTime(frozen_time), frozen_uuid=frozen_uuid.hex) self.frozen_tgz_filepath = 'deploy/source/{}'.format( self.frozen_tgz_filename) self.StartObjectPatch(times, 'Now', return_value=frozen_time) self.StartObjectPatch(uuid, 'uuid4', return_value=frozen_uuid) self.StartObjectPatch(os.path, 'getsize', return_value=100)
def Format(self, entry): """Safely formats a log entry into human readable text. Args: entry: A log entry message emitted from the V2 API client. Returns: A string without line breaks respecting the `max_length` property. """ text = self._LogEntryToText(entry) text = text.strip().replace('\n', ' ') try: time = times.FormatDateTime(times.ParseDateTime(entry.timestamp), self.api_time_format) except times.Error: log.warning('Received timestamp [{0}] does not match expected' ' format.'.format(entry.timestamp)) time = '????-??-?? ??:??:??' out = '{timestamp} {log_text}'.format( timestamp=time, log_text=text) if self.max_length and len(out) > self.max_length: out = out[:self.max_length - 3] + '...' return out
def Run(self, args): cert_ref = Revoke.ParseCertificateResource(args) if not console_io.PromptContinue( message='You are about to revoke Certificate [{}]'.format( cert_ref.RelativeName()), default=True): log.status.Print('Aborted by user.') return reason = flags_v1.ParseRevocationChoiceToEnum(args.reason) client = privateca_base.GetClientInstance(api_version='v1') messages = privateca_base.GetMessagesModule(api_version='v1') certificate = client.projects_locations_caPools_certificates.Revoke( messages. PrivatecaProjectsLocationsCaPoolsCertificatesRevokeRequest( name=cert_ref.RelativeName(), revokeCertificateRequest=messages.RevokeCertificateRequest( reason=reason, requestId=request_utils.GenerateRequestId()))) revoke_time = times.ParseDateTime( certificate.revocationDetails.revocationTime) log.status.Print('Revoked certificate [{}] at {}.'.format( certificate.name, times.FormatDateTime(revoke_time, tzinfo=times.LOCAL)))
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 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 TransformNotAfterTime(subject_description): """Use this function in a display transform to truncate anything smaller than minutes from ISO8601 timestamp.""" if subject_description and 'notAfterTime' in subject_description: return times.ParseDateTime( subject_description.get('notAfterTime')).astimezone( tz.tzutc()).strftime('%Y-%m-%dT%H:%MZ') return ''
def SetUp(self): self.StartPatch('time.sleep') # To speed up tests with polling self.mocked_cloudbuild_v1 = mock.Client( core_apis.GetClientClass('cloudbuild', 'v1')) self.mocked_cloudbuild_v1.Mock() self.addCleanup(self.mocked_cloudbuild_v1.Unmock) self.cloudbuild_v1_messages = core_apis.GetMessagesModule( 'cloudbuild', 'v1') self.mocked_storage_v1 = mock.Client( core_apis.GetClientClass('storage', 'v1')) self.mocked_storage_v1.Mock() self.addCleanup(self.mocked_storage_v1.Unmock) self.storage_v1_messages = core_apis.GetMessagesModule('storage', 'v1') properties.VALUES.core.project.Set('my-project') messages = self.cloudbuild_v1_messages self._statuses = messages.Build.StatusValueValuesEnum self._vmtypes = messages.BuildOptions.MachineTypeValueValuesEnum frozen_time = times.ParseDateTime('2016-05-26T00:05:00.000000Z') frozen_uuid = uuid.uuid4() self.frozen_zip_filename = 'source/{frozen_time}-{frozen_uuid}.zip'.format( frozen_time=times.GetTimeStampFromDateTime(frozen_time), frozen_uuid=frozen_uuid.hex) self.frozen_tgz_filename = 'source/{frozen_time}-{frozen_uuid}.tgz'.format( frozen_time=times.GetTimeStampFromDateTime(frozen_time), frozen_uuid=frozen_uuid.hex) self.StartObjectPatch(times, 'Now', return_value=frozen_time) self.StartObjectPatch(uuid, 'uuid4', return_value=frozen_uuid) self.StartObjectPatch(os.path, 'getsize', return_value=100)
def SamplePubsubMetadata(self): """Returns a PubsubMetadata object for use in tests.""" expire_time = times.FormatDateTime( times.ParseDateTime('2019-08-14 15:44:10')) return MESSAGE_MODULE.PubsubSnapshotMetadata(topicName='topic', snapshotName='snapshot', expireTime=expire_time)
def Run(self, args): cert_ref = _ParseCertificateResource(args) reason = flags.ParseRevocationChoiceToEnum(args.reason) client = privateca_base.GetClientInstance() messages = privateca_base.GetMessagesModule() operation = client.projects_locations_certificateAuthorities_certificates.Revoke( messages. PrivatecaProjectsLocationsCertificateAuthoritiesCertificatesRevokeRequest( name=cert_ref.RelativeName(), revokeCertificateRequest=messages.RevokeCertificateRequest( reason=reason, requestId=request_utils.GenerateRequestId()))) response = operations.Await(operation, 'Revoking Certificate.') certificate = operations.GetMessageFromResponse( response, messages.Certificate) log.status.Print('Publishing a new Certificate Revocation List.') client.projects_locations_certificateAuthorities.PublishCrl( messages. PrivatecaProjectsLocationsCertificateAuthoritiesPublishCrlRequest( name=cert_ref.Parent().RelativeName(), publishCertificateRevocationListRequest=messages. PublishCertificateRevocationListRequest())) revoke_time = times.ParseDateTime( certificate.revocationDetails.revocationTime) log.status.Print('Revoked certificate [{}] at {}.'.format( certificate.name, times.FormatDateTime(revoke_time, tzinfo=times.LOCAL)))
def RewriteTerm(self, key, op, operand, key_type): """Rewrites <key op operand>. Args: key: The dotted resource name. op: The operator name. operand: The operand string value. key_type: The type of key, None if not known. Returns: A rewritten expression node or None if not supported server side. """ # TODO(b/77934881) compute API labels filter workaround if key.split('.')[0] == 'labels': # server side labels matching is currently problematic return None if isinstance(operand, list): # foo:(bar,baz) needs OR return None # Determine if the operand is matchable or a literal string. if not key_type: key_type = _GuessOperandType(operand) matchable = key_type is six.text_type # Convert time stamps to ISO RFC 3339 normal form. if key.endswith('Timestamp') or key.endswith('_timestamp'): try: operand = times.FormatDateTime(times.ParseDateTime(operand)) except (times.DateTimeSyntaxError, times.DateTimeValueError): pass else: matchable = False # Transform input field to List API field. if matchable and key.lower() in self._FIELD_MAPPING: key = self._FIELD_MAPPING[key] if operand.lower() in ('true', 'false'): operand = operand.lower() if op == ':': op = 'eq' if matchable: operand = ConvertHASPatternToFullMatch(operand) elif op in ('=', '!='): op = 'ne' if op.startswith('!') else 'eq' if matchable: operand = ConvertEQPatternToFullMatch(operand) elif op in ('~', '!~'): # All re match operands are strings. op = 'ne' if op.startswith('!') else 'eq' operand = ConvertREPatternToFullMatch(operand, wordmatch=key in ('region', 'zone')) else: return None return [key, ' ', op, ' ', operand]
def _ParseTimePredicate(self, after, before): """Return a predicate for filtering jobs by their creation time. Args: after: Only return true if the job was created after this time. before: Only return true if the job was created before this time. """ if after and (not before): self.preds.append(lambda x: times.ParseDateTime(x.createTime) > after) elif (not after) and before: self.preds.append(lambda x: times.ParseDateTime(x.createTime) <= before) elif after and before: def _Predicate(x): create_time = times.ParseDateTime(x.createTime) return after < create_time and create_time <= before self.preds.append(_Predicate)
def _SelectNewestCosImage(images): """Selects newest COS image from the list.""" cos_images = sorted([image for image in images if image.name.startswith(COS_MAJOR_RELEASE)], key=lambda x: times.ParseDateTime(x.creationTimestamp)) if not cos_images: raise NoCosImageException() return cos_images[-1].selfLink
def _SelectNewestGciImage(images): """Selects newest GCI image from the list.""" gci_images = sorted([image for image in images if image.name.startswith(GCI_MAJOR_RELEASE)], key=lambda x: times.ParseDateTime(x.creationTimestamp)) if not gci_images: raise NoGciImageException() return gci_images[-1].selfLink
def ParseExpireTime(expiration_value): """Parse flag value into Datetime format for expireTime.""" # expiration_value could be in Datetime format or Duration format. datetime = times.ParseDateTime(expiration_value) parsed_datetime = times.FormatDateTime(datetime, '%Y-%m-%dT%H:%M:%S.%6f%Ez', times.UTC) return parsed_datetime
def testChangedAfterNone(self): self._MockRequest(self.example_metrics, start_time=times.FormatDateTime( times.ParseDateTime('2100-01-01 00:00:00'))) self.Run( 'beta dataflow metrics list %s --changed-after="2100-01-01 00:00:00"' % self.job_id) self.AssertOutputEquals("""\ """)
def Parse(s): if not s: return None try: return times.ParseDateTime(s, '%Y-%m-%d').date() except times.Error as e: raise ArgumentTypeError( _GenerateErrorMessage(u'Failed to parse date: {0}'.format(unicode(e)), user_input=s))
def Parse(s): """Parses a string value into a Datetime object.""" if not s: return None try: return times.ParseDateTime(s) except times.Error as e: raise ArgumentTypeError( _GenerateErrorMessage(u'Failed to parse date/time: {0}'.format( unicode(e)), user_input=s))
def testChangedAfterAll(self): self._MockRequest(self.example_metrics, start_time=times.FormatDateTime( times.ParseDateTime('2000-01-01 00:00:00'))) self.Run( 'beta dataflow metrics list %s --changed-after="2000-01-01 00:00:00"' % self.job_id) self.AssertOutputEquals("""\ --- name: context: {} name: s5-ByteCount origin: dataflow/v1b3 scalar: 130194921.0 updateTime: '2015-01-15 12:31:07' --- name: context: {} name: s05-s5-finish-msecs origin: dataflow/v1b3 scalar: 0.0 updateTime: '2015-01-15 12:31:07' --- name: context: output_user_name: some/transform/Read-out0 name: ElementCount origin: dataflow/v1b3 scalar: 164656.0 updateTime: '2015-01-15 12:31:07' --- name: context: output_user_name: some/transform/Write-out0 name: MeanByteCount origin: dataflow/v1b3 scalar: 164656.0 updateTime: '2015-01-15 12:31:07' --- name: context: output_user_name: BigQueryIO.Read3-out0 name: ElementCount origin: dataflow/v1b3 scalar: 164656.0 updateTime: '2015-01-15 12:31:07' --- name: context: {} name: BigQueryIO.Read3-out0-MeanByteCount origin: dataflow/v1b3 scalar: 77.0 updateTime: '2015-01-15 12:31:07' """)
def Convert(self, string): """Converts a datetime value from string returns it.""" if not string: return None try: return times.ParseDateTime(string, tzinfo=self._tzinfo) except times.Error as e: raise exceptions.ParseError( self.GetPresentationName(), 'Failed to parse duration [{}]: {}.'.format( string, _SubException(e)))
def _ShouldInclude(logpoint, cutoff_time): """Determines if a logpoint should be included in the output. Args: logpoint: a Breakpoint object describing a logpoint. cutoff_time: The oldest finalTime to include for completed logpoints. Returns: True if the logpoint should be included based on the criteria in args. """ if not logpoint.isFinalState or not logpoint.finalTime: return True final_time = times.ParseDateTime(logpoint.finalTime, tzinfo=times.UTC) return final_time >= cutoff_time
def RecentlyModified(update_time): """Checks if the trigger with the given update_time was recently modified. Args: update_time: str, the time when the trigger was last modified. Returns: True if the trigger was recently modified and might not be ready for use. """ update_dt = times.ParseDateTime(update_time) max_duration = iso_duration.Duration(minutes=MAX_READY_LATENCY_MINUTES) ready_dt = times.GetDateTimePlusDuration(update_dt, max_duration) return times.Now() < ready_dt
def _ShouldInclude(snapshot, cutoff_time): """Determines if a snapshot should be included in the output. Args: snapshot: a Breakpoint message desciribing a snapshot. cutoff_time: The oldest finalTime to include for completed snapshots. Returns: True if the snapshot should be included based on the criteria in args. """ if not snapshot.isFinalState or not snapshot.finalTime: return True final_time = times.ParseDateTime(snapshot.finalTime, tzinfo=times.UTC) return final_time >= cutoff_time
def _RewriteTimes(self, key, op, operand): """Rewrites <*Time op operand>.""" try: dt = times.ParseDateTime(operand) except ValueError as e: raise ValueError( '{operand}: date-time value expected for {key}: {error}'. format(operand=operand, key=key, error=str(e))) dt_string = times.FormatDateTime(dt, '%Y-%m-%dT%H:%M:%S.%3f%Ez', times.UTC) return '{key}{op}{dt_string}'.format(key=key, op=op, dt_string=self.Quote(dt_string, always=True))
def Run(self, args): result = self.iam_client.projects_serviceAccounts_keys.List( self.messages.IamProjectsServiceAccountsKeysListRequest( name=iam_util.EmailToAccountResourceName(args.iam_account), keyTypes=iam_util.ManagedByFromString(args.managed_by))) keys = result.keys if args.created_before: ts = args.created_before keys = [ key for key in keys if times.ParseDateTime(key.validAfterTime) < ts ] return keys
def RewriteTerm(self, key, op, operand, key_type): """Rewrites <key op operand>. Args: key: The dotted resource name. op: The operator name. operand: The operand string value. key_type: The type of key, None if not known. Returns: A rewritten expression node or None if not supported server side. """ if isinstance(operand, list): # foo:(bar,baz) needs OR return None # Determine if the operand is matchable or a literal string. if not key_type: key_type = _GuessOperandType(operand) matchable = key_type is unicode # Convert time stamps to ISO RFC 3339 normal form. if key.endswith('Timestamp') or key.endswith('_timestamp'): try: operand = times.FormatDateTime(times.ParseDateTime(operand)) except (times.DateTimeSyntaxError, times.DateTimeValueError): pass else: matchable = False if operand.lower() in ('true', 'false'): operand = operand.lower() if op == ':': op = 'eq' if matchable: operand = ConvertHASPatternToFullMatch(operand) elif op in ('=', '!='): op = 'ne' if op.startswith('!') else 'eq' if matchable: operand = ConvertEQPatternToFullMatch(operand) elif op in ('~', '!~'): # All re match operands are strings. op = 'ne' if op.startswith('!') else 'eq' operand = ConvertREPatternToFullMatch(operand, wordmatch=key in ('region', 'zone')) else: return None return [key, ' ', op, ' ', operand]
def InitializeNormalization(self, value): """Checks the first non-empty resource value to see if it can be normalized. This method is called at most once on the first non-empty resource value. After that a new normalization method is set for the remainder of the resource values. Resource values are most likely well defined protobuf string encodings. The RE patterns match against those. Args: value: A resource value to normalize. Returns: The normalized value. """ self._normalize = lambda x: x # Check for datetime. Dates may have trailing timzone indicators. We don't # match them but ParseDateTime will handle them. if re.match(r'\d\d\d\d-\d\d-\d\d[ T]\d\d:\d\d:\d\d', value): try: value = times.ParseDateTime(value) # Make sure the value and operand times are both tz aware or tz naive. # Otherwise datetime comparisons will fail. tzinfo = times.LOCAL if value.tzinfo else None self._operand.Initialize( self._operand.list_value or self._operand.string_value, normalize=lambda x: times.ParseDateTime(x, tzinfo=tzinfo)) self._normalize = times.ParseDateTime except ValueError: pass # More type checks go here. return value
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 GetFilterUpperBound(self, now): """The log message filter which keeps out messages which are too new. Args: now: The current time, as a datetime object. Returns: The upper bound filter text that we should use. """ tzinfo = times.ParseDateTime(self.timestamp).tzinfo now = now.replace(tzinfo=tzinfo) upper_bound = now - datetime.timedelta(seconds=5) return 'timestamp<"{0}"'.format( times.FormatDateTime(upper_bound, '%Y-%m-%dT%H:%M:%S.%6f%Ez'))
def ParseExpireTime(s): """Return timedelta TTL for a cluster. Args: s: expireTime string timestamp in RFC3339 format. Returns: datetime.timedelta of time remaining before cluster expiration. Raises: TypeError, ValueError if time could not be parsed. """ if not s: return None expire_dt = times.ParseDateTime(s) if not expire_dt: return None return expire_dt - times.Now(expire_dt.tzinfo)
def SetUp(self): self.StartObjectPatch( times, 'Now', return_value=times.ParseDateTime('2016-05-26T00:05:00.000000Z')) self.mocked_cloudbuild_v1 = mock.Client( core_apis.GetClientClass('cloudbuild', 'v1')) self.mocked_cloudbuild_v1.Mock() self.addCleanup(self.mocked_cloudbuild_v1.Unmock) properties.VALUES.core.project.Set('my-project') self.cloudbuild_v1_messages = core_apis.GetMessagesModule( 'cloudbuild', 'v1') self._statuses = self.cloudbuild_v1_messages.Build.StatusValueValuesEnum