inmanta / web-console

Next generation inmanta web-console
Apache License 2.0
2 stars 1 forks source link

Support nested attributes in add instance form #696

Closed bartv closed 3 years ago

bartv commented 3 years ago

Currently the add instance form only support the toplevel attributes. More and more services use a nested structure. This goal of this ticket is to:

edvgui commented 3 years ago

In the current state of things, the input attributes would look like this:

desired_attributes = {
    "identifier": "my-evc-001",
    "connectionType": "POINT_TO_POINT",
    "evcEndPoints": [
        {
            "identifier": "my-evc-ep-1",
            "egressBandwidthProfilePerEndPoint": [
                {
                    "cir": 1,
                },
                {
                    "cir": 2,
                },
            ],
            "evcEndPointMap": {
                "type": "LIST",
                "vlanIdList": [{"vlanId": 200}],
            },
            "carrierEthernetSubscriberUni": {
                "href": "inmanta:456-852-789",
            },
        },
        {
            "identifier": "my-evc-ep-2",
            "egressBandwidthProfilePerEndPoint": [
                {
                    "cir": 1,
                },
                {
                    "cir": 2,
                },
            ],
            "evcEndPointMap": {
                "type": "LIST",
                "vlanIdList": [{"vlanId": 201}],
            },
            "carrierEthernetSubscriberUni": {
                "href": "inmanta:123-852-456",
            },
        },
    ],
}

for a service definition that looks like this:

entity CarrierEthernetService:
    connection_type connectionType
end

entity CarrierEthernetEvc extends CarrierEthernetService, lsm::ServiceEntity:
    evc_id identifier
end
index CarrierEthernetEvc(identifier)
CarrierEthernetEvc.evcEndPoints [2] -- CarrierEthernetEvcEndPoint

entity CarrierEthernetEvcEndPoint extends lsm::EmbeddedEntity:
    evc_id identifier
end
index CarrierEthernetEvcEndPoint(identifier)
CarrierEthernetEvcEndPoint.egressBandwidthProfilePerEndPoint [0:] -- EgressBwpFlow
CarrierEthernetEvcEndPoint.evcEndPointMap [1] -- VlanIdListOrUntag
CarrierEthernetEvcEndPoint.carrierEthernetSubscriberUni [1] -- CarrierEthernetSubscriberUniRef

entity EgressBwpFlow extends lsm::EmbeddedEntity:
    std::positive_int cir
end

entity VlanIdListOrUntag extends lsm::EmbeddedEntity:
    vlan_id_list_type type
end
VlanIdListOrUntag.vlanIdList [0:] -- VlanId

entity VlanId extends lsm::EmbeddedEntity:
    vlan_id_type vlanId
end

entity CarrierEthernetSubscriberUniRef extends lsm::EmbeddedEntity:
    string href
end

Here is an automatically generated openapi json file for this service:

