add instance information to webhooks (#577)

Fixes #574
This commit is contained in:
bmc-msft
2021-02-19 16:00:51 -05:00
committed by GitHub
parent 8ce4638b8a
commit 305c23a4d9
6 changed files with 60 additions and 9 deletions

View File

@ -15,6 +15,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
}, },
"event_id": "00000000-0000-0000-0000-000000000000", "event_id": "00000000-0000-0000-0000-000000000000",
"event_type": "ping", "event_type": "ping",
"instance_id": "00000000-0000-0000-0000-000000000000",
"instance_name": "example",
"webhook_id": "00000000-0000-0000-0000-000000000000" "webhook_id": "00000000-0000-0000-0000-000000000000"
} }
``` ```
@ -4016,6 +4018,15 @@ Each event will be submitted via HTTP POST to the user provided URL.
"event_type": { "event_type": {
"$ref": "#/definitions/EventType" "$ref": "#/definitions/EventType"
}, },
"instance_id": {
"format": "uuid",
"title": "Instance Id",
"type": "string"
},
"instance_name": {
"title": "Instance Name",
"type": "string"
},
"webhook_id": { "webhook_id": {
"format": "uuid", "format": "uuid",
"title": "Webhook Id", "title": "Webhook Id",
@ -4025,6 +4036,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"required": [ "required": [
"event_type", "event_type",
"event", "event",
"instance_id",
"instance_name",
"webhook_id" "webhook_id"
], ],
"title": "WebhookMessage", "title": "WebhookMessage",

View File

@ -10,6 +10,7 @@ from typing import Optional
from onefuzztypes.events import Event, EventMessage, get_event_type from onefuzztypes.events import Event, EventMessage, get_event_type
from .azure.creds import get_instance_id, get_instance_name
from .webhooks import Webhook from .webhooks import Webhook
EVENTS: Queue = Queue() EVENTS: Queue = Queue()
@ -35,6 +36,11 @@ def get_events() -> Optional[str]:
def send_event(event: Event) -> None: def send_event(event: Event) -> None:
event_type = get_event_type(event) event_type = get_event_type(event)
logging.info("sending event: %s - %s", event_type, event) logging.info("sending event: %s - %s", event_type, event)
event_message = EventMessage(event_type=event_type, event=event) event_message = EventMessage(
event_type=event_type,
event=event,
instance_id=get_instance_id(),
instance_name=get_instance_name(),
)
EVENTS.put(event_message) EVENTS.put(event_message)
Webhook.send_event(event_message) Webhook.send_event(event_message)

View File

@ -21,6 +21,7 @@ from onefuzztypes.webhooks import WebhookMessageLog as BASE_WEBHOOK_MESSAGE_LOG
from pydantic import BaseModel from pydantic import BaseModel
from .__version__ import __version__ from .__version__ import __version__
from .azure.creds import get_instance_id, get_instance_name
from .azure.queue import queue_object from .azure.queue import queue_object
from .azure.storage import StorageType from .azure.storage import StorageType
from .orm import ORMMixin from .orm import ORMMixin
@ -169,13 +170,22 @@ class Webhook(BASE_WEBHOOK, ORMMixin):
event_id=event_message.event_id, event_id=event_message.event_id,
event_type=event_message.event_type, event_type=event_message.event_type,
event=event_message.event, event=event_message.event,
instance_id=event_message.instance_id,
instance_name=event_message.instance_name,
) )
message.save() message.save()
message.queue_webhook() message.queue_webhook()
def ping(self) -> EventPing: def ping(self) -> EventPing:
ping = EventPing(ping_id=uuid4()) ping = EventPing(ping_id=uuid4())
self._add_event(EventMessage(event_type=EventType.ping, event=ping)) self._add_event(
EventMessage(
event_type=EventType.ping,
event=ping,
instance_id=get_instance_id(),
instance_name=get_instance_name(),
)
)
return ping return ping
def send(self, message_log: WebhookMessageLog) -> bool: def send(self, message_log: WebhookMessageLog) -> bool:
@ -213,7 +223,12 @@ def build_message(
) -> Tuple[bytes, Optional[str]]: ) -> Tuple[bytes, Optional[str]]:
data = ( data = (
WebhookMessage( WebhookMessage(
webhook_id=webhook_id, event_id=event_id, event_type=event_type, event=event webhook_id=webhook_id,
event_id=event_id,
event_type=event_type,
event=event,
instance_id=get_instance_id(),
instance_name=get_instance_name(),
) )
.json(sort_keys=True, exclude_none=True) .json(sort_keys=True, exclude_none=True)
.encode() .encode()

View File

@ -4,22 +4,32 @@
# Licensed under the MIT License. # Licensed under the MIT License.
import unittest import unittest
from unittest.mock import MagicMock, patch
from uuid import UUID from uuid import UUID
from onefuzztypes.events import EventPing, EventType from onefuzztypes.events import EventPing, EventType
from __app__.onefuzzlib.webhooks import build_message
class TestWebhookHmac(unittest.TestCase): class TestWebhookHmac(unittest.TestCase):
def test_webhook_hmac(self) -> None: @patch("__app__.onefuzzlib.webhooks.get_instance_id")
@patch("__app__.onefuzzlib.webhooks.get_instance_name")
def test_webhook_hmac(self, mock_name: MagicMock, mock_id: MagicMock) -> None:
mock_name.return_value = "example"
mock_id.return_value = UUID(int=3)
# late import to enable the patch to function
from __app__.onefuzzlib.webhooks import build_message
webhook_id = UUID(int=0) webhook_id = UUID(int=0)
event_id = UUID(int=1) event_id = UUID(int=1)
event_type = EventType.ping event_type = EventType.ping
event = EventPing(ping_id=UUID(int=2)) event = EventPing(ping_id=UUID(int=2))
data, digest = build_message( data, digest = build_message(
webhook_id=webhook_id, event_id=event_id, event_type=event_type, event=event webhook_id=webhook_id,
event_id=event_id,
event_type=event_type,
event=event,
) )
expected = ( expected = (
@ -27,16 +37,19 @@ class TestWebhookHmac(unittest.TestCase):
b'"event": {"ping_id": "00000000-0000-0000-0000-000000000002"}, ' b'"event": {"ping_id": "00000000-0000-0000-0000-000000000002"}, '
b'"event_id": "00000000-0000-0000-0000-000000000001", ' b'"event_id": "00000000-0000-0000-0000-000000000001", '
b'"event_type": "ping", ' b'"event_type": "ping", '
b'"instance_id": "00000000-0000-0000-0000-000000000003", '
b'"instance_name": "example", '
b'"webhook_id": "00000000-0000-0000-0000-000000000000"' b'"webhook_id": "00000000-0000-0000-0000-000000000000"'
b"}" b"}"
) )
expected_digest = ( expected_digest = (
"3502f83237ce006b7f6cfa40b89c0295009e3ccb0a1e62ce1d689700c2c6e698" "2f0610d708d9938dc053200cd2242b4cca4e9bb7227e5e662f28307f57c7fc9b"
"61c0de81e011495c2ca89fbf99485b841cee257bcfba326a3edc66f39dc1feec" "d1ffcab6fff9f409b3fb856db4f358be9078ec0b64874efac2b8f065211e2a14"
) )
print(repr(expected)) print(repr(expected))
print(repr(data))
self.assertEqual(data, expected) self.assertEqual(data, expected)
self.assertEqual(digest, None) self.assertEqual(digest, None)

View File

@ -216,6 +216,8 @@ def main():
event_id=UUID(int=0), event_id=UUID(int=0),
event_type=EventType.ping, event_type=EventType.ping,
event=EventPing(ping_id=UUID(int=0)), event=EventPing(ping_id=UUID(int=0)),
instance_id=UUID(int=0),
instance_name="example",
) )
layer( layer(

View File

@ -226,3 +226,5 @@ class EventMessage(BaseEvent):
event_id: UUID = Field(default_factory=uuid4) event_id: UUID = Field(default_factory=uuid4)
event_type: EventType event_type: EventType
event: Event event: Event
instance_id: UUID
instance_name: str