def _TimeCreatedToDateTime(time_created_ms): # Convert to float. timestamp = float(time_created_ms) # Round the timestamp to whole seconds. timestamp = round(timestamp / 1000) try: return times.GetDateTimeFromTimeStamp(timestamp) except (ArithmeticError, times.DateTimeValueError): # Values like -62135596800000 have been observed, causing underflows. return None
def testListTagsOutput(self): self._manifests = { _MakeSha('sha1'): { 'tag': ['tag1'], 'timeCreatedMs': _TIME_CREATED_MS }, _MakeSha('sha2'): { 'tag': ['tag2', 'tag3'], 'timeCreatedMs': _NEWER_TIME_CREATED_MS }, _MakeSha('sha3'): { 'tag': ['tag4'], 'timeCreatedMs': _UNDERFLOW_CREATED_MS } } self.ListTags() expected_time = times.FormatDateTime( times.GetDateTimeFromTimeStamp(_TIME_CREATED), '%Y-%m-%dT%H:%M:%S') newer_expected_time = times.FormatDateTime( times.GetDateTimeFromTimeStamp( _NEWER_TIME_CREATED), '%Y-%m-%dT%H:%M:%S') self.AssertOutputContains('DIGEST TAGS TIMESTAMP', normalize_space=True) self.AssertOutputContains( '{digest} {tags} {timestamp}'.format( digest='sha1', tags='tag1', timestamp=expected_time), normalize_space=True) self.AssertOutputContains( '{digest} {tags} {timestamp}'.format( digest='sha2', tags='tag2,tag3', timestamp=newer_expected_time), normalize_space=True) self.AssertOutputContains( '{digest} {tags}'.format(digest='sha3', tags='tag4'), normalize_space=True) # Verify descending order of the timestamps. self.assertLess( self.GetOutput().index('sha2'), self.GetOutput().index('sha1')) self.assertLess( self.GetOutput().index('sha1'), self.GetOutput().index('sha3'))
def formatTime(self, record, datefmt=None): return times.FormatDateTime(times.GetDateTimeFromTimeStamp( record.created), fmt=datefmt, tzinfo=times.UTC)
def TransformDate(r, format='%Y-%m-%dT%H:%M:%S', unit=1, undefined='', tz=None, tz_default=None): """Formats the resource as a strftime() format. Args: r: A timestamp number or an object with 3 or more of these fields: year, month, day, hour, minute, second, millisecond, microsecond, nanosecond. format: The strftime(3) format. unit: If the resource is a Timestamp then divide by _unit_ to yield seconds. undefined: Returns this value if the resource is not a valid time. tz: Return the time relative to the tz timezone if specified, the explicit timezone in the resource if it has one, otherwise the local timezone. For example, ...date(tz=EST5EDT, tz_default=UTC). tz_default: The default timezone if the resource does not have a timezone suffix. Returns: The strftime() date format for r or undefined if r does not contain a valid time. """ # Check if r has an isoformat() method. try: r = r.isoformat() except (AttributeError, TypeError, ValueError): pass tz_in = times.GetTimeZone(tz_default) if tz_default else None # Check if r is a timestamp. try: timestamp = float(r) / float(unit) dt = times.GetDateTimeFromTimeStamp(timestamp, tz_in) return times.FormatDateTime(dt, format) except (TypeError, ValueError): pass # Check if r is a serialized datetime object. original_repr = resource_property.Get(r, ['datetime'], None) if original_repr and isinstance(original_repr, basestring): r = original_repr tz_out = times.GetTimeZone(tz) if tz else None # Check if r is a date/time string. try: dt = times.ParseDateTime(r, tz_in) return times.FormatDateTime(dt, format, tz_out) except (AttributeError, ImportError, TypeError, ValueError): pass def _FormatFromParts(): """Returns the formatted time from broken down time parts in r. Raises: TypeError: For invalid time part errors. ValueError: For time conversion errors or not enough valid time parts. Returns: The formatted time from broken down time parts in r. """ valid = 0 parts = [] now = datetime.datetime.now(tz_in) for part in ('year', 'month', 'day', 'hour', 'minute', 'second'): value = resource_property.Get(r, [part], None) if value is None: # Missing parts default to now. value = getattr(now, part, 0) else: valid += 1 parts.append(int(value)) # The last value is microseconds. Add in any subsecond parts but don't count # them in the validity check. parts.append(0) for i, part in enumerate(['nanosecond', 'microsecond', 'millisecond']): value = resource_property.Get(r, [part], None) if value is not None: parts[-1] += int(int(value) * 1000**(i - 1)) # year&month&day or hour&minute&second would be OK, "3" covers those and any # combination of 3 non-subsecond date/time parts. if valid < 3: raise ValueError parts.append(tz_in) dt = datetime.datetime(*parts) return times.FormatDateTime(dt, format, tz_out) try: return _FormatFromParts() except (TypeError, ValueError): pass # Does anyone really know what time it is? return undefined
def _TimeCreatedToDateTime(time_created): timestamp = float(time_created) / 1000 # Drop the microsecond portion. timestamp = round(timestamp, 0) return times.GetDateTimeFromTimeStamp(timestamp)
def testListTagsOutput(self, track): resource_url1 = 'https://{repo}@{digest}'.format( repo=_IMAGE, digest=_MakeSha('sha1')) resource_url2 = 'https://{repo}@{digest}'.format( repo=_IMAGE, digest=_MakeSha('sha2')) resource_url3 = 'https://{repo}@{digest}'.format( repo=_IMAGE, digest=_MakeSha('sha3')) messages = apis.GetMessagesModule('containeranalysis', 'v1alpha1') self.fetch_occurrence_mock.return_value = { resource_url1: [ _BuildDetails('025192e7-6c4f-4352-96cf-f5dd7724105f', 'deadbeefbaadf00d'), _PackageVulnerability( messages.VulnerabilityDetails.SeverityValueValuesEnum.CRITICAL), _PackageVulnerability( messages.VulnerabilityDetails.SeverityValueValuesEnum.HIGH), _PackageVulnerability( messages.VulnerabilityDetails.SeverityValueValuesEnum.MEDIUM), _DerivedImage( 'https://gcr.io/google-appengine/debian@sha256:abcdefg', 20), _DerivedImage('https://gcr.io/google-appengine/base@sha256:0123345', 10), _DerivedImage('https://gcr.io/google-appengine/java@sha256:a1b2c3', 3), ], resource_url2: [ _BuildDetails('2076ecf0-e411-4828-843e-88ad3a97b897', 'baadf00ddeadbeef'), _PackageVulnerability( messages.VulnerabilityDetails.SeverityValueValuesEnum.HIGH), _PackageVulnerability( messages.VulnerabilityDetails.SeverityValueValuesEnum.HIGH), _DerivedImage( 'https://gcr.io/google-appengine/debian@sha256:abcdefg', 20), _DerivedImage( 'https://gcr.io/google-appengine/python@sha256:d5e6f7', 4), _DerivedImage('https://gcr.io/google-appengine/base@sha256:0123345', 10), ], resource_url3: [ _BuildDetails('2076ecf0-e411-4828-843e-88427a97b444', 'f000f000deadbeef'), _PackageVulnerability( messages.VulnerabilityDetails.SeverityValueValuesEnum.HIGH), _DerivedImage( 'https://gcr.io/google-appengine/base@sha256:deadf000', 10), ], } def _MockSummaryFunc(unused_repository, resource_url): # `prefix` a convenience var for shorter line length below. prefix = messages.SeverityCount.SeverityValueValuesEnum if resource_url == resource_url1: return messages.GetVulnzOccurrencesSummaryResponse( counts=[ messages.SeverityCount(count=1, severity=prefix.CRITICAL), messages.SeverityCount(count=1, severity=prefix.HIGH), messages.SeverityCount(count=1, severity=prefix.MEDIUM)]) elif resource_url == resource_url2: return messages.GetVulnzOccurrencesSummaryResponse( counts=[messages.SeverityCount(count=2, severity=prefix.HIGH)]) elif resource_url == resource_url3: return messages.GetVulnzOccurrencesSummaryResponse( counts=[messages.SeverityCount(count=1, severity=prefix.HIGH)]) self.fetch_summary_mock.side_effect = _MockSummaryFunc self._manifests = { _MakeSha('sha1'): { 'tag': ['tag1'], 'timeCreatedMs': _TIME_CREATED_MS }, _MakeSha('sha2'): { 'tag': ['tag2', 'tag3'], 'timeCreatedMs': _NEWER_TIME_CREATED_MS }, _MakeSha('sha3'): { 'tag': ['tag4'], 'timeCreatedMs': _UNDERFLOW_CREATED_MS } } self.ListTags(track) expected_time = times.FormatDateTime( times.GetDateTimeFromTimeStamp(_TIME_CREATED), '%Y-%m-%dT%H:%M:%S') newer_expected_time = times.FormatDateTime( times.GetDateTimeFromTimeStamp( _NEWER_TIME_CREATED), '%Y-%m-%dT%H:%M:%S') self.AssertOutputContains( 'DIGEST TAGS TIMESTAMP GIT_SHA VULNERABILITIES FROM BUILD', normalize_space=True) self.AssertOutputContains( '{digest} {tags} {timestamp} {sha1} {vulnz} {_from} {build}'.format( digest='sha1', tags='tag1', timestamp=expected_time, vulnz='CRITICAL=1,HIGH=1,MEDIUM=1', sha1='deadbeef', _from='gcr.io/google-appengine/java', build='025192e7-6c4f-4352-96cf-f5dd7724105f'), normalize_space=True) self.AssertOutputContains( '{digest} {tags} {timestamp} {sha1} {vulnz} {_from} {build}'.format( digest='sha2', tags='tag2,tag3', timestamp=newer_expected_time, vulnz='HIGH=2', sha1='baadf00d', _from='gcr.io/google-appengine/python', build='2076ecf0-e411-4828-843e-88ad3a97b897'), normalize_space=True) self.AssertOutputContains( '{digest} {tags} {sha1} {vulnz} {_from} {build}'.format( digest='sha3', tags='tag4', vulnz='HIGH=1', sha1='f000f000', _from='gcr.io/google-appengine/base', build='2076ecf0-e411-4828-843e-88427a97b444'), normalize_space=True) # Verify descending order of the timestamps. self.assertLess( self.GetOutput().index('sha2'), self.GetOutput().index('sha1')) self.assertLess( self.GetOutput().index('sha1'), self.GetOutput().index('sha3'))