Collapsed because it is huged ```json { "data": { "openapi": "3.0.2", "info": { "title": "Inmanta Service Orchestrator", "version": "4.2.0" }, "servers": [ { "url": "http://192.168.2.22:8888/" } ], "paths": { "/lsm/v1/service_inventory/carrierEthernetEvc": { "post": { "operationId": "lsm_services_create-carrierEthernetEvc", "summary": "Create a new service instance", "parameters": [ { "description": "The id of the environment", "required": true, "schema": { "type": "string", "format": "uuid" }, "name": "X-Inmanta-tid", "in": "header" } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "attributes": { "title": "carrierEthernetEvc", "required": [ "identifier", "connectionType" ], "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "service_instance_id": { "type": "string", "format": "uuid", "nullable": true } } } } }, "required": true }, "responses": { "200": { "description": "The newly created service instance.", "headers": { "X-Inmanta-tid": { "description": "X-Inmanta-tid", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "title": "ServiceInstance", "required": [ "id", "environment", "service_entity", "version", "config", "state", "created_at", "last_updated", "callback", "deleted" ], "type": "object", "properties": { "id": { "title": "Id", "type": "string", "format": "uuid" }, "environment": { "title": "Environment", "type": "string", "format": "uuid" }, "service_entity": { "title": "Service Entity", "type": "string" }, "version": { "title": "Version", "type": "integer" }, "config": { "title": "Config", "type": "object" }, "state": { "title": "State", "type": "string" }, "candidate_attributes": { "title": "Candidate Attributes", "required": [ "identifier", "connectionType" ], "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "active_attributes": { "title": "Active Attributes", "required": [ "identifier", "connectionType" ], "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "rollback_attributes": { "title": "Rollback Attributes", "required": [ "identifier", "connectionType" ], "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "created_at": { "title": "Created At", "type": "string", "format": "date-time" }, "last_updated": { "title": "Last Updated", "type": "string", "format": "date-time" }, "callback": { "title": "Callback", "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 65536, "format": "uri" } }, "deleted": { "title": "Deleted", "type": "boolean" }, "deployment_progress": { "$ref": "#/components/schemas/DeploymentProgress" }, "service_identity_attribute_value": { "title": "Service Identity Attribute Value", "type": "string" } }, "description": "An instance of a service entity.\n\n:param id: A unique uuid for this service instance\n:param environment: The environment this service instance belongs to\n:param service_entity: The name of the service entity defined in this environment\n:param version: An opaque version identifier that is incremented on every state change. This identifier is strict\n monotonic and integer.\n:param config: A dict with flags that override config in the service entity\n:param state: The state of this instance. The state refers to a state defined in the service entity lifecycle\n\n:param candidate_attributes: The set of attributes used when the service instance model state is candidate or designed.\n:param active_attributes: The set of attributes when the model is evaluated with only active instances.\n:param rollback_attributes: The set of attributes that can be used to rollback active attributes that result in an error\n state.\n\n:param created_at: The timestamp indicating when this ServiceInstance was created.\n:param last_updated: The timestamp of the last state transition of this ServiceInstance.\n:param callback: A list of callback urls that are notified when the state of this instance changes.\n:param deployment_progress: Summary of the deployment progress of the resources associated with this instance\n:param service_identity_attribute_value: If an identity was specified for the service entity corresponding to this instance,\nthen this field holds identity value of the instance." } } } } } }, "400": { "description": "This exception is raised on invalid requests, e.g., when the attribute validation fails" }, "404": { "description": "This exception is raised when the referenced environment or service_entity is not found" }, "409": { "description": "This exception is raised when the given service_instance_id already exists" } }, "tags": [ "carrierEthernetEvc" ] } }, "/lsm/v1/service_inventory/carrierEthernetEvc/{service_id}": { "get": { "operationId": "lsm_services_get-carrierEthernetEvc", "summary": "Get a given service instance", "parameters": [ { "description": "The id of the environment", "required": true, "schema": { "type": "string", "format": "uuid" }, "name": "X-Inmanta-tid", "in": "header" }, { "description": "The id of the service instance to be retrieved\nor a service identity query in the form of 'identity_attribute_name=attribute_value',\nfor example, if the identity is 'order_id', specifying `order_id=1234` can be used to query this instance,\ninstead of the uuid", "required": true, "schema": { "type": "string" }, "name": "service_id", "in": "path" }, { "description": "If not specified the last version of the service instance is returned. If the current_version\nis provided, this value is verified against the actual current_version. If these do not match\na Conflict exception is raised. Use this parameter to verify if your current state still\nmatches the actual state.", "required": false, "schema": { "type": "integer", "nullable": true }, "name": "current_version", "in": "query" }, { "description": "Determines whether to include the deployment progress summary of\nthe resources associated with this instance", "required": false, "schema": { "type": "boolean", "nullable": true }, "name": "include_deployment_progress", "in": "query" } ], "responses": { "200": { "description": "The newly created service instance.", "headers": { "X-Inmanta-tid": { "description": "X-Inmanta-tid", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "title": "ServiceInstance", "required": [ "id", "environment", "service_entity", "version", "config", "state", "created_at", "last_updated", "callback", "deleted" ], "type": "object", "properties": { "id": { "title": "Id", "type": "string", "format": "uuid" }, "environment": { "title": "Environment", "type": "string", "format": "uuid" }, "service_entity": { "title": "Service Entity", "type": "string" }, "version": { "title": "Version", "type": "integer" }, "config": { "title": "Config", "type": "object" }, "state": { "title": "State", "type": "string" }, "candidate_attributes": { "title": "Candidate Attributes", "required": [ "identifier", "connectionType" ], "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "active_attributes": { "title": "Active Attributes", "required": [ "identifier", "connectionType" ], "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "rollback_attributes": { "title": "Rollback Attributes", "required": [ "identifier", "connectionType" ], "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "created_at": { "title": "Created At", "type": "string", "format": "date-time" }, "last_updated": { "title": "Last Updated", "type": "string", "format": "date-time" }, "callback": { "title": "Callback", "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 65536, "format": "uri" } }, "deleted": { "title": "Deleted", "type": "boolean" }, "deployment_progress": { "$ref": "#/components/schemas/DeploymentProgress" }, "service_identity_attribute_value": { "title": "Service Identity Attribute Value", "type": "string" } }, "description": "An instance of a service entity.\n\n:param id: A unique uuid for this service instance\n:param environment: The environment this service instance belongs to\n:param service_entity: The name of the service entity defined in this environment\n:param version: An opaque version identifier that is incremented on every state change. This identifier is strict\n monotonic and integer.\n:param config: A dict with flags that override config in the service entity\n:param state: The state of this instance. The state refers to a state defined in the service entity lifecycle\n\n:param candidate_attributes: The set of attributes used when the service instance model state is candidate or designed.\n:param active_attributes: The set of attributes when the model is evaluated with only active instances.\n:param rollback_attributes: The set of attributes that can be used to rollback active attributes that result in an error\n state.\n\n:param created_at: The timestamp indicating when this ServiceInstance was created.\n:param last_updated: The timestamp of the last state transition of this ServiceInstance.\n:param callback: A list of callback urls that are notified when the state of this instance changes.\n:param deployment_progress: Summary of the deployment progress of the resources associated with this instance\n:param service_identity_attribute_value: If an identity was specified for the service entity corresponding to this instance,\nthen this field holds identity value of the instance." } } } } } }, "404": { "description": "This exception is raised when the referenced environment or service_entity is not found" }, "409": { "description": "This exception is raised when the provided current_version does not match the actual current version" } }, "tags": [ "carrierEthernetEvc" ] }, "delete": { "operationId": "lsm_services_delete-carrierEthernetEvc", "summary": "Delete an existing service instance", "parameters": [ { "description": "The id of the environment", "required": true, "schema": { "type": "string", "format": "uuid" }, "name": "X-Inmanta-tid", "in": "header" }, { "description": "The id of the service instance to be deleted", "required": true, "schema": { "type": "string", "format": "uuid" }, "name": "service_id", "in": "path" } ], "responses": { "200": { "description": "", "headers": { "X-Inmanta-tid": { "description": "X-Inmanta-tid", "schema": { "type": "string" } } } }, "404": { "description": "This exception is raised when the referenced environment, service_entity or service_id is not found" }, "409": { "description": "This exception is raised when the provided current_version does not match the actual current version" } }, "tags": [ "carrierEthernetEvc" ] }, "patch": { "operationId": "lsm_services_update-carrierEthernetEvc", "summary": "Update an existing service instance.", "parameters": [ { "description": "The id of the environment", "required": true, "schema": { "type": "string", "format": "uuid" }, "name": "X-Inmanta-tid", "in": "header" }, { "description": "The id of the service instance for which the attributes should be updated", "required": true, "schema": { "type": "string", "format": "uuid" }, "name": "service_id", "in": "path" } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "attributes": { "title": "carrierEthernetEvc", "type": "object", "properties": { "identifier": { "title": "Identifier", "type": "string" }, "connectionType": { "$ref": "#/components/schemas/connection_type" } } }, "current_version": { "type": "integer", "nullable": true } } } } }, "required": true }, "responses": { "200": { "description": "", "headers": { "X-Inmanta-tid": { "description": "X-Inmanta-tid", "schema": { "type": "string" } } } }, "400": { "description": "This exception is raised on invalid requests, e.g., when the attribute validation fails" }, "404": { "description": "This exception is raised when the referenced environment, service_entity or service_id is not found" }, "409": { "description": "This exception is raised when the provided current_version does not match the actual current version" } }, "tags": [ "carrierEthernetEvc" ] } } }, "components": { "schemas": { "connection_type": { "title": "connection_type", "description": "An enumeration.", "enum": [ "POINT_TO_POINT" ] }, "DeploymentProgress": { "title": "DeploymentProgress", "description": "The current progress of the deployment of resources associated with a service instance\n\n:param total: Total number of resources\n:param failed: Number of resources in failed or unavailable state\n:param deployed: Number of successfully deployed resources\n:param waiting: Number of resources not yet deployed or failed", "type": "object", "properties": { "total": { "title": "Total", "type": "integer" }, "failed": { "title": "Failed", "type": "integer" }, "deployed": { "title": "Deployed", "type": "integer" }, "waiting": { "title": "Waiting", "type": "integer" } }, "required": [ "total", "failed", "deployed", "waiting" ] }, "AttributeModifier": { "title": "AttributeModifier", "description": "An enumeration.", "enum": [ "r", "rw", "rw+" ], "type": "string" }, "ServiceAttribute": { "title": "ServiceAttribute", "description": ":param type: The Inmanta type of this service attribute.\n:param default_value: The default value of this service attribute.\n:param default_value_set: Indicates whether a default value was provided in the service entity definition.\n:param validation_type: When a typedef was used, this parameter specifies the name of the constraint type.\n Otherwise this value is equal to type.\n:param validation_parameters: Validation parameters for validation_type.", "type": "object", "properties": { "name": { "title": "Name", "type": "string" }, "description": { "title": "Description", "type": "string" }, "modifier": { "default": "rw", "allOf": [ { "$ref": "#/components/schemas/AttributeModifier" } ] }, "type": { "title": "Type", "type": "string" }, "default_value": { "title": "Default Value", "anyOf": [ { "type": "boolean" }, { "type": "number" }, { "type": "integer" }, { "type": "string" }, { "type": "array", "items": { "anyOf": [ { "type": "boolean" }, { "type": "number" }, { "type": "integer" }, { "type": "string" } ] } }, { "type": "object", "additionalProperties": { "anyOf": [ { "type": "boolean" }, { "type": "number" }, { "type": "integer" }, { "type": "string" } ] } } ] }, "default_value_set": { "title": "Default Value Set", "default": false, "type": "boolean" }, "validation_type": { "title": "Validation Type", "type": "string" }, "validation_parameters": { "title": "Validation Parameters", "type": "object" } }, "required": [ "name", "type" ] }, "EmbeddedServiceEntity": { "title": "EmbeddedServiceEntity", "description": ":param lower_limit: The lower limit (inclusive) of the arity of the relation between an entity and this\n EmbeddedServiceEntity.\n:param upper_limit: The upper limit (inclusive) of the arity of the relation between an entity and this\n EmbeddedServiceEntity. A None value indicates that the relation doesn't have an upper limit.", "type": "object", "properties": { "attributes": { "title": "Attributes", "type": "array", "items": { "$ref": "#/components/schemas/ServiceAttribute" } }, "embedded_entities": { "title": "Embedded Entities", "default": [], "type": "array", "items": { "$ref": "#/components/schemas/EmbeddedServiceEntity" } }, "name": { "title": "Name", "type": "string" }, "description": { "title": "Description", "type": "string" }, "modifier": { "default": "rw", "allOf": [ { "$ref": "#/components/schemas/AttributeModifier" } ] }, "lower_limit": { "title": "Lower Limit", "default": 0, "minimum": 0, "type": "integer" }, "upper_limit": { "title": "Upper Limit", "minimum": 1, "type": "integer" } }, "required": [ "attributes", "name" ] }, "AttributeSetOpt": { "title": "AttributeSetOpt", "description": "An enumeration.", "enum": [ "candidate", "active" ], "type": "string" }, "LifecycleState": { "title": "LifecycleState", "description": "Base class for all data objects in Inmanta", "type": "object", "properties": { "name": { "title": "Name", "type": "string" }, "label": { "title": "Label", "type": "string" }, "export_resources": { "title": "Export Resources", "type": "boolean" }, "validate_self": { "$ref": "#/components/schemas/AttributeSetOpt" }, "validate_others": { "$ref": "#/components/schemas/AttributeSetOpt" }, "purge_resources": { "title": "Purge Resources", "type": "boolean" }, "deleted": { "title": "Deleted", "type": "boolean" }, "values": { "title": "Values", "type": "object", "additionalProperties": { "anyOf": [ { "type": "boolean" }, { "type": "number" }, { "type": "integer" }, { "type": "string" } ] } } }, "required": [ "name", "export_resources", "purge_resources", "deleted", "values" ] }, "LifecycleTransfer": { "title": "LifecycleTransfer", "description": ":param description: description (or name) of this transition for documentation and debugging purposes.\n\n:param source: source state\n:param target: target state\n:param error: error state, required if validate or resource_based is true else prohibited\n\n:param on_update: this transition is initiated if the parameters are updated\n:param on_delete: this transition is initiated if the instance receives a delete call\n:param api_set_state: this transition is initiated by an explicit API set state call\n:param resource_based: this transition is initiated by deployment of specific resources\n:param auto: this transition is initiated when the source state is reached,\n(unless the config value pointed to by config_name is false)\n\n:param validate: this transition will preform a validation once initiated (allowed on auto or api_set_state)\n:param config_name: name of a configuration value that determines if an auto the transition should be done or not\n(implies auto)\n\n:param target_operation: operation to perform upon transfer to the source state\n:param error_operation: operation to perform upon transfer to the error state", "type": "object", "properties": { "source": { "title": "Source", "type": "string" }, "target": { "title": "Target", "type": "string" }, "error": { "title": "Error", "type": "string" }, "on_update": { "title": "On Update", "default": false, "type": "boolean" }, "on_delete": { "title": "On Delete", "default": false, "type": "boolean" }, "api_set_state": { "title": "Api Set State", "default": false, "type": "boolean" }, "resource_based": { "title": "Resource Based", "default": false, "type": "boolean" }, "auto": { "title": "Auto", "default": false, "type": "boolean" }, "validate": { "title": "Validate", "default": false, "type": "boolean" }, "config_name": { "title": "Config Name", "type": "string" }, "description": { "title": "Description", "type": "string" }, "target_operation": { "title": "Target Operation", "type": "string" }, "error_operation": { "title": "Error Operation", "type": "string" } }, "required": [ "source", "target" ] }, "Lifecycle": { "title": "Lifecycle", "description": "Base class for all data objects in Inmanta", "type": "object", "properties": { "states": { "title": "States", "type": "array", "items": { "$ref": "#/components/schemas/LifecycleState" } }, "transfers": { "title": "Transfers", "type": "array", "items": { "$ref": "#/components/schemas/LifecycleTransfer" } }, "initial_state": { "title": "Initial State", "type": "string" }, "name": { "title": "Name", "type": "string" } }, "required": [ "states", "transfers", "initial_state", "name" ] }, "ResourceAction": { "title": "ResourceAction", "description": "Enumeration of all resource actions.", "enum": [ "store", "push", "pull", "deploy", "dryrun", "getfact", "other" ], "type": "string" }, "Failure": { "title": "Failure", "description": ":param instance_version: The instance version before the failure.\n:param model_version: The version of the model where this failure occurred.\n:param resource: The resource for which the failure occurred.\n:param action: The resource action that failed.\n:param time: When this error occurred.\n:param message: The error message.", "type": "object", "properties": { "instance_version": { "title": "Instance Version", "type": "integer" }, "model_version": { "title": "Model Version", "type": "integer" }, "resource_id": { "title": "Resource Id", "type": "string" }, "action": { "$ref": "#/components/schemas/ResourceAction" }, "time": { "title": "Time", "type": "string", "format": "date-time" }, "message": { "title": "Message", "type": "string" } }, "required": [ "instance_version", "model_version", "resource_id", "action", "time", "message" ] }, "FailureGroup": { "title": "FailureGroup", "description": "A collection of similar errors for the same resource.", "type": "object", "properties": { "resource_id": { "title": "Resource Id", "type": "string" }, "failures": { "title": "Failures", "type": "array", "items": { "$ref": "#/components/schemas/Failure" } } }, "required": [ "resource_id", "failures" ] }, "ErrorCategory": { "title": "ErrorCategory", "description": "Category of an error.", "enum": [ "plugin_exception", "parse_error", "runtime_error" ], "type": "string" }, "Position": { "title": "Position", "description": "Position in a file. Based on the\n`LSP spec 3.15 `__", "type": "object", "properties": { "line": { "title": "Line", "type": "integer" }, "character": { "title": "Character", "type": "integer" } }, "required": [ "line", "character" ] }, "Range": { "title": "Range", "description": "Range in a file. Based on the\n`LSP spec 3.15 `__", "type": "object", "properties": { "start": { "$ref": "#/components/schemas/Position" }, "end": { "$ref": "#/components/schemas/Position" } }, "required": [ "start", "end" ] }, "Location": { "title": "Location", "description": "Location in a file. Based on the\n`LSP spec 3.15 `__", "type": "object", "properties": { "uri": { "title": "Uri", "type": "string" }, "range": { "$ref": "#/components/schemas/Range" } }, "required": [ "uri", "range" ] }, "Error": { "title": "Error", "description": "Error occurred while trying to compile.", "type": "object", "properties": { "category": { "default": "runtime_error", "allOf": [ { "$ref": "#/components/schemas/ErrorCategory" } ] }, "type": { "title": "Type", "type": "string" }, "message": { "title": "Message", "type": "string" }, "location": { "$ref": "#/components/schemas/Location" } }, "required": [ "type", "message" ] }, "Rejection": { "title": "Rejection", "description": ":param instance_version: The instance version associated with the failed validation compile.\n:param model_version: The version of the model that got rejected.\n:param compile_id: The id of the validation compile that failed.\n:param errors: The compile errors that caused the rejection.\n:param trace: The full error stream of the validation compile.", "type": "object", "properties": { "instance_version": { "title": "Instance Version", "type": "integer" }, "model_version": { "title": "Model Version", "type": "integer" }, "compile_id": { "title": "Compile Id", "type": "string", "format": "uuid" }, "errors": { "title": "Errors", "type": "array", "items": { "$ref": "#/components/schemas/Error" } }, "trace": { "title": "Trace", "type": "string" } }, "required": [ "instance_version", "compile_id", "errors" ] }, "LogLevel": { "title": "LogLevel", "description": "Log levels used for various parts of the inmanta orchestrator.", "enum": [ 50, 40, 30, 20, 10, 3, 0 ] }, "EventType": { "title": "EventType", "description": "An enumeration.", "enum": [ "CREATE_TRANSITION", "API_SET_STATE_TRANSITION", "ON_UPDATE_TRANSITION", "ON_DELETE_TRANSITION", "RESOURCE_TRANSITION", "RESOURCE_EVENT", "AUTO_TRANSITION", "ALLOCATION_UPDATE" ], "type": "string" }, "Event": { "title": "Event", "description": "Event log for the lifecycle manager.\n\n:param id: The unique uuid of the event.\n:param service_instance_id: The id of the service instance this event belongs to.\n:param service_instance_version: The version of the service instance this event belong to.\n:param timestamp: A timestamp indicating when the event happened.\n:param source: The source state of the event.\n:param destination: The destination state of the event. This field is only set when the event reports a successful\ntransition to another state.\n:param message: A message describing the event.\n:param ignored_transition: This flag indicates that the transition request was ignored due because more transition\nrequests were executing concurrently.\n:param event_correlation_id: If this event belongs to previous event, this field contains the id of the associated\nevent. This is used to correlate the event produced on initiation of a transition with the event raised on\ncompletion of transition.\n:param severity: The severity of the message reported by the event.\n:param id_compile_report: When this event reports the outcome of a validate, this field contains the id of\nthe compile report.\n:param event_type: Indicates the type of the event.\n:param is_error_transition: This flag indicates whether this event signals a transition to an error state.", "type": "object", "properties": { "id": { "title": "Id", "type": "string", "format": "uuid" }, "service_instance_id": { "title": "Service Instance Id", "type": "string", "format": "uuid" }, "service_instance_version": { "title": "Service Instance Version", "type": "integer" }, "timestamp": { "title": "Timestamp", "type": "string", "format": "date-time" }, "source": { "title": "Source", "type": "string" }, "destination": { "title": "Destination", "type": "string" }, "message": { "title": "Message", "type": "string" }, "ignored_transition": { "title": "Ignored Transition", "type": "boolean" }, "event_correlation_id": { "title": "Event Correlation Id", "type": "string", "format": "uuid" }, "severity": { "$ref": "#/components/schemas/LogLevel" }, "id_compile_report": { "title": "Id Compile Report", "type": "string", "format": "uuid" }, "event_type": { "$ref": "#/components/schemas/EventType" }, "is_error_transition": { "title": "Is Error Transition", "type": "boolean" } }, "required": [ "id", "service_instance_id", "service_instance_version", "timestamp", "message", "ignored_transition", "event_correlation_id", "severity", "event_type", "is_error_transition" ] }, "BaseModel": { "title": "BaseModel", "description": "Base class for all data objects in Inmanta", "type": "object", "properties": {} }, "Enum": { "title": "Enum", "description": "Generic enumeration.\n\nDerive from this class to define new enumerations.", "enum": [] }, "ExtensionStatus": { "title": "ExtensionStatus", "description": "Status response for extensions loaded in the server", "type": "object", "properties": { "name": { "title": "Name", "type": "string" }, "version": { "title": "Version", "type": "string" }, "package": { "title": "Package", "type": "string" } }, "required": [ "name", "version", "package" ] }, "SliceStatus": { "title": "SliceStatus", "description": "Status response for slices loaded in the the server", "type": "object", "properties": { "name": { "title": "Name", "type": "string" }, "status": { "title": "Status", "type": "object", "additionalProperties": { "anyOf": [ { "$ref": "#/components/schemas/BaseModel" }, { "$ref": "#/components/schemas/Enum" }, { "type": "string", "format": "uuid" }, { "type": "boolean" }, { "type": "integer" }, { "type": "number" }, { "type": "string", "format": "date-time" }, { "type": "string" }, { "type": "array", "items": { "anyOf": [ { "$ref": "#/components/schemas/BaseModel" }, { "$ref": "#/components/schemas/Enum" }, { "type": "string", "format": "uuid" }, { "type": "boolean" }, { "type": "integer" }, { "type": "number" }, { "type": "string", "format": "date-time" }, { "type": "string" } ] } }, { "type": "object", "additionalProperties": { "anyOf": [ { "$ref": "#/components/schemas/BaseModel" }, { "$ref": "#/components/schemas/Enum" }, { "type": "string", "format": "uuid" }, { "type": "boolean" }, { "type": "integer" }, { "type": "number" }, { "type": "string", "format": "date-time" }, { "type": "string" } ] } } ] } } }, "required": [ "name", "status" ] }, "FeatureStatus": { "title": "FeatureStatus", "description": "Status of the feature", "type": "object", "properties": { "slice": { "title": "Slice", "type": "string" }, "name": { "title": "Name", "type": "string" }, "value": { "title": "Value" } }, "required": [ "slice", "name" ] }, "CompileData": { "title": "CompileData", "description": "Top level structure of compiler data to be exported.", "type": "object", "properties": { "errors": { "title": "Errors", "type": "array", "items": { "$ref": "#/components/schemas/Error" } } }, "required": [ "errors" ] }, "Environment": { "title": "Environment", "description": "An inmanta environment.\n\n:note: repo_url and repo_branch will be moved to the settings.", "type": "object", "properties": { "id": { "title": "Id", "type": "string", "format": "uuid" }, "name": { "title": "Name", "type": "string" }, "project_id": { "title": "Project Id", "type": "string", "format": "uuid" }, "repo_url": { "title": "Repo Url", "type": "string" }, "repo_branch": { "title": "Repo Branch", "type": "string" }, "settings": { "title": "Settings", "type": "object", "additionalProperties": { "anyOf": [ { "type": "boolean" }, { "type": "integer" }, { "type": "string" }, { "type": "object", "additionalProperties": { "anyOf": [ { "type": "string" }, { "type": "integer" }, { "type": "boolean" } ] } } ] } }, "halted": { "title": "Halted", "type": "boolean" } }, "required": [ "id", "name", "project_id", "repo_url", "repo_branch", "settings", "halted" ] }, "Compilestate": { "title": "Compilestate", "description": "An enumeration.", "enum": [ 1, 2 ] }, "EnvironmentSetting": { "title": "EnvironmentSetting", "description": "A class to define a new environment setting.\n\n:param name: The name of the setting.\n:param type: The type of the value. This type is mainly used for documentation purpose.\n:param default: An optional default value for this setting. When a default is set and the\n is requested from the database, it will return the default value and also store\n the default value in the database.\n:param doc: The documentation/help string for this setting\n:param recompile: Trigger a recompile of the model when a setting is updated?\n:param update_model: Update the configuration model (git pull on project and repos)\n:param agent_restart: Restart autostarted agents when this settings is updated.\n:param allowed_values: list of possible values (if type is enum)", "type": "object", "properties": { "name": { "title": "Name", "type": "string" }, "type": { "title": "Type", "type": "string" }, "default": { "title": "Default", "anyOf": [ { "type": "boolean" }, { "type": "integer" }, { "type": "string" }, { "type": "object", "additionalProperties": { "anyOf": [ { "type": "string" }, { "type": "integer" }, { "type": "boolean" } ] } } ] }, "doc": { "title": "Doc", "type": "string" }, "recompile": { "title": "Recompile", "type": "boolean" }, "update_model": { "title": "Update Model", "type": "boolean" }, "agent_restart": { "title": "Agent Restart", "type": "boolean" }, "allowed_values": { "title": "Allowed Values", "type": "array", "items": { "anyOf": [ { "type": "boolean" }, { "type": "integer" }, { "type": "string" }, { "type": "object", "additionalProperties": { "anyOf": [ { "type": "string" }, { "type": "integer" }, { "type": "boolean" } ] } } ] } } }, "required": [ "name", "type", "default", "doc", "recompile", "update_model", "agent_restart" ] } } } } } ```
butterybread commented 3 years ago

