|
|
|
@ -2,6 +2,7 @@ package s3tables |
|
|
|
|
|
|
|
import ( |
|
|
|
"context" |
|
|
|
"encoding/json" |
|
|
|
"fmt" |
|
|
|
"net" |
|
|
|
"net/http" |
|
|
|
@ -81,64 +82,13 @@ func TestS3TablesCreateBucketIAMPolicy(t *testing.T) { |
|
|
|
allowedBucket := "tables-allowed" |
|
|
|
deniedBucket := "tables-denied" |
|
|
|
iamConfigDir := t.TempDir() |
|
|
|
iamConfigPath := filepath.Join(iamConfigDir, "iam_config.json") |
|
|
|
iamConfig := fmt.Sprintf(`{ |
|
|
|
"sts": { |
|
|
|
"tokenDuration": "1h", |
|
|
|
"maxSessionLength": "12h", |
|
|
|
"issuer": "seaweedfs-sts", |
|
|
|
"signingKey": "%s" |
|
|
|
}, |
|
|
|
"accounts": [ |
|
|
|
{ |
|
|
|
"id": "%s", |
|
|
|
"displayName": "tables-integration" |
|
|
|
} |
|
|
|
], |
|
|
|
"identities": [ |
|
|
|
{ |
|
|
|
"name": "admin", |
|
|
|
"credentials": [ |
|
|
|
{ |
|
|
|
"accessKey": "%s", |
|
|
|
"secretKey": "%s" |
|
|
|
} |
|
|
|
], |
|
|
|
"account": { |
|
|
|
"id": "%s", |
|
|
|
"displayName": "tables-integration" |
|
|
|
}, |
|
|
|
"policyNames": ["S3TablesBucketPolicy"] |
|
|
|
} |
|
|
|
], |
|
|
|
"policy": { |
|
|
|
"defaultEffect": "Deny", |
|
|
|
"storeType": "memory" |
|
|
|
}, |
|
|
|
"policies": [ |
|
|
|
{ |
|
|
|
"name": "S3TablesBucketPolicy", |
|
|
|
"document": { |
|
|
|
"Version": "2012-10-17", |
|
|
|
"Statement": [ |
|
|
|
{ |
|
|
|
"Effect": "Allow", |
|
|
|
"Action": ["s3tables:CreateTableBucket"], |
|
|
|
"Resource": [ |
|
|
|
"arn:aws:s3tables:%s:%s:bucket/%s", |
|
|
|
"arn:aws:s3:::%s" |
|
|
|
] |
|
|
|
} |
|
|
|
] |
|
|
|
} |
|
|
|
} |
|
|
|
] |
|
|
|
}`, testIAMSigningKey, testAccountID, testAccessKey, testSecretKey, testAccountID, testRegion, testAccountID, allowedBucket, allowedBucket) |
|
|
|
require.NoError(t, os.WriteFile(iamConfigPath, []byte(iamConfig), 0644)) |
|
|
|
s3ConfigPath := writeS3APIConfig(t, iamConfigDir) |
|
|
|
iamConfigPath := writeIAMConfig(t, iamConfigDir, allowedBucket) |
|
|
|
|
|
|
|
cluster, err := startMiniClusterWithExtraArgs(t, []string{ |
|
|
|
"-s3.config=" + iamConfigPath, |
|
|
|
"-s3.config=" + s3ConfigPath, |
|
|
|
"-s3.iam.config=" + iamConfigPath, |
|
|
|
"-s3.iam.readOnly=false", |
|
|
|
}) |
|
|
|
require.NoError(t, err, "failed to start cluster with IAM config") |
|
|
|
defer cluster.Stop() |
|
|
|
@ -796,3 +746,71 @@ func randomString(length int) string { |
|
|
|
} |
|
|
|
return string(b) |
|
|
|
} |
|
|
|
|
|
|
|
func writeIAMConfig(t *testing.T, dir, allowedBucket string) string { |
|
|
|
t.Helper() |
|
|
|
config := map[string]any{ |
|
|
|
"sts": map[string]string{ |
|
|
|
"tokenDuration": "1h", |
|
|
|
"maxSessionLength": "12h", |
|
|
|
"issuer": "seaweedfs-sts", |
|
|
|
"signingKey": testIAMSigningKey, |
|
|
|
}, |
|
|
|
"accounts": []map[string]string{{"id": testAccountID, "displayName": "tables-integration"}}, |
|
|
|
"identities": []map[string]any{ |
|
|
|
{ |
|
|
|
"name": "admin", |
|
|
|
"credentials": []map[string]string{{"accessKey": testAccessKey, "secretKey": testSecretKey}}, |
|
|
|
"account": map[string]string{"id": testAccountID, "displayName": "tables-integration"}, |
|
|
|
"policyNames": []string{"S3TablesBucketPolicy"}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
"policy": map[string]string{ |
|
|
|
"defaultEffect": "Deny", |
|
|
|
"storeType": "memory", |
|
|
|
}, |
|
|
|
"policies": []map[string]any{ |
|
|
|
{ |
|
|
|
"name": "S3TablesBucketPolicy", |
|
|
|
"document": map[string]any{ |
|
|
|
"Version": "2012-10-17", |
|
|
|
"Statement": []map[string]any{ |
|
|
|
{ |
|
|
|
"Effect": "Allow", |
|
|
|
"Action": []string{"s3tables:CreateTableBucket"}, |
|
|
|
"Resource": []string{ |
|
|
|
fmt.Sprintf("arn:aws:s3tables:%s:%s:bucket/%s", testRegion, testAccountID, allowedBucket), |
|
|
|
fmt.Sprintf("arn:aws:s3:::%s", allowedBucket), |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
} |
|
|
|
data, err := json.MarshalIndent(config, "", " ") |
|
|
|
require.NoError(t, err) |
|
|
|
path := filepath.Join(dir, "iam_config.json") |
|
|
|
require.NoError(t, os.WriteFile(path, data, 0644)) |
|
|
|
return path |
|
|
|
} |
|
|
|
|
|
|
|
func writeS3APIConfig(t *testing.T, dir string) string { |
|
|
|
t.Helper() |
|
|
|
config := map[string]any{ |
|
|
|
"identities": []map[string]any{ |
|
|
|
{ |
|
|
|
"name": "admin", |
|
|
|
"credentials": []map[string]string{{"accessKey": testAccessKey, "secretKey": testSecretKey}}, |
|
|
|
"actions": []string{"Admin", "Read", "List", "Tagging", "Write"}, |
|
|
|
"account": map[string]string{"id": testAccountID, "displayName": "tables-integration"}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
"accounts": []map[string]string{{"id": testAccountID, "displayName": "tables-integration"}}, |
|
|
|
} |
|
|
|
data, err := json.MarshalIndent(config, "", " ") |
|
|
|
require.NoError(t, err) |
|
|
|
path := filepath.Join(dir, "s3_config.json") |
|
|
|
require.NoError(t, os.WriteFile(path, data, 0644)) |
|
|
|
return path |
|
|
|
} |