背景
云助手可以自动地、批量地执行日常维护命令。通过云助手执行命令目前分为两步,首先创建一个命令,然后执行命令,对于SDK用户来讲,首先调用CreateCommand API,然后调用InvokeCommand API。命令的执行脚本在创建命令阶段设置,在执行命令阶段在ECS实例中执行该脚本。
由于命令的执行内容在创建命令时已经固定,所以如果要执行不同的脚本,哪怕只有细微的区别,都只能创建多条命令,命令无法复用。同时,由于云助手每个用户最多持有100条命令,反复创建命令很容易达到这个限额,用户需要先删除命令才能重新创建命令。
介绍
命令支持自定义参数功能可以有效缓解以上问题,命令可以一次创建,多种执行。创建命令时,在执行脚本中,为参数留出空间,在执行命令时,传入自定义参数的值,即可组合成不同的脚本,使用上非常灵活。
在创建命令时,以某种格式标识参数在脚本中的位置,具体来讲,用“{{}}”对参数进行包裹,花括号内即为参数的名字。在执行命令时,传入相应的参数值,即可产生一条新的命令。举个例子,在创建命令时,脚本设置为
echo {{name}}
在执行命令时,传入参数键值对
{"name":"Jack"}
则“Jack”会取代脚本中{{name}}的位置,形成新的脚本
echo Jack
并在实例中执行。
通过这种方式,用户可以通过合理的创建命令,传入不同的参数值,从而复用执行脚本,命令的维护成本大幅降低。
控制台使用
- 创建命令时,在命令内容部分输入脚本,其中参数用“{{}}”标示,使用参数选择“是”,其余与创建一条普通云助手命令没有区别。
- 执行这条命令,并填入自定义参数的值,如果不填入,会以空字符串代替该参数。
- 以上例子的执行结果如下。
SDK使用
以Java SDK为例展示命令支持自定义参数的使用方法。
通过CreateCommand创建命令
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
IAcsClient client = new DefaultAcsClient(profile);
CreateCommandRequest request = new CreateCommandRequest();
request.setEnableParameter(true);
//"echo {{name}}"的Base64编码
request.setCommandContent("ZWNobyB7e25hbWV9fQ==");
request.setType("RunShellScript");
request.setName("test_enable_parameter");
try {
CreateCommandResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
返回如下
{
"RequestId": "AF0EF4C9-21F9-4106-8A10-F8942318BB4B",
"CommandId": "c-9554c9c281be469b82a56ace39cd6360"
}
再通过InvokeCommand执行该命令
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
IAcsClient client = new DefaultAcsClient(profile);
InvokeCommandRequest request = new InvokeCommandRequest();
request.setCommandId("c-9554c9c281be469b82a56ace39cd6360");
List<String> instanceIdList = new ArrayList<String>();
instanceIdList.add("i-xxxx");
request.setInstanceIds(instanceIdList);
Map parameters = new HashMap();
parameters.put("name", "Jack");
request.setParameters(parameters);
try {
InvokeCommandResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
通过以上步骤,在实例上执行的命令为
echo Jack
执行后通过DescribeInvocationResults可以看到output为Jack。
相关API
云助手命令支持自定义参数的对云助手的API产生如下变更:
- CreateCommand 请求参数
名称 | 类型 | 是否必选 | 示例值 | 描述 |
---|---|---|---|---|
CommandContent | String | 是 | ZWNobyAxMjM= | 命令 Base64 编码后的内容。当您传入请求参数 Type 后,必须同时传入该参数。该参数的值必须使用 Base64 编码后传输,且脚本内容的大小在 Base64 编码之后不能超过 16 KB。如果带有参数,参数用{{}}包含的方式定义,参数个数为0~10个,参数名允许a-zA-Z0-9-_ 的组合,不允许出现其他符号,参数名最多支持64字节。参数名不区分大小写。在{{}}内参数名前后的空格,换行符将被忽略。 |
EnableParameter | Boolean | 否 | false | 创建的命令是否携带自定义参数。默认值:false,表示不在命令中携带自定义参数。 |
- InvokeCommand 请求参数
名称 | 类型 | 是否必选 | 示例值 | 描述 |
---|---|---|---|---|
Parameters | Map | 否 | {"name":"Jack"} | 执行命令时传入的自定义参数的键值对。参数个数的取值范围:0~10。Map的键不允许为空字符串,最多支持64个字符。Map的值允许为空字符串。与CommandContent组合完的命令在Base64编码后,不能超过16KB。 |
Parameters的类型为Map,在此感谢POP同学的支持。原有SDK不支持传递Map,用户需要自行将Map序列化为JSON字符串,传递参数为JSON字符串。POP支持传入Map类型的参数后,用户只需要向Map传递键值对,序列化的工作交由SDK完成。现在已经支持该功能的SDK的语言有Java和Go,其他语言目前还只能通过JSON字符串进行传递,将在六月初完全支持。
- DescribeCommands 返回参数
名称 | 类型 | 示例值 | 描述 |
---|---|---|---|
Commands | 命令数据集类型(CommandSetType) | ||
└ParameterNames | List | ["name","gender"] | 通过CommandContent解析出的自定义参数名列表,以List的形式返回。 |
└EnableParameter | Boolean | false | 该命令是否启用自定义参数。 |
- DescribeInvocations 返回参数
名称 | 类型 | 示例值 | 描述 |
---|---|---|---|
Invocations | 命令执行记录集类(InvocationSetType) | ||
└Parameters | String | {"name":"Jack"} | 以Json字符串的形式,返回本次执行传入的自定义参数。如果该命令禁用了自定义参数功能,则返回空字符串。 |
└CommandContent | String | ZWNobyBKYWNr(echo Jack的Base64形式) | 返回本次执行的脚本,如果启用了自定义参数,则是添加了自定义参数后的脚本 |
应用举例
当一个脚本中有一条命令需要进行文件复制,启用命令支持参数功能后,只需创建一条命令。
cp {{option}} {{source_file}} {{dest_dir}}
在执行命令时,传入参数
{"source_file":"Main.java","dest_dir":"/home"}
即可将Main.java复制到/home目录下。
在执行命令时,传入参数
{"option":"-r","source_file":"/home/dir1","dest_dir":"/home/dir2"}
即可进行目录的拷贝。
而对于以上两种场景,在不采用自定义参数功能时,需要进行两次命令创建
cp Main.java /home
cp -r /home/dir1/home/dir2
命令管理成本很高,使用上很不灵活。
总结
云助手命令支持自定义参数功能可以降低命令的管理成本,用户可以创建更少的命令,更加灵活的执行命令。