mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-12 10:08:09 +00:00
add Timestamp to multiple models (#796)
Expose the Azure storage table's "Timestamp" for the models where Timestamp should be user-accessible and remove the Timestamp field from models that did not sign up for it. The behavior where Timestamp is only set by Azure Storage is kept.
This commit is contained in:
@ -37,7 +37,7 @@ from onefuzztypes.enums import (
|
|||||||
)
|
)
|
||||||
from onefuzztypes.models import Error, SecretData
|
from onefuzztypes.models import Error, SecretData
|
||||||
from onefuzztypes.primitives import Container, PoolName, Region
|
from onefuzztypes.primitives import Container, PoolName, Region
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel
|
||||||
from typing_extensions import Protocol
|
from typing_extensions import Protocol
|
||||||
|
|
||||||
from .azure.table import get_client
|
from .azure.table import get_client
|
||||||
@ -219,8 +219,9 @@ class ModelMixin(BaseModel):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: if you want to include Timestamp in a model that uses ORMMixin,
|
||||||
|
# it must be maintained as part of the model.
|
||||||
class ORMMixin(ModelMixin):
|
class ORMMixin(ModelMixin):
|
||||||
Timestamp: Optional[datetime] = Field(alias="Timestamp")
|
|
||||||
etag: Optional[str]
|
etag: Optional[str]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -257,7 +258,7 @@ class ORMMixin(ModelMixin):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def export_exclude(self) -> Optional[MappingIntStrAny]:
|
def export_exclude(self) -> Optional[MappingIntStrAny]:
|
||||||
return {"etag": ..., "Timestamp": ...}
|
return {"etag": ...}
|
||||||
|
|
||||||
def telemetry_include(self) -> Optional[MappingIntStrAny]:
|
def telemetry_include(self) -> Optional[MappingIntStrAny]:
|
||||||
return {}
|
return {}
|
||||||
|
@ -42,6 +42,7 @@ PROXY_LOG_PREFIX = "scaleset-proxy: "
|
|||||||
# This isn't intended to ever be shared to the client, hence not being in
|
# This isn't intended to ever be shared to the client, hence not being in
|
||||||
# onefuzztypes
|
# onefuzztypes
|
||||||
class Proxy(ORMMixin):
|
class Proxy(ORMMixin):
|
||||||
|
timestamp: Optional[datetime.datetime] = Field(alias="Timestamp")
|
||||||
region: Region
|
region: Region
|
||||||
state: VmState = Field(default=VmState.init)
|
state: VmState = Field(default=VmState.init)
|
||||||
auth: Authentication = Field(default_factory=build_auth)
|
auth: Authentication = Field(default_factory=build_auth)
|
||||||
@ -179,12 +180,12 @@ class Proxy(ORMMixin):
|
|||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
elif not self.heartbeat and self.Timestamp and self.Timestamp < ten_minutes_ago:
|
elif not self.heartbeat and self.timestamp and self.timestamp < ten_minutes_ago:
|
||||||
logging.error(
|
logging.error(
|
||||||
PROXY_LOG_PREFIX + "no heartbeat in the last 10 minutes: "
|
PROXY_LOG_PREFIX + "no heartbeat in the last 10 minutes: "
|
||||||
"%s timestamp: %s compared_to:%s",
|
"%s timestamp: %s compared_to:%s",
|
||||||
self.region,
|
self.region,
|
||||||
self.Timestamp,
|
self.timestamp,
|
||||||
ten_minutes_ago,
|
ten_minutes_ago,
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -17,12 +17,12 @@ class TaskEvent(BASE_TASK_EVENT, ORMMixin):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_summary(cls, task_id: UUID) -> List[TaskEventSummary]:
|
def get_summary(cls, task_id: UUID) -> List[TaskEventSummary]:
|
||||||
events = cls.search(query={"task_id": [task_id]})
|
events = cls.search(query={"task_id": [task_id]})
|
||||||
# handle None case of Optional[e.Timestamp], which shouldn't happen
|
# handle None case of Optional[e.timestamp], which shouldn't happen
|
||||||
events.sort(key=lambda e: e.Timestamp or datetime.datetime.max)
|
events.sort(key=lambda e: e.timestamp or datetime.datetime.max)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
TaskEventSummary(
|
TaskEventSummary(
|
||||||
timestamp=e.Timestamp,
|
timestamp=e.timestamp,
|
||||||
event_data=get_event_data(e.event_data),
|
event_data=get_event_data(e.event_data),
|
||||||
event_type=get_event_type(e.event_data),
|
event_type=get_event_type(e.event_data),
|
||||||
)
|
)
|
||||||
|
@ -535,6 +535,7 @@ class JobTaskInfo(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Job(BaseModel):
|
class Job(BaseModel):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
job_id: UUID = Field(default_factory=uuid4)
|
job_id: UUID = Field(default_factory=uuid4)
|
||||||
state: JobState = Field(default=JobState.init)
|
state: JobState = Field(default=JobState.init)
|
||||||
config: JobConfig
|
config: JobConfig
|
||||||
@ -557,6 +558,7 @@ class NodeHeartbeatEntry(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Node(BaseModel):
|
class Node(BaseModel):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
pool_name: PoolName
|
pool_name: PoolName
|
||||||
machine_id: UUID
|
machine_id: UUID
|
||||||
state: NodeState = Field(default=NodeState.init)
|
state: NodeState = Field(default=NodeState.init)
|
||||||
@ -620,6 +622,7 @@ class AutoScaleConfig(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Pool(BaseModel):
|
class Pool(BaseModel):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
name: PoolName
|
name: PoolName
|
||||||
pool_id: UUID = Field(default_factory=uuid4)
|
pool_id: UUID = Field(default_factory=uuid4)
|
||||||
os: OS
|
os: OS
|
||||||
@ -647,6 +650,7 @@ class ScalesetNodeState(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Scaleset(BaseModel):
|
class Scaleset(BaseModel):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
pool_name: PoolName
|
pool_name: PoolName
|
||||||
scaleset_id: UUID = Field(default_factory=uuid4)
|
scaleset_id: UUID = Field(default_factory=uuid4)
|
||||||
state: ScalesetState = Field(default=ScalesetState.init)
|
state: ScalesetState = Field(default=ScalesetState.init)
|
||||||
@ -676,6 +680,7 @@ class NotificationConfig(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Repro(BaseModel):
|
class Repro(BaseModel):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
vm_id: UUID = Field(default_factory=uuid4)
|
vm_id: UUID = Field(default_factory=uuid4)
|
||||||
task_id: UUID
|
task_id: UUID
|
||||||
config: ReproConfig
|
config: ReproConfig
|
||||||
@ -795,6 +800,7 @@ class NodeCommandEnvelope(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class TaskEvent(BaseModel):
|
class TaskEvent(BaseModel):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
task_id: UUID
|
task_id: UUID
|
||||||
machine_id: UUID
|
machine_id: UUID
|
||||||
event_data: WorkerEvent
|
event_data: WorkerEvent
|
||||||
@ -813,6 +819,7 @@ class NodeAssignment(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Task(BaseModel):
|
class Task(BaseModel):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
job_id: UUID
|
job_id: UUID
|
||||||
task_id: UUID = Field(default_factory=uuid4)
|
task_id: UUID = Field(default_factory=uuid4)
|
||||||
state: TaskState = Field(default=TaskState.init)
|
state: TaskState = Field(default=TaskState.init)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
# Copyright (c) Microsoft Corporation.
|
# Copyright (c) Microsoft Corporation.
|
||||||
# Licensed under the MIT License.
|
# Licensed under the MIT License.
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ class WebhookMessage(EventMessage):
|
|||||||
|
|
||||||
|
|
||||||
class WebhookMessageLog(WebhookMessage):
|
class WebhookMessageLog(WebhookMessage):
|
||||||
|
timestamp: Optional[datetime] = Field(alias="Timestamp")
|
||||||
state: WebhookMessageState = Field(default=WebhookMessageState.queued)
|
state: WebhookMessageState = Field(default=WebhookMessageState.queued)
|
||||||
try_count: int = Field(default=0)
|
try_count: int = Field(default=0)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user