OctoMation应用开发手册 - flagify-com/OctoMation GitHub Wiki
OctoMation 为用户与第三方设备、平台等协作提供了一个运行环境, 应用开发者只需要按照规范开发并且上传于第三方对接的App即可完成对第三方工具、设备、平台的调用。
应用的开发可以使用Python3(推荐Python3.10+)进行开发。
OctoMation 的 应用 和 HoneyGuide SOAR的 应用 是互通的。
- App:与第三方设备、平台等对接的应用,并且在OctoMation 中可执行。
- Action: 应用的动作,在App中某个具体功能的实现, 一个App中可以存在1-N个动作。
- 资源: 对应于App中的绑定设备、平台中的资产(资源), 资源可以是账号、密码、链接、甚至可以是文件。
OctoMation剧本调度引擎会根据剧本逻辑,向执行引擎发送指令,启动某个指定的Python应用APP,同时向该应用传递执行参数和设备资源信息,从完成动作执行,并获取执行结果。
应用APP根据入参和设备信息,调用目标设备资源,执行动作,并获取结果。默认结果为JSON格式,可以根据需要参照模板定义,进行输出渲染。
以下是一个标准的OctoMation Python
应用的工程目录结构:
|-- shakespeare-app-helloworld
|-- config.json
|-- helloworld.py
|-- resources
| |-- fif.png
| |-- readme.md
|-- shakespeare-action-template
| |-- show.art
这是OctoMation标准的目录结构, 为了简化应用的创建, 我们也提供了
应用生成器
目录结构各文件夹和文件解释
名称 | 属性 | 是否必须 | 说明 |
---|---|---|---|
shakespeare-app-helloworld | 根目录 | 是 | 应用根文件夹为应用包的名称, 发布时将该文件夹打包为zip文件后即可上传到OctoMation中, 应用名可以自定义, 但不能与已有的应用同名。 |
config.json | 配置文件 | 是 | 应用配置说明文件, 文件名不可更改, 必须存在。 |
helloworld.py | 代码文件 | 是 | 应用的实现代码文件, 文件名可自定义, 但必须在 config.json 中的jar字段中配置。 |
resources | 目录 | 是 | 此目录中存放应用的 帮助文档 、应用icon图标 。 |
resources - newapp.png | 图片文件 | 是 | 应用的icon 文件, 可以是PNG、JPG、ICON格式。 |
resources - readme.md | 说明文件 | 是 | 应用的使用说明文件, Markdown格式。 |
shakespeare-action-template | 目录 | 是 | 应用渲染模板目录, 所有应用返回结果渲染文件都保存在此目录中。 |
shakespeare-action-template - show.art | 渲染文件 | 否 | 渲染模板文件, 创建时名字可以自定义,以config.json 中的配置为主,如不配置模板, 系统直接展示应用动作的json返回值。 |
下面,将用一个helloworld
来详细了解config.json文件
{
// 应用名称: 要求英文格式
"name": "helloworld",
// 应用说明: 必填, 详细说明这个应用是干嘛的
"description": "一个helloworld应用",
// 应用版本
"app_version": "1.0.0",
// 最小的系统版本,这里填写 1.0 即可
"min_shakespeare_version": "1.0",
// 应用提供者: 可以是公司或者名字
"app_supplier": "wuzhi",
// 项目名称
"product_name": "helloworld",
// 应用 logo, 在resources目录下面的logo文件, 等应用上传后会显示在系统内
"logo": "resources/fif.png",
// 应用的readme,应用详细的帮助文档
"read_me": "resources/readme.md",
//运行主程序, 应用的实现代码文件
"jar": "helloworld.py",
// 运行环境, 这里就固定为PYTHON
"logic_language": "PYTHON",
// 语言版本,这里固定为3
"logic_language_version": "3",
// 是否测试, 这里固定为false
"has_test": false,
// 测试的动作, 这里填空即可
"test_action": "",
// 应用使用到的资源, 字段必须存在,但如果没有资源的话,可以使用{}
// 代码中中以assets[$参数名]的方式实现配置获取。如 APP使用mysql,需要配置mysql地址,则参数名为 mysql_host,项目中使用assets["mysql_host"]获取。
"configuration": {
// 字段名可以自定义,这里定义了一个 `host` 资源
// 当定义好资源名后,则需要定义如下字段
"host": {
// 资源是否必填, true 为 必填, flask 为非必填
"required": true,
// 在前端页面的排序,0为最前面
"order": 0,
// 资源的数据类型:
// string 字符串
// integer 整形
// password 密码类型,存储的数据会在数据库中进行加密
// long 长整形
// date 时间类型
// double 浮点型
// boolean 布尔型
// outside_file 上传文件
// json json类型
// jsonarray jsonarray类型
"data_type": "string",
// 此资源的详细说明
"description": "helloworld 演示资源"
}
},
// 应用的动作,是个list[json], 应用最少有一个动作
"actions": [
{
// 动作名称,不能使用中文
"action": "helloworld",
// 动作详细说明
"description": "helloworld 演示动作",
// 动作在代码中的 `函数名`
"class_name": "helloworld",
// 动作的渲染文件, 如果不渲染,可以为 ""
"result_display_tmpt": "shakespeare-action-template/show.art",
// 渲染方式,使用 js 即可
"result_display_tmpt_type": "js",
// 是否安全模式, 当系统以安全模式运行时,所有的write动作将不会真正执行
"safe_mode": false,
// 定义该动作是否是测试动作,如果是true,则在资源配置时可以调用测试,并且系统会定时调用该方法检查资源是否可用。如果不可用,返回结果必须按照以下格式返回:code!=200 or sumarry存在且其中的statusCode存在且!=200
"is_test": false,
// 动作类型
// query 查询
// write 写入
// notify 通知
"classify": "query",
// 入参, 如果没有入参则填写 {}
"parameters": {},
// 出参,是个list[json],每个动作最少一个出参
"output": [
{
// 参数路径必须以 action_result
// 后面的每一层则为返回json 中的 key
// 如果key中的value是个 list,可以用 * 进行返回
// 具体参考 `out_list` 这个动作的 output
"data_path": "action_result.data",
// 动作返回的类型
// string 字符串
// integer 整形
// password 密码类型,存储的数据会在数据库中进行加密
// long 长整形
// date 时间类型
// double 浮点型
// boolean 布尔型
// outside_file 上传文件
// json json类型
// jsonarray jsonarray类型
"data_type": "string",
// 动作的详细说明
"description": "返回值演示"
}
]
},
{
"action": "out_list",
"description": "out list 演示",
"class_name": "query_file",
// 这里将不进行渲染
"result_display_tmpt": "",
"result_display_tmpt_type": "js",
"safe_mode": false,
"is_test": false,
"classify": "query",
"parameters": {
// 字段名可以自定义,这里定义了一个 `file_name` 入参
// 当定义好参数名后,则需要定义如下字段
"file_name": {
// 参数是否必填, true 为 必填, flask 为非必填
"required": true,
// 在前端页面的排序,0为最前面
"order": 0,
// 动作参数的类型
// string 字符串
// integer 整形
// password 密码类型,存储的数据会在数据库中进行加密
// long 长整形
// date 时间类型
// double 浮点型
// boolean 布尔型
// outside_file 上传文件
// json json类型
// jsonarray jsonarray类型
"data_type": "string",
"description": "要查询的文件名字"
}
},
"output": [
{
// 这里的 * 代表一个自循环
// 在运行这个动作后,返回的数据将是一个循环,在剧本中使用这个返回结果后会一条一条的运行
"data_path": "action_result.data.*",
"data_type": "string",
"description": "一个测试 list"
},
{
"data_path": "action_result.data.*.hellowrold",
"data_type": "string",
"description": "一个测试 list"
}
]
}
]
}
{
"code":200,
"data":{
"result":[
{
"ip":"1.2.3.4",
"type":"ipv4"
},
{
"ip":"1.2.3.5",
"type":"ipv4"
}
]
}
}
ip的data_path可以设计为:action_result.data.result.*.ip
为什么这样设计路径:在设计剧本时,如果后续的节点选择ip作为参数,result中有多个对象,执行剧本时系统会自动取得result中所有的ip自动循环执行。
示例代码: helloworld.py
# -*- coding: utf-8 -*-
# 如果需要引入依赖,import xxxx 即可, 但在使用时,此依赖必须在python环境中存在
# helloworld 函数名称, 在config.json 中 actions - class_name 的值,必须一致
# params、assets、context_info 为函数必要的参数,
# params 入参 在config.json 中 actions - parameters 的值,是个字典,同python的字典相同操作方式
# assets 资源 在config.json 中 configuration 的值,是个字典,同python的字典相同操作方式
# context_info 上下文
# context_info["activieId"] 执行链事件ID 字符串
# context_info["appName"] 执行链应用名称 字符串
# context_info["actionName"] 执行链动作名称 字符串
# context_info["eventId"] 执行链事件ID 字符串
# context_info["logMode"] 执行链 日志模型 布尔值
# context_info["executor"] 执行链 执行人 字符串
# context_info["executeTime"] 执行链 执行时间 整型
def helloworld(params, assets, context_info):
"""helloworld 演示动作"""
# helloworld 演示资源
host = assets["host"]
# 返回值
# 返回值中 code、msg是必须的, code 非 200的情况下, 应用运行会报错
json_ret = {"code": 200, "msg": "","data": ""}
'''添加函数实现
'''
json_ret['data'] = "这是一个测试"
return json_ret
def out_list(params, assets, context_info):
"""out list 演示"""
# helloworld 演示资源
host = assets["host"]
# 要查询的文件名字
file_name = params["file_name"]
# 返回值
# 这里的返回值将返回一个list,因为在config.json中我们定义了这个动作返回取的是*
json_ret = {"code": 200, "msg": "","data": [{"hellowrold": ""}]}
'''添加函数实现
'''
json_ret['data'] = [{"hellowrold": "h1"}, {"hellowrold": "h2"}]
return json_ret
渲染模板是一个 art-template
[参考文档](介绍 - art-template (aui.github.io))
以helloworld.art
作为示例,详细的语句可以参考 art-template
<div class="ant-table ant-table-default ant-table-bordered">
<div class="ant-table-content">
<div class="ant-table-body">
<table>
<thead class="ant-table-thead">
<tr>
<th>
<span class="ant-table-header-column">
<div>
<span class="ant-table-column-title">value</span>
<span class="ant-table-column-sorter"></span>
</div>
</span>
</th>
</tr>
</thead>
<tbody class="ant-table-tbody">
<!-- action_results 则是这个动作的所有返回结果 -->
{{each action_results action_result}}
<!-- action_result.data 则是对于这个动作的返回结果,在congfig.json的 actions - action - output 中 对应的字段-->
{{if action_result.data}}
<tr class="ant-table-row">
<td>{{action_result.data}}</td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
</div>
直接将工程目录打包成zip包,确保解压后的结构跟工程目录结构一致。
登录到 OctoMation, 点击应用管理 - 上传应用(右上角)- 选择刚打包后的zip包。
如果上传成功,则会显示
上传成功
的字样
如果应用存在资源, 则需要点击应用 - 切换到资源 - 新建 , 对资源进行配置, 配置完成后点击保存即可。
进入到作战室 - 执行动作 - 选择上传的应用 - 选择要执行的动作 - 配置好参数(如果存在)- 点击立即执行。
为了方便开发人员快速开发应用,我们在 OctoMation 中内置了一个 应用生成器
, 可以用来快速生成应用,
详细使用手册: 应用开发辅助工具
应用生成器
使用视频
dev.mp4
合格的应用APP还包括单元测试代码🧪🧪🧪