Proposal for design

To adhere as much as possible to the patternfly guidelines and components, Form Groups have been used to achieve the following design:

Copy

We start at level 0 for the root properties. Every next level has an indentation of 32px (This was the indentation provided by Patternfly Form Group components). We make a distinction between FLAT properties and NESTED properties.

FLAT (all basic values with basic input fields):

NESTED:

These types should cover all different possibilities. FLAT values can just be presented as a normal input field. NESTED values have a collapsable view. Inside this view, for each property that is flat, we can show the normal input field. For every property that is nested, we show a collapsable view again. (... and so on... and so on...)

List of objects are special where they have 2 actions.

bartv commented 3 years ago

This looks useful indeed. I even think that the json and/or yaml view could be nice (in a later version). Because that is exactly what you do: create a json body (of which yaml is a less bad way to write it)

andraskvr commented 3 years ago

Looks nice indeed, the different views as well. Minor comment: Maybe we could increase the visual emphasis on what belongs together, with regards to nesting. I think it can be a bit difficult to follow that, if the structure is complex. (Then again, there might not be an easy way to show it, if it's that complex, but maybe some more spacing / bordering can help). +1 : The design might be easier to understand if the property names were not just one letter long :slightly_smiling_face:

Overall very nice I think. :+1:

butterybread commented 3 years ago

Yea, I think we need to try it out a bit. We can always improve it later. Diverging from this design would introduce custom styles which is more work. I hope the collapsing will help the overall UX. Hide some details you are not focussed on. Maybe to aid the structure we can introduce some different labels. (instead of abc, we can do def.abc and emphasize the dot a bit.