我正在编写一些Node.js,以基于YAML模板部署AWS CloudFormation堆栈,希望使所有模板通用一个脚本,因此希望解析YAML以检测某些功能,因为这会影响API调用。我有一种方法可以将YAML转换回JSON,然后...
出于这个示例的目的,我想知道是否有任何IAM资源(类型如“ AWS :: IAM :: Role”,“ AWS :: IAM :: Group”),以及这些资源中是否有显式名称。我必须为一个未命名的IAM资源指定功能CAPABILITY_IAM,但是如果有名称,则需要使用CAPABILITY_NAMED_IAM。
当它是对象数组时,我已经使用.map()和.filter()完成了此操作,但是这种格式是对象映射,因此无法使用。我似乎找不到找到类似方法的简单“单线”方法-也许我不知道正确的搜索词?
因此,对于此输入(经过编辑以减少):
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"UnnamedRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"Path": "/"
}
},
"NamedRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "SomeName"
"Path": "/"
}
},
"IrrelevantNonIAMResource": {
"Type": "AWS::Lambda::Function",
"Properties": {
"FunctionName": "SomeFunction"
}
}
}
}
所以,第一个问题-希望获得此输出:
"Resources": {
"UnnamedRole": {
"Type": "AWS::IAM::Role",
"Needs": "CAPABILITY_IAM"
},
"NamedRole": {
"Type": "AWS::IAM::Role",
"Needs": "CAPABILITY_NAMED_IAM"
}
}
额外的信用!! -只需一个字就能回答:
@James要求输入代码-我对此没有任何要求,为什么我在这里。但是,我想得到一种看起来更接近这种风格的东西-我用来在Route53中找到相关域的地方,其中HostedZones是对象数组。上面的资源是一个对象图:
let zones = data.HostedZones.filter(z => z.Config.PrivateZone == false)
.map(z => ({ Id: z.Id.replace('/hostedzone/',''), Name: z.Name}))
.filter(z => z.Name.includes(domainName));
是否有类似的短语法可以在一排长行中完成我想做的事情?
关于涵盖本主题的任何很好的参考。 Node的新手-在2小时的搜索中找不到任何内容。
答案 0 :(得分:0)
好吧,似乎没有doing what you ask的本机方式,因此请像单行语句那样去做,但是(如链接答案中所述)您可以编写自己的objectMap函数。 / p>
另一方面,您可以使用一些实用程序库,例如lodash,这些实用程序库将使用它们的.chain 和 .map个可以迭代对象的函数。
希望这对您有所帮助!
答案 1 :(得分:0)
可以使用reduce
函数来完成操作(顺便说一句,您在"RoleName": "SomeName"
这行有错误,应该以{{1}}结尾)。
,
Object.keys(o.Resources).reduce((acc, v) => {
if (o.Resources[v].Type === "AWS::IAM::Role" && o.Resources[v].Properties.RoleName) {
acc.Resources[v] = { Type: "AWS::IAM::Role", Needs: "CAPABILITY_NAMED_IAM"}
} else if (o.Resources[v].Type === "AWS::IAM::Role") {
acc.Resources[v] = { Type: "AWS::IAM::Role", Needs: "CAPABILITY_IAM" }
}
return acc;
}, { Resources: {}});