diff --git a/continuous-operations.md b/continuous-operations.md index 9a2efedb..a0daae9e 100644 --- a/continuous-operations.md +++ b/continuous-operations.md @@ -8,32 +8,54 @@ description: > --> # Continuous Operations Events -Continuous Operations events are related to the operation of services deployed in target environments, tracking of incidents and their resolution. Incidents, and their resolution, can be detected by a number of different actors, like the end-user, a quality gate, a monitoring system, an SRE through a ticketing system or even the service itself. +Continuous Operations events are related to the operation of services deployed in target environments. ## Subjects -This specification defines one subject in this stage, the [`incident`](#incident). To quote the definition of the term from the NIST glossary, and [incident][] is: - -> An occurrence that actually or potentially jeopardizes the confidentiality, integrity, or availability of an information system or the information the system processes, stores, or transmits or that constitutes a violation or imminent threat of violation of security policies, security procedures, or acceptable use policies. +This specification defines two subjects in this stage: [`incident`](#incident) and [`ticket`](#ticket). Events associated to these subjects can be generated by a number of different actors, such as the end-user, an SRE, a quality gate, a monitoring system, or the service itself. | Subject | Description | Predicates | |---------|-------------|------------| -| [`incident`](#incident) | A problem in a production environment | [`detected`](#incident-detected), [`reported`](#incident-reported), [`resolved`](#incident-resolved)| +| [`incident`](#incident) | A problem in a production environment | [`detected`](#incident-detected), [`reported`](#incident-reported), [`resolved`](#incident-resolved) | +| [`ticket`](#ticket) | A ticket in a ticketing system | [`created`](#ticket-created), [`updated`](#ticket-updated), [`closed`](#ticket-closed) | ### `incident` -An `incident` represents a problem in a production environment. +An `incident` represents a problem in a production environment. To quote the definition of the term from the NIST glossary, an [incident][] is: + +> An occurrence that actually or potentially jeopardizes the confidentiality, integrity, or availability of an information system or the information the system processes, stores, or transmits or that constitutes a violation or imminent threat of violation of security policies, security procedures, or acceptable use policies. | Field | Type | Description | Examples | |-------|------|-------------|----------| | id | `String` | See [id](spec.md#id-subject)| `04896C75-F34D-40FF-A584-3F2B71CB9D47`, `issue123`, `risk-CVE123` | -| source | `URI-Reference` | See [source](spec.md#source-subject) | `region1/production`, `monitoring-system/metricA`| +| source | `URI-Reference` | See [source](spec.md#source-subject) | `region1/production`, `monitoring-system/metricA` | | type | `String` | See [type](spec.md#type-subject) | `incident` | -| description | `String` | Short, free style description of the incident | "Response time above 10ms", "New CVE-123 detected" | +| description | `String` | Short, free style description of the incident | `Response time above 10ms`, `New CVE-123 detected` | | environment | `Object` ([`environment`](./continuous-deployment.md#environment)) | Reference to the environment | `{"id": "production"}`, `{"id": "staging"}`, `{"id": "prod123", "source": "iaas-region-1"}` | | service | `Object` ([`service`](./continuous-deployment.md#service)) | Reference to the service | `{"id": "service123"}`, `{"id": "service123", "source": "region1/k8s/namespace"}` | | artifactId | `Purl` | Identifier of the artifact deployed with this service | `0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427`, `927aa808433d17e315a258b98e2f1a55f8258e0cb782ccb76280646d0dbe17b5`, `six-1.14.0-py2.py3-none-any.whl` | +### `ticket` + +A ticket can request a change, report a problem, or document an [`incident`](#incident). + +| Field | Type | Description | Examples | +|-------|------|-------------|----------| +| id | `String` | See [id](spec.md#id-subject)| `04896C75-F34D-40FF-A584-3F2B71CB9D47`, `issue123`, `risk-CVE123` | +| source | `URI-Reference` | See [source](spec.md#source-subject) | `ticketing-system` | +| type | `String` | See [type](spec.md#type-subject) | `ticket` | +| summary | `String` | The summary provided on the ticket | `Implement feature xyz`, `New CVE-123 detected` | +| ticketType | `String (enum)` | The ticket type | `bug`, `enhancement`, `custom` | +| group | `String` | The group or project the ticket is currently assigned to | `backend` | +| creator | `String` | The ticket author | `Alice` | +| assignee | `String` | Who is currently investigating the ticket | `Bob` | +| priority | `String (enum)` | An indicator of the importance of the ticket | `high`, `medium`, `low`, `custom` | +| labels | `Array (string)` | Labels associated to the ticket | `[productxyz, bug]` | +| milestone | `String` | An ID that represents a goal for when this ticket is to be completed | `123`, `sprint-123`, `Q1` | +| changed | `Object (list)` | An object representing the changes to the ticket | `[{"field": "labels", "from": "", "to": "bug"}]` | +| resolution | `String (enum)` | Indicates the closing status of the ticket | `completed`, `withdrawn` | +| author | `String` | The person who authored the updates | `Bob` | + ## Events ### [`incident detected`](examples/incident_detected.json) @@ -49,7 +71,7 @@ This event represents an incident that has been detected by a system or human. | id | `String` | See [id](spec.md#id-subject)| `04896C75-F34D-40FF-A584-3F2B71CB9D47`, `issue123`, `risk-CVE123` | ✅ | | source | `URI-Reference` | See [source](spec.md#source-subject) | `region1/production`, `monitoring-system/metricA`| | | type | `String` | See [type](spec.md#type-subject) | `incident` | | -| description | `String` | Short, free style description of the incident | "Response time above 10ms", "New CVE-123 detected" | | +| description | `String` | Short, free style description of the incident | `Response time above 10ms`, `New CVE-123 detected` | | | environment | `Object` ([`environment`](./continuous-deployment.md#environment)) | Reference to the environment | `{"id": "production"}`, `{"id": "staging"}`, `{"id": "prod123", "source": "iaas-region-1"}` | ✅ | | service | `Object` ([`service`](./continuous-deployment.md#service)) | Reference to the service | `{"id": "service123"}`, `{"id": "service123", "source": "region1/k8s/namespace"}` | | | artifactId | `Purl` | Identifier of the artifact deployed with this service | `0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427`, `927aa808433d17e315a258b98e2f1a55f8258e0cb782ccb76280646d0dbe17b5`, `six-1.14.0-py2.py3-none-any.whl` | | @@ -67,7 +89,7 @@ This event represents an incident that has been reported through a ticketing sys | id | `String` | See [id](spec.md#id-subject)| `04896C75-F34D-40FF-A584-3F2B71CB9D47`, `issue123`, `risk-CVE123` | ✅ | | source | `URI-Reference` | See [source](spec.md#source-subject) | `region1/production`, `monitoring-system/metricA`| | | type | `String` | See [type](spec.md#type-subject) | `incident` | | -| description | `String` | Short, free style description of the incident | "Response time above 10ms", "New CVE-123 detected" | | +| description | `String` | Short, free style description of the incident | `Response time above 10ms`, `New CVE-123 detected` | | | environment | `Object` ([`environment`](./continuous-deployment.md#environment)) | Reference to the environment | `{"id": "production"}`, `{"id": "staging"}`, `{"id": "prod123", "source": "iaas-region-1"}` | ✅ | | ticketURI | `URI` | URI of the ticket | `example.issues.com/ticket123` | ✅ | | service | `Object` ([`service`](./continuous-deployment.md#service)) | Reference to the service | `{"id": "service123"}`, `{"id": "service123", "source": "region1/k8s/namespace"}` | | @@ -86,9 +108,63 @@ This event represents an incident that has been resolved, meaning that the probl | id | `String` | See [id](spec.md#id-subject)| `04896C75-F34D-40FF-A584-3F2B71CB9D47`, `issue123`, `risk-CVE123` | ✅ | | source | `URI-Reference` | See [source](spec.md#source-subject) | `region1/production`, `monitoring-system/metricA`| | | type | `String` | See [type](spec.md#type-subject) | `incident` | | -| description | `String` | Short, free style description of the incident resolution | "Response time restored below 10ms", "CVE-123 acknowledged as non-exploitable" | | +| description | `String` | Short, free style description of the incident resolution | `Response time restored below 10ms`, `CVE-123 acknowledged as non-exploitable` | | | environment | `Object` ([`environment`](./continuous-deployment.md#environment)) | Reference to the environment | `{"id": "production"}`, `{"id": "staging"}`, `{"id": "prod123", "source": "iaas-region-1"}` | ✅ | | service | `Object` ([`service`](./continuous-deployment.md#service)) | Reference to the service | `{"id": "service123"}`, `{"id": "service123", "source": "region1/k8s/namespace"}` | | | artifactId | `Purl` | Identifier of the artifact deployed with this service | `0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427`, `927aa808433d17e315a258b98e2f1a55f8258e0cb782ccb76280646d0dbe17b5`, `six-1.14.0-py2.py3-none-any.whl` | | +### [`ticket created`](examples/ticket_created.json) + +This event represents a ticket that has been created within some ticketing system. + +- Event Type: __`dev.cdevents.ticket.created.0.1.0-draft`__ +- Predicate: created +- Subject: [`ticket`](#ticket) + +| Field | Type | Description | Examples | Mandatory ✅ | +| ------|----- | ----------- | ---------| ------------ | +| id | `String`| See [id](spec.md#id-subject) | `ticket-123` | ✅ | +| source | `URI-Reference` | See [source](spec.md#source-subject) | `ticketing-system` | | +| type | `String` | See [type](spec.md#type-subject) | `ticket` | | +| summary | `String` | The summary provided on the ticket | `Implement feature xyz`, `New CVE-123 detected` | ✅ | +| ticketType | `String (enum)` | The ticket type | `bug`, `enhancement`, `custom` | | +| group | `String` | The group the ticket is currently assigned to | `backend` | | +| creator | `String` | The ticket author | `Alice` | ✅ | +| assignee | `String` | Who is currently investigating the ticket | `Bob` | | +| priority | `String (enum)` | An indicator of the importance of the ticket | `high`, `medium`, `low`, `custom` | | +| labels | `String (list)` | Labels associated to the ticket | `productxyz, bug` | | +| milestone | `String` | An ID that represents a goal for when this ticket is to be completed | `123`, `sprint-123`, `Q1` | | + +### [`ticket updated`](examples/ticket_updated.json) + +This event represents a ticket that has been created within some ticketing system. + +- Event Type: __`dev.cdevents.ticket.updated.0.1.0-draft`__ +- Predicate: updated +- Subject: [`ticket`](#ticket) + +| Field | Type | Description | Examples | Mandatory ✅ | +| ------|----- | ----------- | ---------| ------------ | +| id | `String`| See [id](spec.md#id-subject) | `ticket-123` | ✅ | +| source | `URI-Reference` | See [source](spec.md#source-subject) | `ticketing-system` | | +| type | `String` | See [type](spec.md#type-subject) | `ticket` | | +| changed | `Object (list)` | An object representing the changes to the ticket | `[{"field": "labels", "from": "", "to": "bug"}]` | ✅ | +| author | `String` | The person who authored the updates | `Bob` | ✅ | + +### [`ticket closed`](examples/ticket_closed.json) + +This event represents a ticket that has been created within some ticketing system. + +- Event Type: __`dev.cdevents.ticket.closed.0.1.0-draft`__ +- Predicate: closed +- Subject: [`ticket`](#ticket) + +| Field | Type | Description | Examples | Mandatory ✅ | +| ------|----- | ----------- | ---------| ------------ | +| id | `String`| See [id](spec.md#id-subject) | `ticket-123` | ✅ | +| source | `URI-Reference` | See [source](spec.md#source-subject) | `ticketing-system` | | +| type | `String` | See [type](spec.md#type-subject) | `ticket` | | +| resolution | `String (enum)` | Indicates the closing status of the ticket | `completed`, `withdrawn` | ✅ | +| author | `String` | The person who authored the updates | `Bob` | ✅ | + [incident]: https://csrc.nist.gov/glossary/term/incident diff --git a/examples/ticket_closed.json b/examples/ticket_closed.json new file mode 100644 index 00000000..b2583c66 --- /dev/null +++ b/examples/ticket_closed.json @@ -0,0 +1,18 @@ +{ + "context": { + "version": "0.4.0-draft", + "id": "F4BD2B55-B6F6-4F44-AF72-BD2D0E7A8708", + "source": "/ticketing/system", + "type": "dev.cdevents.ticket.closed.0.1.0", + "timestamp": "2022-11-11T13:52:20.079Z" + }, + "subject": { + "id": "ticket-123", + "source": "/ticketing/system", + "type": "ticket", + "content": { + "resolution": "completed", + "author": "Bob" + } + } +} diff --git a/examples/ticket_created.json b/examples/ticket_created.json new file mode 100644 index 00000000..d7f7d672 --- /dev/null +++ b/examples/ticket_created.json @@ -0,0 +1,24 @@ +{ + "context": { + "version": "0.4.0-draft", + "id": "F4BD2B55-B6F6-4F44-AF72-BD2D0E7A8708", + "source": "/ticketing/system", + "type": "dev.cdevents.ticket.created.0.1.0", + "timestamp": "2022-11-11T13:52:20.079Z" + }, + "subject": { + "id": "ticket-123", + "source": "/ticketing/system", + "type": "ticket", + "content": { + "summary": "New CVE-123 detected", + "ticketType": "task", + "group": "backend", + "creator": "Alice", + "assignee": "Bob", + "priority": "high", + "labels": ["cve"], + "milestone": "123" + } + } +} diff --git a/examples/ticket_updated.json b/examples/ticket_updated.json new file mode 100644 index 00000000..82266f3e --- /dev/null +++ b/examples/ticket_updated.json @@ -0,0 +1,24 @@ +{ + "context": { + "version": "0.4.0-draft", + "id": "F4BD2B55-B6F6-4F44-AF72-BD2D0E7A8708", + "source": "/ticketing/system", + "type": "dev.cdevents.ticket.updated.0.1.0", + "timestamp": "2022-11-11T13:52:20.079Z" + }, + "subject": { + "id": "ticket-123", + "source": "/ticketing/system", + "type": "ticket", + "content": { + "changed": [ + { + "field": "labels", + "from": "", + "to": "bug" + } + ], + "author": "Bob" + } + } +} diff --git a/schemas/ticketclosed.json b/schemas/ticketclosed.json new file mode 100644 index 00000000..5dddd402 --- /dev/null +++ b/schemas/ticketclosed.json @@ -0,0 +1,113 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cdevents.dev/0.4.0-draft/schema/ticket-closed-event", + "properties": { + "context": { + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "enum": [ + "dev.cdevents.ticket.closed.0.1.0" + ], + "default": "dev.cdevents.ticket.closed.0.1.0" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "version", + "id", + "source", + "type", + "timestamp" + ] + }, + "subject": { + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "minLength": 1, + "enum": [ + "ticket" + ], + "default": "ticket" + }, + "content": { + "properties": { + "resolution": { + "type": "string", + "enum": [ + "completed", + "withdrawn", + "duplicate", + "wontdo" + ] + }, + "author": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "resolution", + "author" + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "type", + "content" + ] + }, + "customData": { + "oneOf": [ + { + "type": "object" + }, + { + "type": "string", + "contentEncoding": "base64" + } + ] + }, + "customDataContentType": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "context", + "subject" + ] +} diff --git a/schemas/ticketcreated.json b/schemas/ticketcreated.json new file mode 100644 index 00000000..4e108cd1 --- /dev/null +++ b/schemas/ticketcreated.json @@ -0,0 +1,141 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cdevents.dev/0.4.0-draft/schema/ticket-created-event", + "properties": { + "context": { + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "enum": [ + "dev.cdevents.ticket.created.0.1.0" + ], + "default": "dev.cdevents.ticket.created.0.1.0" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "version", + "id", + "source", + "type", + "timestamp" + ] + }, + "subject": { + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "minLength": 1, + "enum": [ + "ticket" + ], + "default": "ticket" + }, + "content": { + "properties": { + "summary": { + "type": "string" + }, + "ticketType": { + "type": "string", + "enum": [ + "bug", + "enhancement", + "incident", + "task", + "question" + ] + }, + "group": { + "type": "string" + }, + "creator": { + "type": "string", + "minLength": 1 + }, + "assignee": { + "type": "string" + }, + "priority": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ] + }, + "labels": { + "type": "array", + "items": { + "type": "string" + } + }, + "milestone": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "summary", + "creator" + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "type", + "content" + ] + }, + "customData": { + "oneOf": [ + { + "type": "object" + }, + { + "type": "string", + "contentEncoding": "base64" + } + ] + }, + "customDataContentType": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "context", + "subject" + ] +} diff --git a/schemas/ticketupdated.json b/schemas/ticketupdated.json new file mode 100644 index 00000000..8e7e6dac --- /dev/null +++ b/schemas/ticketupdated.json @@ -0,0 +1,128 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cdevents.dev/0.4.0-draft/schema/ticket-updated-event", + "properties": { + "context": { + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "enum": [ + "dev.cdevents.ticket.updated.0.1.0" + ], + "default": "dev.cdevents.ticket.updated.0.1.0" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "version", + "id", + "source", + "type", + "timestamp" + ] + }, + "subject": { + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "minLength": 1, + "enum": [ + "ticket" + ], + "default": "ticket" + }, + "content": { + "properties": { + "changed": { + "type": "array", + "items": { + "properties": { + "field": { + "type": "string", + "minLength": 1 + }, + "from": { + "type": "string" + }, + "to": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "field", + "from", + "to" + ] + } + }, + "author": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "changed", + "author" + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "type", + "content" + ] + }, + "customData": { + "oneOf": [ + { + "type": "object" + }, + { + "type": "string", + "contentEncoding": "base64" + } + ] + }, + "customDataContentType": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "context", + "subject" + ] +}