Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ classes:
See the [Configuration](#configuration-attributes) section below.
range: Configuration
rank: 60
slots:
- x-placeholder-extensions

Metadata:
description: Metadata about the application.
Expand Down Expand Up @@ -225,6 +227,7 @@ classes:
slots:
- type
- components
- x-placeholder-extensions

RequiredResources:
description: >-
Expand Down Expand Up @@ -375,6 +378,8 @@ classes:
range: ComponentProperties
required: true
rank: 20
slots:
- x-placeholder-extensions

HelmComponent:
is_a: Component
Expand Down Expand Up @@ -715,6 +720,17 @@ slots:
inlined_as_list: true
rank: 20

x-placeholder-extensions:
description: >-
Allows addition of arbitrary object (mapping) whose contents
suppliers use to provide vendor-specific functionality beyond what is defined in
the Margo specification. See the [Specification Extensions](#specification-extensions) section below for more details.
required: false
multivalued: true
inlined: true
inlined_as_list: false
rank: 999

enums:
CpuArchitectureType:
permissible_values:
Expand Down
50 changes: 44 additions & 6 deletions src/specification/applications/resources/index.md.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ which defines the [desired state](../margo-management-interface/desired-state.md
{%- else -%}
{%- if slot.name == "properties" -%}
map[string][string]
{%- elif slot.name == "x-placeholder-extensions" -%}
map[string]interface{}
{%- else -%}
map[string][{{ slot.range }}]
{%- endif -%}
Expand All @@ -31,11 +33,18 @@ which defines the [desired state](../margo-management-interface/desired-state.md
{%- endif -%}
{%- endmacro -%}

{%- macro display_slot_name(slot_name) -%}
{%- if slot_name == "x-placeholder-extensions" -%}
x-<unique-name>-extensions
{%- else -%}
{{ slot_name }}
{%- endif -%}
{%- endmacro -%}

| Attribute | Type | Required? | Description |
| --- | --- | --- | --- |
{% for slot in schemaview.class_slots("ApplicationDescription")|sort(attribute='rank') -%}
{% set slot_def = schemaview.induced_slot(slot, "ApplicationDescription") -%}
| {{ slot }} | {{ format_range(slot_def) }} | {% if slot_def.required == True %} Y {% else %} N {% endif %} | {{ slot_def.description }}|
{% for slot_def in schemaview.class_induced_slots("ApplicationDescription")|sort(attribute='rank') -%}
| {{ display_slot_name(slot_def.name) }} | {{ format_range(slot_def) }} | {% if slot_def.required == True %} Y {% else %} N {% endif %} | {{ slot_def.description }}|
{% endfor -%}

{% for c in gen.all_class_objects()|sort(attribute='rank') %}
Expand All @@ -60,9 +69,9 @@ which defines the [desired state](../margo-management-interface/desired-state.md
{%- for slot in gen.get_direct_slots(c)|sort(attribute='rank') %}
{%- if c.name == "Parameter" and slot.name == "name" %}
{%- elif slot.name != "value" %}
| {{ slot.name }} | {{ format_range(slot) }} | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}|
| {{ display_slot_name(slot.name) }} | {{ format_range(slot) }} | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}|
{%- else %}
| {{ slot.name }} | <*see description*> | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}|
| {{ display_slot_name(slot.name) }} | <*see description*> | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}|
{%- endif %}
{%- endfor %}

Expand Down Expand Up @@ -170,4 +179,33 @@ An example of an `ApplicationDescription` defining [deployment profiles](#deploy

```yaml
{% include 'examples/valid/ApplicationDescription-002.yaml' %}
```
```

## Specification extensions

> **Note:** See the [specification extensions](../margo-management-interface/specification-extensions.md) page for additional details.

The Application Description document supports the following specification extension scenarios:

### Collaboration between application and workload fleet manager suppliers

To make use of specification extensions defined by a workload fleet manager supplier, the extension property MUST be added to the Application Description yaml document's [root](#top-level-attributes).

The workload fleet manager MUST ignore any unknown specification extensions targeting a workload fleet manager supplier. Importing an application description with unknown specification extensions MUST NOT result in a failure because of the included specification extensions.

The workload fleet manager MUST NOT propagate these specification extension properties to the device via the [Application Deployment yaml](../margo-management-interface/desired-state#specification-extensions) document.


### Collaboration between application and device suppliers

To make use of specification extensions defined by a device supplier, the extension property MUST be added to the root of either the [deploymentProfile](#deploymentprofile-attributes) or [component](#component-attributes) objects.

The workload fleet manager MUST import an application description with specification extensions targeting a device supplier without resulting in a failure because of the included specification extensions.

The workload fleet manager MUST propagate these extension properties to the device via the [Application Deployment yaml](../margo-management-interface/desired-state#specification-extensions) document.






Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ classes:
inlined: true
inlined_as_list: false
rank: 20
slots:
- x-placeholder-extensions

DeploymentProfile:
description: A class representing a deployment profile.
Expand All @@ -113,6 +115,7 @@ classes:
slots:
- type
- components
- x-placeholder-extensions

HelmDeploymentProfile:
is_a: DeploymentProfile
Expand Down Expand Up @@ -154,6 +157,8 @@ classes:
inlined: true
inlined_as_list: false
rank: 20
slots:
- x-placeholder-extensions

HelmComponent:
is_a: Component
Expand Down Expand Up @@ -221,3 +226,14 @@ slots:
multivalued: true
required: true
rank: 20

x-placeholder-extensions:
description: >-
Allows addition of an arbitrary object (mapping)
whose contents suppliers use to provide vendor-specific functionality beyond what is defined in
the Margo specification. See the [Specification Extensions](#specification-extensions) section below for more details.
required: false
multivalued: true
inlined: true
inlined_as_list: false
rank: 999
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ spec:
{%- else -%}
{%- if slot.name == "properties" -%}
map[string][string]
{%- elif slot.name == "x-placeholder-extensions" -%}
map[string]interface{}
{%- else -%}
map[string][{{ slot.range }}]
{%- endif -%}
Expand All @@ -311,10 +313,18 @@ spec:
{%- endif -%}
{%- endmacro -%}

{%- macro display_slot_name(slot_name) -%}
{%- if slot_name == "x-placeholder-extensions" -%}
x-&lt;unique-name&gt;-extensions
{%- else -%}
{{ slot_name }}
{%- endif -%}
{%- endmacro -%}

| Attribute | Type | Required? | Description |
| --- | --- | --- | --- |
{% for slot in schemaview.class_slots("DesiredState")|sort(attribute='rank') -%}
| {{ slot }} | {{ schemaview.get_slot(slot).range }} | {% if schemaview.get_slot(slot).required == True %} Y {% else %} N {% endif %} | {{ schemaview.get_slot(slot).description }}|
| {{ display_slot_name(slot) }} | {{ schemaview.get_slot(slot).range }} | {% if schemaview.get_slot(slot).required == True %} Y {% else %} N {% endif %} | {{ schemaview.get_slot(slot).description }}|
{% endfor -%}

{% for c in gen.all_class_objects()|sort(attribute='rank') %}
Expand All @@ -328,7 +338,7 @@ spec:
{%- set parameters_slot = schemaview.get_slot("parameters") -%}
{%- set is_map_key = parameters_slot and parameters_slot.range == c.name and not parameters_slot.inlined_as_list and slot.identifier %}
{%- if not is_map_key %}
| {{ slot.name }} | {{ format_range(slot) }} | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}|
| {{ display_slot_name(slot.name) }} | {{ format_range(slot) }} | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}|
{%- endif %}
{%- endfor %}
{%- endif %}
Expand Down Expand Up @@ -361,3 +371,21 @@ In this example, an application is deployed to a child device with the see-thru
```yaml
{% include 'examples/valid/gateway-autonomous.yaml' %}
```

### Specification Extensions

> **Note:** See the [specification extensions](../margo-management-interface/specification-extensions.md) page for additional details.

The Application Deployment document supports the following specification extension scenarios:

#### Collaboration between application and device suppliers

Application suppliers targeting device supplier specification extensions include the required specification extension properties in the [application description](../applications/application-description.md#specification-extensions) document. Workload fleet manager service implementations MUST include the specification extension properties defined in the application description in the application deployment document. The specification extensions defined in the application description's deploymentProfile or component objects must be included in the comparable [deploymentProfile](#deploymentprofile-attributes) or [component](#component-attributes) objects in the application deployment document exactly as they are in the application description document.

The device client implementations MUST ignore any unknown specification extensions targeting a device supplier. Importing an application deployment with unknown specification extensions MUST NOT result in a failure because of the included specification extensions.

#### Collaboration between workload fleet manager and device suppliers

For the workload fleet manager to make use of specification extensions defined by a device supplier, the extension property MUST be added to the Application Deployment yaml document's [spec](#spec-attributes) object.

The device client implementations MUST ignore any unknown specification extensions targeting a device supplier. Importing an application deployment with unknown specification extensions MUST NOT result in a failure because of the included specification extensions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ DELETE /api/v1/clients/{clientId}/capabilities/{deviceId}
| apiVersion | string | Y | Identifier of the version the API resource follows.|
| kind | string | Y | Must be `DeviceCapabilitiesManifest`.|
| properties | Properties | Y | Element that defines characteristics about the device. See the [Properties Fields](#properties-attributes) section below. |
| x-&lt;unique-name&gt;-extensions | map[string]interface{} | N | Allows addition of an arbitrary JSON object whose contents suppliers use to provide vendor-specific functionality beyond what is defined in the Margo specification. See the [Specification Extensions](#specification-extensions) section below for more details. |


### Properties Attributes

Expand Down Expand Up @@ -335,3 +337,15 @@ A WFM client reporting the "Gateway" role MUST report its own capabilities to th
```
DELETE /api/v1/clients/{clientId}/capabilities/gateway1/deviceA
```

## Specification Extensions

> **Note:** See the [specification extensions](../margo-management-interface/specification-extensions.md) page for additional details.

The Device Capabilities document supports the following specification extension scenarios:

### Collaboration between device and workload fleet manager suppliers

For the device workload fleet manager clients to make use of specification extensions defined by a workload fleet manager supplier, the extension property MUST be added to the device capabilities JSON document's [root](#request-body-attributes).

Workload fleet manager service implementations MUST ignore any unknown specification extensions targeting a device supplier. Importing a device capabilities document with unknown specification extensions MUST NOT result in a failure because of the included specification extensions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Specification Extensions

Workload fleet manager and device suppliers may desire a way to add custom metadata, configuration, or functionality to certain Margo documents that goes beyond what is defined in the Margo specification.

The functionality is supported via specification extensions and may be used for:

- Collaboration between application and workload fleet manager suppliers
- Collaboration between application and device suppliers
- Collaboration between workload fleet manager and device suppliers

While specification extensions are not interoperable by nature, a standardized extension mechanism ensures that such customizations do not break interoperability or conformance for other suppliers, that unknown extensions are safely ignored, and that the Margo specification can evolve without breaking supplier-specific customizations.

Specification extensions add functionality that is not part of the Margo specification. It is expected suppliers collaborate with each other in order to know what is available. Margo does not maintain a listing of these specification extensions.

Workload fleet management server and client implementations MUST NOT fail when encountering unknown specification extensions in the Application Description, Application Deployment or Device Capabilities documents. Unknown specification extension properties targeting a workload fleet manager or device supplier MUST be ignored.

For specifics, see the specification extension documentation for each of the following documents:

- [Application Description](../applications/application-description.md#specification-extensions)
- [Application Deployment](./desired-state#specification-extensions)
- [Device Capabilities](./device-capabilities.md#specification-extensions)

The property naming conventions for adding specification extension is `x-<unique name>-extensions`.

The `<unique-name>` MUST match the `[a-z][a-z0-9-]*` regular expression and conform with the following rules:

- MUST start with a lowercase letter
- MUST have no spaces or special characters
- MAY contain lowercase letters, digits, and dashes

It is recommended to use identifying information as the unique name such as a company name, organization name, a combination of company name and department, etc. to reduce chances of naming conflicts.

For example:

- x-acme-extensions
- x-edgecircuitsystems-extensions
- x-northstar-industries-extensions
- x-northforgesystems-processautomation-extensions

The value of an extension property MUST be an object (a YAML/JSON mapping). Its child properties may be any simple or complex structure, as long as it is valid YAML or JSON applicable to the document type the specification extension property is added to.

> **Note:** The supplier implementing the specification extension defines the specification extension property name and supported child properties. A supplier wishing to make use of the specification extension uses the specification extension property name and child properties the implementor has defined.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
openapi: 3.0.3
openapi: 3.1.0
info:
title: Margo Workload Management API
version: 1.0.0
Expand Down Expand Up @@ -403,8 +403,7 @@ components:
Monotonically increasing unsigned 64-bit integer in the inclusive range [1, 2^64-1].
Prevents rollback attacks. The first manifest MUST use 1.
DeploymentBundleRef:
type: object
nullable: true
type: [object, 'null']
description: >
Describes a single archive containing all ApplicationDeployment documents. If there are zero deployments (deployments array is empty) the property MUST be present with the value null (it MUST NOT be omitted).
properties:
Expand Down Expand Up @@ -471,6 +470,13 @@ components:
DeviceCapabilitiesManifest:
type: object
required: [apiVersion, kind, properties]
patternProperties:
'^x-[a-z][a-z0-9-]*-extensions$':
type: object
description: >-
Vendor-specific extension. Keys MUST match x-<unique-name>-extensions
where <unique-name> matches [a-z][a-z0-9-]*.
additionalProperties: false
properties:
apiVersion:
type: string
Expand Down Expand Up @@ -648,6 +654,13 @@ components:
type: object
description: Helm Application Deployment Profile Component
required: [name, properties]
patternProperties:
'^x-[a-z][a-z0-9-]*-extensions$':
type: object
description: >-
Vendor-specific extension. Keys MUST match x-<unique-name>-extensions
where <unique-name> matches [a-z][a-z0-9-]*.
additionalProperties: false
properties:
name:
type: string
Expand All @@ -672,6 +685,13 @@ components:
type: object
description: Compose Application Deployment Profile Component
required: [name, properties]
patternProperties:
'^x-[a-z][a-z0-9-]*-extensions$':
type: object
description: >-
Vendor-specific extension. Keys MUST match x-<unique-name>-extensions
where <unique-name> matches [a-z][a-z0-9-]*.
additionalProperties: false
properties:
name:
type: string
Expand All @@ -696,6 +716,13 @@ components:
type: object
description: Application Deployment Profile
required: [type, components]
patternProperties:
'^x-[a-z][a-z0-9-]*-extensions$':
type: object
description: >-
Vendor-specific extension. Keys MUST match x-<unique-name>-extensions
where <unique-name> matches [a-z][a-z0-9-]*.
additionalProperties: false
properties:
type:
type: string
Expand Down Expand Up @@ -745,6 +772,13 @@ components:
type: object
description: Application Deployment specification
required: [applicationId, deploymentProfile]
patternProperties:
'^x-[a-z][a-z0-9-]*-extensions$':
type: object
description: >-
Vendor-specific extension. Keys MUST match x-<unique-name>-extensions
where <unique-name> matches [a-z][a-z0-9-]*.
additionalProperties: false
properties:
applicationId:
type: string
Expand Down
Loading