regex - 使用正则表达式从 IAM 策略解析 ARN
问题描述
我有以下 IAM 政策:
{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWS":"arn:aws:sts::<account>:assumed-role/custom_role/<role>"},"Action":"sts:AssumeRole","Condition":{"StringEquals":{"sts:ExternalId":"<account>"}}}]}
但该"AWS"
部分也可以是一个数组:
"AWS": [
"arn:aws:sts::<account>:assumed-role/custom_role/<role_1>",
"arn:aws:sts::<account>:assumed-role/custom_role/<role_2>"
]
我需要的是一个正则表达式,它可以解析这两种结构并将列表arn:aws:sts
作为字符串列表返回......我如何在 Golang 中使用正则表达式来实现这一点?我尝试使用但对象结构在和json.Unmarshal
之间不同[]string
string
编辑:
我有以下片段:
re := regexp.MustCompile(`arn:aws:sts::[a-z0-9]*:assumed-role/custom_role/[a-z0-9]-*`)
result := re.FindAll([]byte(arn), 10)
for _, res := range result {
fmt.Println(string(res))
}
>>> `arn:aws:sts::<account_id>:assumed-role/custom_role/`
解决方案
使用 JSON 解码器
您可以将AWS
密钥直接解码为实现“json.Unmarshaler”接口的自定义类型,并正确解码两个输入。
type AWSRoles []string
func (r *AWSRoles) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err == nil {
*r = append(*r, s)
return nil
}
var ss []string
if err := json.Unmarshal(b, &ss); err == nil {
*r = ss
return nil
}
return errors.New("cannot unmarshal neither to a string nor a slice of strings")
}
type AWSPolicy struct {
Statement []struct {
Principal struct {
AWSRoles AWSRoles `json:"AWS"`
} `json:"Principal"`
} `json:"Statement"`
}
这是一个测试
var testsAWSPolicyParsing = []struct {
name string
input []byte
wantRoles []string
}{
{
name: "unique role",
input: []byte(`{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWS":"arn:aws:sts::<account>:assumed-role/custom_role/<role>"},"Action":"sts:AssumeRole","Condition":{"StringEquals":{"sts:ExternalId":"<account>"}}}]}`),
wantRoles: []string{"arn:aws:sts::<account>:assumed-role/custom_role/<role>"},
},
{
name: "multiple roles",
input: []byte(`{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWS":["arn:aws:sts::<account>:assumed-role/custom_role/<role_1>","arn:aws:sts::<account>:assumed-role/custom_role/<role_2>"]},"Action":"sts:AssumeRole","Condition":{"StringEquals":{"sts:ExternalId":"<account>"}}}]}`),
wantRoles: []string{
"arn:aws:sts::<account>:assumed-role/custom_role/<role_1>",
"arn:aws:sts::<account>:assumed-role/custom_role/<role_2>",
},
},
}
func TestParseAWSPolicy(t *testing.T) {
for _, tc := range testsAWSPolicyParsing {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var p AWSPolicy
err := json.Unmarshal(tc.input, &p)
if err != nil {
t.Fatal("unexpected error parsing AWSRoles policy", err)
}
if l := len(p.Statement); l != 1 {
t.Fatalf("unexpected Statement length. want 1, got %d", l)
}
if got := p.Statement[0].Principal.AWSRoles; !reflect.DeepEqual(got, tc.wantRoles) {
t.Fatalf("roles are not the same, got %v, want %v", got, tc.wantRoles)
}
})
}
}
使用正则表达式
如果您仍想使用正则表达式,只要:
- AWS 账户只有数字 [0-9]
- 自定义角色名称只有字母数字字符和下划线
var awsRolesRegex = regexp.MustCompile("arn:aws:sts::[a-z0-9]+:assumed-role/custom_role/[a-zA-Z0-9_]+")
推荐阅读
- python - 如何在 Python 中使用 to_replace 和正则表达式替换数据框中的行名?
- php - Laravel 无法访问共享存储
- javascript - XMLHttpRequest() POST 返回 405 错误;不允许的方法
- java - 将包含多字节字符的字符串拆分为字符串数组
- python - 如何在 python Telegram bot 对话处理程序中循环
- html - 为什么浏览器上不显示图片?
- css - CSS 网格/Flex 调整大小魔术
- java - 转换为 Dame 工作,但捕获不工作......为什么?
- python - Python 错误:request.exceptions.MissingsSchma 错误。尝试解析多个 url 并使用 requests 模块访问
- javascript - 如何让 rangeslider.js 在移动设备上工作?