Skip to content

Commit

Permalink
feat(schema): schema changes for custom REST endpoints (#1509)
Browse files Browse the repository at this point in the history
**Issue number:**
[ADDON-76812](https://splunk.atlassian.net/browse/ADDON-76812)

### PR Type

**What kind of change does this PR introduce?**
* [x] Feature
* [ ] Bug Fix
* [ ] Refactoring (no functional or API changes)
* [ ] Documentation Update
* [ ] Maintenance (dependency updates, CI, etc.)

## Summary

### Changes

Schema changes required for the future feature for adding custom REST
endpoints.

This change adds new `options` section with `restHandlers`.

```js
{
  "meta": {},
  "pages": {
    "configuration": {},
    "inputs": {},
    "dashboards": {}
  },
  "alerts": [],
  "options": {
    "restHandlers": []  // <--- here 
  }
}
```

The array above consists of entries of the following form (example):

```js
{
  "endpoint": "some_endpoint",
  "handlerType": "EAI",
  "registerHandler": {
    "file": "my_handler.py",
    "actions": ["list", "create", "edit", "remove"]
  },
  "requestParameters": {
    "create": {
      "some_param": {"type": "string"},
      "other_param": {"type": "number"},
      "other_param_nullable": {
        "type": "number",
        "nullable": true,
      }
    },
    "list": {
      "array_param": {
        "type": "array",
        "items": {"type": "string"},
      },
      "obj_param": {
        "type": "object",
        "properties": {
          "key": {"type": "string"},
        }
      }
    }
  },
  "responseParams": {
    // similar to requestParameters
  }
}
```

- `endpoint` - it denotes the URL path that handler is connected to
- `handlerType` - currently only `EAI` is specified here, to denote,
that only
[EAI](https://dev.splunk.com/enterprise/docs/devtools/customrestendpoints/customresteai/)
endpoints are supported. This is added in case we would like to support
other handlers as well in the future.
- `registerHandler` - optional. If specified, it registers the handler
in `web.conf` and `restmap.conf`.
- `requestParameters` - an object with action name as a key and value
being a dictionary containing keys (parameter names) to values (OpenAPI
data types).
- `responseParameters` - similar to the above one

The data types are based on [OpenAPI data
types](https://swagger.io/docs/specification/v3_0/data-models/data-types).
Example data types:

- `{"type": "string"}`
- `{"type": "number", "nullable": true}`
- `{"type": "boolean"}`
- `{"type": "array", "items": {"type": "string"}}`
- `{"type": "object", "parameters": {"some_param": {"type": "string"}}}`
- `{"anyOf": [...]}`
- `{"allOf": [...]}`

### User experience

No changes to the current user experience.

## Checklist

If an item doesn't apply to your changes, leave it unchecked.

* [x] I have performed a self-review of this change according to the
[development
guidelines](https://splunk.github.io/addonfactory-ucc-generator/contributing/#development-guidelines)
* [x] Tests have been added/modified to cover the changes [(testing
doc)](https://splunk.github.io/addonfactory-ucc-generator/contributing/#build-and-test)
* [ ] Changes are documented
* [x] PR title and description follows the [contributing
principles](https://splunk.github.io/addonfactory-ucc-generator/contributing/#pull-requests)

---------

Co-authored-by: Artem Rys <[email protected]>
  • Loading branch information
kkedziak-splunk and artemrys authored Jan 3, 2025
1 parent 3020cfd commit 451111a
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 0 deletions.
198 changes: 198 additions & 0 deletions splunk_add_on_ucc_framework/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2341,6 +2341,201 @@
]
}
},
"OpenApiType": {
"type": "object",
"description": "OpenAPI request or response param type.",
"oneOf": [
{
"properties": {
"type": {
"type": "string",
"enum": ["string", "number", "integer", "boolean"]
},
"nullable": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false,
"required": [
"type"
]
},
{
"properties": {
"type": {
"type": "string",
"const": "array"
},
"items": {
"$ref": "#/definitions/OpenApiType"
},
"nullable": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false,
"required": [
"type",
"items"
]
},
{
"properties": {
"type": {
"type": "string",
"const": "object"
},
"properties": {
"type": "object",
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/OpenApiType"
}
}
}
},
"additionalProperties": false,
"required": [
"type",
"properties"
]
},
{
"properties": {
"anyOf": {
"type": "array",
"items": {
"$ref": "#/definitions/OpenApiType"
}
},
"nullable": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false,
"required": [
"anyOf"
]
},
{
"properties": {
"oneOf": {
"type": "array",
"items": {
"$ref": "#/definitions/OpenApiType"
}
},
"nullable": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false,
"required": [
"oneOf"
]
}
]
},
"RestHandlerActionParams": {
"type": "object",
"description": "Request or response parameters for a particular action.",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"$ref": "#/definitions/OpenApiType"
}
}
},
"RestHandlerParams": {
"type": "object",
"description": "Request or response parameters.",
"additionalProperties": false,
"properties": {
"list": {
"$ref": "#/definitions/RestHandlerActionParams"
},
"edit": {
"$ref": "#/definitions/RestHandlerActionParams"
},
"create": {
"$ref": "#/definitions/RestHandlerActionParams"
},
"remove": {
"$ref": "#/definitions/RestHandlerActionParams"
}
}
},
"RestHandler": {
"type": "object",
"description": "Rest handlers not automatically generated by UCC.",
"properties": {
"endpoint": {
"type": "string",
"description": "The endpoint for the custom rest handler."
},
"handlerType": {
"type": "string",
"description": "The type of the handler.",
"enum": ["EAI"]
},
"registerHandler": {
"type": "object",
"description": "Parameters needed to register the endpoint in web.conf and restmap.conf",
"properties": {
"file": {
"type": "string",
"description": "The file where the custom rest handler is located."
},
"actions": {
"type": "array",
"description": "The actions that the custom rest handler supports.",
"items": {
"type": "string",
"description": "The action that the custom rest handler supports.",
"enum": ["list", "edit", "create", "remove"]
}
}
},
"additionalProperties": false,
"required": [
"file",
"actions"
]
},
"requestParameters": {
"type": "object",
"description": "The parameters that the custom rest handler supports.",
"$ref": "#/definitions/RestHandlerParams"
},
"responseParameters": {
"type": "object",
"description": "The parameters that the custom rest handler returns.",
"$ref": "#/definitions/RestHandlerParams"
}
},
"additionalProperties": false,
"required": [
"endpoint",
"handlerType"
]
},
"Options": {
"type": "object",
"description": "Additional options for the addon",
"properties": {
"restHandlers": {
"type": "array",
"items": {
"$ref": "#/definitions/RestHandler"
}
}
},
"additionalProperties": false
},
"Pages": {
"type": "object",
"description": "Definition of addon pages (configuration, inputs, dashboard)",
Expand Down Expand Up @@ -3412,6 +3607,9 @@
"$ref": "#/definitions/Alerts"
},
"minItems": 1
},
"options": {
"$ref": "#/definitions/Options"
}
},
"required": [
Expand Down
43 changes: 43 additions & 0 deletions tests/unit/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,46 @@ def test_interval_entity_options(schema_validate, config):
}
)
)


def test_rest_handler_without_ui(schema_validate, config):
crh = {
"endpoint": "some_endpoint",
"handlerType": "EAI",
"requestParameters": {
"create": {
"some_param": {"type": "string"},
"other_param": {"type": "number"},
"other_param_nullable": {
"type": "number",
"nullable": True,
},
},
"list": {
"array_param": {
"type": "array",
"items": {"type": "string"},
},
"obj_param": {
"type": "object",
"properties": {
"key": {"type": "string"},
},
},
},
},
"responseParameters": {
"list": {
"some_param": {"type": "string"},
},
},
}
config.setdefault("options", {})["restHandlers"] = [crh]
schema_validate(config)

crh["registerHandler"] = {
"file": "my_handler.py",
"actions": ["list", "create", "edit", "remove"],
}

schema_validate(config)

0 comments on commit 451111a

Please sign in to comment.