@@ -26,8 +26,10 @@ import (
26
26
"io"
27
27
"net/http"
28
28
"os"
29
+ "slices"
29
30
"sort"
30
31
"strconv"
32
+ "strings"
31
33
"time"
32
34
"unicode/utf8"
33
35
@@ -2046,6 +2048,16 @@ func (a adminAPIHandlers) ExportIAM(w http.ResponseWriter, r *http.Request) {
2046
2048
2047
2049
// ImportIAM - imports all IAM info into MinIO
2048
2050
func (a adminAPIHandlers ) ImportIAM (w http.ResponseWriter , r * http.Request ) {
2051
+ a .importIAM (w , r , "" )
2052
+ }
2053
+
2054
+ // ImportIAMV2 - imports all IAM info into MinIO
2055
+ func (a adminAPIHandlers ) ImportIAMV2 (w http.ResponseWriter , r * http.Request ) {
2056
+ a .importIAM (w , r , "v2" )
2057
+ }
2058
+
2059
+ // ImportIAM - imports all IAM info into MinIO
2060
+ func (a adminAPIHandlers ) importIAM (w http.ResponseWriter , r * http.Request , apiVer string ) {
2049
2061
ctx := r .Context ()
2050
2062
2051
2063
// Get current object layer instance.
@@ -2070,6 +2082,10 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2070
2082
writeErrorResponseJSON (ctx , w , errorCodes .ToAPIErr (ErrInvalidRequest ), r .URL )
2071
2083
return
2072
2084
}
2085
+
2086
+ var skipped , removed , added madmin.IAMEntities
2087
+ var failed madmin.IAMErrEntities
2088
+
2073
2089
// import policies first
2074
2090
{
2075
2091
@@ -2095,8 +2111,10 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2095
2111
for policyName , policy := range allPolicies {
2096
2112
if policy .IsEmpty () {
2097
2113
err = globalIAMSys .DeletePolicy (ctx , policyName , true )
2114
+ removed .Policies = append (removed .Policies , policyName )
2098
2115
} else {
2099
2116
_ , err = globalIAMSys .SetPolicy (ctx , policyName , policy )
2117
+ added .Policies = append (added .Policies , policyName )
2100
2118
}
2101
2119
if err != nil {
2102
2120
writeErrorResponseJSON (ctx , w , importError (ctx , err , allPoliciesFile , policyName ), r .URL )
@@ -2175,8 +2193,9 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2175
2193
return
2176
2194
}
2177
2195
if _ , err = globalIAMSys .CreateUser (ctx , accessKey , ureq ); err != nil {
2178
- writeErrorResponseJSON (ctx , w , importErrorWithAPIErr (ctx , toAdminAPIErrCode (ctx , err ), err , allUsersFile , accessKey ), r .URL )
2179
- return
2196
+ failed .Users = append (failed .Users , madmin.IAMErrEntity {Name : accessKey , Error : err })
2197
+ } else {
2198
+ added .Users = append (added .Users , accessKey )
2180
2199
}
2181
2200
2182
2201
}
@@ -2214,8 +2233,9 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2214
2233
}
2215
2234
}
2216
2235
if _ , gerr := globalIAMSys .AddUsersToGroup (ctx , group , grpInfo .Members ); gerr != nil {
2217
- writeErrorResponseJSON (ctx , w , importError (ctx , gerr , allGroupsFile , group ), r .URL )
2218
- return
2236
+ failed .Groups = append (failed .Groups , madmin.IAMErrEntity {Name : group , Error : err })
2237
+ } else {
2238
+ added .Groups = append (added .Groups , group )
2219
2239
}
2220
2240
}
2221
2241
}
@@ -2244,14 +2264,18 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2244
2264
2245
2265
// Validations for LDAP enabled deployments.
2246
2266
if globalIAMSys .LDAPConfig .Enabled () {
2247
- err := globalIAMSys .NormalizeLDAPAccessKeypairs (ctx , serviceAcctReqs )
2267
+ skippedAccessKeys , err := globalIAMSys .NormalizeLDAPAccessKeypairs (ctx , serviceAcctReqs )
2268
+ skipped .ServiceAccounts = append (skipped .ServiceAccounts , skippedAccessKeys ... )
2248
2269
if err != nil {
2249
2270
writeErrorResponseJSON (ctx , w , importError (ctx , err , allSvcAcctsFile , "" ), r .URL )
2250
2271
return
2251
2272
}
2252
2273
}
2253
2274
2254
2275
for user , svcAcctReq := range serviceAcctReqs {
2276
+ if slices .Contains (skipped .ServiceAccounts , user ) {
2277
+ continue
2278
+ }
2255
2279
var sp * policy.Policy
2256
2280
var err error
2257
2281
if len (svcAcctReq .SessionPolicy ) > 0 {
@@ -2309,10 +2333,10 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2309
2333
}
2310
2334
2311
2335
if _ , _ , err = globalIAMSys .NewServiceAccount (ctx , svcAcctReq .Parent , svcAcctReq .Groups , opts ); err != nil {
2312
- writeErrorResponseJSON (ctx , w , importError (ctx , err , allSvcAcctsFile , user ), r .URL )
2313
- return
2336
+ failed .ServiceAccounts = append (failed .ServiceAccounts , madmin.IAMErrEntity {Name : user , Error : err })
2337
+ } else {
2338
+ added .ServiceAccounts = append (added .ServiceAccounts , user )
2314
2339
}
2315
-
2316
2340
}
2317
2341
}
2318
2342
}
@@ -2349,8 +2373,15 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2349
2373
return
2350
2374
}
2351
2375
if _ , err := globalIAMSys .PolicyDBSet (ctx , u , pm .Policies , regUser , false ); err != nil {
2352
- writeErrorResponseJSON (ctx , w , importError (ctx , err , userPolicyMappingsFile , u ), r .URL )
2353
- return
2376
+ failed .UserPolicies = append (
2377
+ failed .UserPolicies ,
2378
+ madmin.IAMErrPolicyEntity {
2379
+ Name : u ,
2380
+ Policies : strings .Split (pm .Policies , "," ),
2381
+ Error : err ,
2382
+ })
2383
+ } else {
2384
+ added .UserPolicies = append (added .UserPolicies , map [string ][]string {u : strings .Split (pm .Policies , "," )})
2354
2385
}
2355
2386
}
2356
2387
}
@@ -2380,17 +2411,28 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2380
2411
// Validations for LDAP enabled deployments.
2381
2412
if globalIAMSys .LDAPConfig .Enabled () {
2382
2413
isGroup := true
2383
- err := globalIAMSys .NormalizeLDAPMappingImport (ctx , isGroup , grpPolicyMap )
2414
+ skippedDN , err := globalIAMSys .NormalizeLDAPMappingImport (ctx , isGroup , grpPolicyMap )
2415
+ skipped .Groups = append (skipped .Groups , skippedDN ... )
2384
2416
if err != nil {
2385
2417
writeErrorResponseJSON (ctx , w , importError (ctx , err , groupPolicyMappingsFile , "" ), r .URL )
2386
2418
return
2387
2419
}
2388
2420
}
2389
2421
2390
2422
for g , pm := range grpPolicyMap {
2423
+ if slices .Contains (skipped .Groups , g ) {
2424
+ continue
2425
+ }
2391
2426
if _ , err := globalIAMSys .PolicyDBSet (ctx , g , pm .Policies , unknownIAMUserType , true ); err != nil {
2392
- writeErrorResponseJSON (ctx , w , importError (ctx , err , groupPolicyMappingsFile , g ), r .URL )
2393
- return
2427
+ failed .GroupPolicies = append (
2428
+ failed .GroupPolicies ,
2429
+ madmin.IAMErrPolicyEntity {
2430
+ Name : g ,
2431
+ Policies : strings .Split (pm .Policies , "," ),
2432
+ Error : err ,
2433
+ })
2434
+ } else {
2435
+ added .GroupPolicies = append (added .GroupPolicies , map [string ][]string {g : strings .Split (pm .Policies , "," )})
2394
2436
}
2395
2437
}
2396
2438
}
@@ -2420,13 +2462,17 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2420
2462
// Validations for LDAP enabled deployments.
2421
2463
if globalIAMSys .LDAPConfig .Enabled () {
2422
2464
isGroup := true
2423
- err := globalIAMSys .NormalizeLDAPMappingImport (ctx , ! isGroup , userPolicyMap )
2465
+ skippedDN , err := globalIAMSys .NormalizeLDAPMappingImport (ctx , ! isGroup , userPolicyMap )
2466
+ skipped .Users = append (skipped .Users , skippedDN ... )
2424
2467
if err != nil {
2425
2468
writeErrorResponseJSON (ctx , w , importError (ctx , err , stsUserPolicyMappingsFile , "" ), r .URL )
2426
2469
return
2427
2470
}
2428
2471
}
2429
2472
for u , pm := range userPolicyMap {
2473
+ if slices .Contains (skipped .Users , u ) {
2474
+ continue
2475
+ }
2430
2476
// disallow setting policy mapping if user is a temporary user
2431
2477
ok , _ , err := globalIAMSys .IsTempUser (u )
2432
2478
if err != nil && err != errNoSuchUser {
@@ -2439,12 +2485,36 @@ func (a adminAPIHandlers) ImportIAM(w http.ResponseWriter, r *http.Request) {
2439
2485
}
2440
2486
2441
2487
if _ , err := globalIAMSys .PolicyDBSet (ctx , u , pm .Policies , stsUser , false ); err != nil {
2442
- writeErrorResponseJSON (ctx , w , importError (ctx , err , stsUserPolicyMappingsFile , u ), r .URL )
2443
- return
2488
+ failed .STSPolicies = append (
2489
+ failed .STSPolicies ,
2490
+ madmin.IAMErrPolicyEntity {
2491
+ Name : u ,
2492
+ Policies : strings .Split (pm .Policies , "," ),
2493
+ Error : err ,
2494
+ })
2495
+ } else {
2496
+ added .STSPolicies = append (added .STSPolicies , map [string ][]string {u : strings .Split (pm .Policies , "," )})
2444
2497
}
2445
2498
}
2446
2499
}
2447
2500
}
2501
+
2502
+ if apiVer == "v2" {
2503
+ iamr := madmin.ImportIAMResult {
2504
+ Skipped : skipped ,
2505
+ Removed : removed ,
2506
+ Added : added ,
2507
+ Failed : failed ,
2508
+ }
2509
+
2510
+ b , err := json .Marshal (iamr )
2511
+ if err != nil {
2512
+ writeErrorResponseJSON (ctx , w , toAdminAPIErr (ctx , err ), r .URL )
2513
+ return
2514
+ }
2515
+
2516
+ writeSuccessResponseJSON (w , b )
2517
+ }
2448
2518
}
2449
2519
2450
2520
func addExpirationToCondValues (exp * time.Time , condValues map [string ][]string ) error {
0 commit comments