github.com/minio/console@v1.3.0/api/client-admin.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2021 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "bytes" 21 "context" 22 "encoding/json" 23 "io" 24 "net" 25 "net/http" 26 "net/url" 27 "strings" 28 "time" 29 30 "github.com/minio/console/pkg" 31 32 "github.com/minio/console/pkg/utils" 33 34 "github.com/minio/console/models" 35 "github.com/minio/madmin-go/v3" 36 "github.com/minio/minio-go/v7/pkg/credentials" 37 iampolicy "github.com/minio/pkg/v2/policy" 38 ) 39 40 const globalAppName = "MinIO Console" 41 42 // MinioAdmin interface with all functions to be implemented 43 // by mock when testing, it should include all MinioAdmin respective api calls 44 // that are used within this project. 45 type MinioAdmin interface { 46 listUsers(ctx context.Context) (map[string]madmin.UserInfo, error) 47 addUser(ctx context.Context, acessKey, SecretKey string) error 48 removeUser(ctx context.Context, accessKey string) error 49 getUserInfo(ctx context.Context, accessKey string) (madmin.UserInfo, error) 50 setUserStatus(ctx context.Context, accessKey string, status madmin.AccountStatus) error 51 listGroups(ctx context.Context) ([]string, error) 52 updateGroupMembers(ctx context.Context, greq madmin.GroupAddRemove) error 53 getGroupDescription(ctx context.Context, group string) (*madmin.GroupDesc, error) 54 setGroupStatus(ctx context.Context, group string, status madmin.GroupStatus) error 55 listPolicies(ctx context.Context) (map[string]*iampolicy.Policy, error) 56 getPolicy(ctx context.Context, name string) (*iampolicy.Policy, error) 57 removePolicy(ctx context.Context, name string) error 58 addPolicy(ctx context.Context, name string, policy *iampolicy.Policy) error 59 setPolicy(ctx context.Context, policyName, entityName string, isGroup bool) error 60 getConfigKV(ctx context.Context, key string) ([]byte, error) 61 helpConfigKV(ctx context.Context, subSys, key string, envOnly bool) (madmin.Help, error) 62 helpConfigKVGlobal(ctx context.Context, envOnly bool) (madmin.Help, error) 63 setConfigKV(ctx context.Context, kv string) (restart bool, err error) 64 delConfigKV(ctx context.Context, kv string) (err error) 65 serviceRestart(ctx context.Context) error 66 serverInfo(ctx context.Context) (madmin.InfoMessage, error) 67 startProfiling(ctx context.Context, profiler madmin.ProfilerType) ([]madmin.StartProfilingResult, error) 68 stopProfiling(ctx context.Context) (io.ReadCloser, error) 69 serviceTrace(ctx context.Context, threshold int64, s3, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo 70 getLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo 71 AccountInfo(ctx context.Context) (madmin.AccountInfo, error) 72 heal(ctx context.Context, bucket, prefix string, healOpts madmin.HealOpts, clientToken string, 73 forceStart, forceStop bool) (healStart madmin.HealStartSuccess, healTaskStatus madmin.HealTaskStatus, err error) 74 // Service Accounts 75 addServiceAccount(ctx context.Context, policy string, user string, accessKey string, secretKey string, name string, description string, expiry *time.Time, comment string) (madmin.Credentials, error) 76 listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) 77 deleteServiceAccount(ctx context.Context, serviceAccount string) error 78 infoServiceAccount(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error) 79 updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error 80 // Remote Buckets 81 listRemoteBuckets(ctx context.Context, bucket, arnType string) (targets []madmin.BucketTarget, err error) 82 getRemoteBucket(ctx context.Context, bucket, arnType string) (targets *madmin.BucketTarget, err error) 83 removeRemoteBucket(ctx context.Context, bucket, arn string) error 84 addRemoteBucket(ctx context.Context, bucket string, target *madmin.BucketTarget) (string, error) 85 // Account password management 86 changePassword(ctx context.Context, accessKey, secretKey string) error 87 serverHealthInfo(ctx context.Context, healthDataTypes []madmin.HealthDataType, deadline time.Duration) (interface{}, string, error) 88 // List Tiers 89 listTiers(ctx context.Context) ([]*madmin.TierConfig, error) 90 // Tier Info 91 tierStats(ctx context.Context) ([]madmin.TierInfo, error) 92 // Add Tier 93 addTier(ctx context.Context, tier *madmin.TierConfig) error 94 // Edit Tier Credentials 95 editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error 96 // verify Tier status 97 verifyTierStatus(ctx context.Context, tierName string) error 98 // Speedtest 99 speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) 100 // Site Relication 101 getSiteReplicationInfo(ctx context.Context) (*madmin.SiteReplicationInfo, error) 102 addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, opts madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error) 103 editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, opts madmin.SREditOptions) (*madmin.ReplicateEditStatus, error) 104 deleteSiteReplicationInfo(ctx context.Context, removeReq madmin.SRRemoveReq) (*madmin.ReplicateRemoveStatus, error) 105 106 // Replication status 107 getSiteReplicationStatus(ctx context.Context, params madmin.SRStatusOptions) (*madmin.SRStatusInfo, error) 108 109 // KMS 110 kmsStatus(ctx context.Context) (madmin.KMSStatus, error) 111 kmsMetrics(ctx context.Context) (*madmin.KMSMetrics, error) 112 kmsAPIs(ctx context.Context) ([]madmin.KMSAPI, error) 113 kmsVersion(ctx context.Context) (*madmin.KMSVersion, error) 114 createKey(ctx context.Context, key string) error 115 importKey(ctx context.Context, key string, content []byte) error 116 listKeys(ctx context.Context, pattern string) ([]madmin.KMSKeyInfo, error) 117 keyStatus(ctx context.Context, key string) (*madmin.KMSKeyStatus, error) 118 deleteKey(ctx context.Context, key string) error 119 setKMSPolicy(ctx context.Context, policy string, content []byte) error 120 assignPolicy(ctx context.Context, policy string, content []byte) error 121 describePolicy(ctx context.Context, policy string) (*madmin.KMSDescribePolicy, error) 122 getKMSPolicy(ctx context.Context, policy string) (*madmin.KMSPolicy, error) 123 listKMSPolicies(ctx context.Context, pattern string) ([]madmin.KMSPolicyInfo, error) 124 deletePolicy(ctx context.Context, policy string) error 125 describeIdentity(ctx context.Context, identity string) (*madmin.KMSDescribeIdentity, error) 126 describeSelfIdentity(ctx context.Context) (*madmin.KMSDescribeSelfIdentity, error) 127 deleteIdentity(ctx context.Context, identity string) error 128 listIdentities(ctx context.Context, pattern string) ([]madmin.KMSIdentityInfo, error) 129 130 // IDP 131 addOrUpdateIDPConfig(ctx context.Context, idpType, cfgName, cfgData string, update bool) (restart bool, err error) 132 listIDPConfig(ctx context.Context, idpType string) ([]madmin.IDPListItem, error) 133 deleteIDPConfig(ctx context.Context, idpType, cfgName string) (restart bool, err error) 134 getIDPConfig(ctx context.Context, cfgType, cfgName string) (c madmin.IDPConfig, err error) 135 136 // LDAP 137 getLDAPPolicyEntities(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) 138 } 139 140 // Interface implementation 141 // 142 // Define the structure of a minIO Client and define the functions that are actually used 143 // from minIO api. 144 type AdminClient struct { 145 Client *madmin.AdminClient 146 } 147 148 func (ac AdminClient) changePassword(ctx context.Context, accessKey, secretKey string) error { 149 return ac.Client.SetUser(ctx, accessKey, secretKey, madmin.AccountEnabled) 150 } 151 152 // implements madmin.ListUsers() 153 func (ac AdminClient) listUsers(ctx context.Context) (map[string]madmin.UserInfo, error) { 154 return ac.Client.ListUsers(ctx) 155 } 156 157 // implements madmin.AddUser() 158 func (ac AdminClient) addUser(ctx context.Context, accessKey, secretKey string) error { 159 return ac.Client.AddUser(ctx, accessKey, secretKey) 160 } 161 162 // implements madmin.RemoveUser() 163 func (ac AdminClient) removeUser(ctx context.Context, accessKey string) error { 164 return ac.Client.RemoveUser(ctx, accessKey) 165 } 166 167 // implements madmin.GetUserInfo() 168 func (ac AdminClient) getUserInfo(ctx context.Context, accessKey string) (madmin.UserInfo, error) { 169 return ac.Client.GetUserInfo(ctx, accessKey) 170 } 171 172 // implements madmin.SetUserStatus() 173 func (ac AdminClient) setUserStatus(ctx context.Context, accessKey string, status madmin.AccountStatus) error { 174 return ac.Client.SetUserStatus(ctx, accessKey, status) 175 } 176 177 // implements madmin.ListGroups() 178 func (ac AdminClient) listGroups(ctx context.Context) ([]string, error) { 179 return ac.Client.ListGroups(ctx) 180 } 181 182 // implements madmin.UpdateGroupMembers() 183 func (ac AdminClient) updateGroupMembers(ctx context.Context, greq madmin.GroupAddRemove) error { 184 return ac.Client.UpdateGroupMembers(ctx, greq) 185 } 186 187 // implements madmin.GetGroupDescription(group) 188 func (ac AdminClient) getGroupDescription(ctx context.Context, group string) (*madmin.GroupDesc, error) { 189 return ac.Client.GetGroupDescription(ctx, group) 190 } 191 192 // implements madmin.SetGroupStatus(group, status) 193 func (ac AdminClient) setGroupStatus(ctx context.Context, group string, status madmin.GroupStatus) error { 194 return ac.Client.SetGroupStatus(ctx, group, status) 195 } 196 197 // implements madmin.ListCannedPolicies() 198 func (ac AdminClient) listPolicies(ctx context.Context) (map[string]*iampolicy.Policy, error) { 199 policyMap, err := ac.Client.ListCannedPolicies(ctx) 200 if err != nil { 201 return nil, err 202 } 203 policies := make(map[string]*iampolicy.Policy, len(policyMap)) 204 for k, v := range policyMap { 205 p, err := iampolicy.ParseConfig(bytes.NewReader(v)) 206 if err != nil { 207 return nil, err 208 } 209 policies[k] = p 210 } 211 return policies, nil 212 } 213 214 // implements madmin.ListCannedPolicies() 215 func (ac AdminClient) getPolicy(ctx context.Context, name string) (*iampolicy.Policy, error) { 216 praw, err := ac.Client.InfoCannedPolicy(ctx, name) 217 if err != nil { 218 return nil, err 219 } 220 return iampolicy.ParseConfig(bytes.NewReader(praw)) 221 } 222 223 // implements madmin.RemoveCannedPolicy() 224 func (ac AdminClient) removePolicy(ctx context.Context, name string) error { 225 return ac.Client.RemoveCannedPolicy(ctx, name) 226 } 227 228 // implements madmin.AddCannedPolicy() 229 func (ac AdminClient) addPolicy(ctx context.Context, name string, policy *iampolicy.Policy) error { 230 buf, err := json.Marshal(policy) 231 if err != nil { 232 return err 233 } 234 return ac.Client.AddCannedPolicy(ctx, name, buf) 235 } 236 237 // implements madmin.SetPolicy() 238 func (ac AdminClient) setPolicy(ctx context.Context, policyName, entityName string, isGroup bool) error { 239 return ac.Client.SetPolicy(ctx, policyName, entityName, isGroup) 240 } 241 242 // implements madmin.GetConfigKV() 243 func (ac AdminClient) getConfigKV(ctx context.Context, key string) ([]byte, error) { 244 return ac.Client.GetConfigKV(ctx, key) 245 } 246 247 // implements madmin.HelpConfigKV() 248 func (ac AdminClient) helpConfigKV(ctx context.Context, subSys, key string, envOnly bool) (madmin.Help, error) { 249 return ac.Client.HelpConfigKV(ctx, subSys, key, envOnly) 250 } 251 252 // implements madmin.helpConfigKVGlobal() 253 func (ac AdminClient) helpConfigKVGlobal(ctx context.Context, envOnly bool) (madmin.Help, error) { 254 return ac.Client.HelpConfigKV(ctx, "", "", envOnly) 255 } 256 257 // implements madmin.SetConfigKV() 258 func (ac AdminClient) setConfigKV(ctx context.Context, kv string) (restart bool, err error) { 259 return ac.Client.SetConfigKV(ctx, kv) 260 } 261 262 // implements madmin.DelConfigKV() 263 func (ac AdminClient) delConfigKV(ctx context.Context, kv string) (err error) { 264 _, err = ac.Client.DelConfigKV(ctx, kv) 265 return err 266 } 267 268 // implements madmin.ServiceRestart() 269 func (ac AdminClient) serviceRestart(ctx context.Context) (err error) { 270 return ac.Client.ServiceRestart(ctx) 271 } 272 273 // implements madmin.ServerInfo() 274 func (ac AdminClient) serverInfo(ctx context.Context) (madmin.InfoMessage, error) { 275 return ac.Client.ServerInfo(ctx) 276 } 277 278 // implements madmin.StartProfiling() 279 func (ac AdminClient) startProfiling(ctx context.Context, profiler madmin.ProfilerType) ([]madmin.StartProfilingResult, error) { 280 return ac.Client.StartProfiling(ctx, profiler) 281 } 282 283 // implements madmin.DownloadProfilingData() 284 func (ac AdminClient) stopProfiling(ctx context.Context) (io.ReadCloser, error) { 285 return ac.Client.DownloadProfilingData(ctx) 286 } 287 288 // implements madmin.ServiceTrace() 289 func (ac AdminClient) serviceTrace(ctx context.Context, threshold int64, _, internal, storage, os, errTrace bool) <-chan madmin.ServiceTraceInfo { 290 thresholdT := time.Duration(threshold) 291 292 tracingOptions := madmin.ServiceTraceOpts{ 293 S3: true, 294 OnlyErrors: errTrace, 295 Internal: internal, 296 Storage: storage, 297 OS: os, 298 Threshold: thresholdT, 299 } 300 301 return ac.Client.ServiceTrace(ctx, tracingOptions) 302 } 303 304 // implements madmin.GetLogs() 305 func (ac AdminClient) getLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo { 306 return ac.Client.GetLogs(ctx, node, lineCnt, logKind) 307 } 308 309 // implements madmin.AddServiceAccount() 310 func (ac AdminClient) addServiceAccount(ctx context.Context, policy string, user string, accessKey string, secretKey string, name string, description string, expiry *time.Time, comment string) (madmin.Credentials, error) { 311 return ac.Client.AddServiceAccount(ctx, madmin.AddServiceAccountReq{ 312 Policy: []byte(policy), 313 TargetUser: user, 314 AccessKey: accessKey, 315 SecretKey: secretKey, 316 Name: name, 317 Description: description, 318 Expiration: expiry, 319 Comment: comment, 320 }) 321 } 322 323 // implements madmin.ListServiceAccounts() 324 func (ac AdminClient) listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) { 325 return ac.Client.ListServiceAccounts(ctx, user) 326 } 327 328 // implements madmin.DeleteServiceAccount() 329 func (ac AdminClient) deleteServiceAccount(ctx context.Context, serviceAccount string) error { 330 return ac.Client.DeleteServiceAccount(ctx, serviceAccount) 331 } 332 333 // implements madmin.InfoServiceAccount() 334 func (ac AdminClient) infoServiceAccount(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error) { 335 return ac.Client.InfoServiceAccount(ctx, serviceAccount) 336 } 337 338 // implements madmin.UpdateServiceAccount() 339 func (ac AdminClient) updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error { 340 return ac.Client.UpdateServiceAccount(ctx, serviceAccount, opts) 341 } 342 343 // AccountInfo implements madmin.AccountInfo() 344 func (ac AdminClient) AccountInfo(ctx context.Context) (madmin.AccountInfo, error) { 345 return ac.Client.AccountInfo(ctx, madmin.AccountOpts{}) 346 } 347 348 func (ac AdminClient) heal(ctx context.Context, bucket, prefix string, healOpts madmin.HealOpts, clientToken string, 349 forceStart, forceStop bool, 350 ) (healStart madmin.HealStartSuccess, healTaskStatus madmin.HealTaskStatus, err error) { 351 return ac.Client.Heal(ctx, bucket, prefix, healOpts, clientToken, forceStart, forceStop) 352 } 353 354 // listRemoteBuckets - return a list of remote buckets 355 func (ac AdminClient) listRemoteBuckets(ctx context.Context, bucket, arnType string) (targets []madmin.BucketTarget, err error) { 356 return ac.Client.ListRemoteTargets(ctx, bucket, arnType) 357 } 358 359 // getRemoteBucket - gets remote bucked based on a given bucket name 360 func (ac AdminClient) getRemoteBucket(ctx context.Context, bucket, arnType string) (*madmin.BucketTarget, error) { 361 targets, err := ac.Client.ListRemoteTargets(ctx, bucket, arnType) 362 if err != nil { 363 return nil, err 364 } 365 if len(targets) > 0 { 366 return &targets[0], nil 367 } 368 return nil, err 369 } 370 371 // removeRemoteBucket removes a remote target associated with particular ARN for this bucket 372 func (ac AdminClient) removeRemoteBucket(ctx context.Context, bucket, arn string) error { 373 return ac.Client.RemoveRemoteTarget(ctx, bucket, arn) 374 } 375 376 // addRemoteBucket sets up a remote target for this bucket 377 func (ac AdminClient) addRemoteBucket(ctx context.Context, bucket string, target *madmin.BucketTarget) (string, error) { 378 return ac.Client.SetRemoteTarget(ctx, bucket, target) 379 } 380 381 func (ac AdminClient) setBucketQuota(ctx context.Context, bucket string, quota *madmin.BucketQuota) error { 382 return ac.Client.SetBucketQuota(ctx, bucket, quota) 383 } 384 385 func (ac AdminClient) getBucketQuota(ctx context.Context, bucket string) (madmin.BucketQuota, error) { 386 return ac.Client.GetBucketQuota(ctx, bucket) 387 } 388 389 // serverHealthInfo implements mc.ServerHealthInfo - Connect to a minio server and call Health Info Management API 390 func (ac AdminClient) serverHealthInfo(ctx context.Context, healthDataTypes []madmin.HealthDataType, deadline time.Duration) (interface{}, string, error) { 391 info := madmin.HealthInfo{} 392 var healthInfo interface{} 393 var version string 394 var tryCount int 395 for info.Version == "" && tryCount < 10 { 396 resp, version, err := ac.Client.ServerHealthInfo(ctx, healthDataTypes, deadline, "") 397 if err != nil { 398 return nil, version, err 399 } 400 decoder := json.NewDecoder(resp.Body) 401 for { 402 if err = decoder.Decode(&info); err != nil { 403 break 404 } 405 } 406 tryCount++ 407 time.Sleep(2 * time.Second) 408 409 } 410 if info.Version == "" { 411 return nil, "", ErrHealthReportFail 412 } 413 healthInfo = info 414 415 return healthInfo, version, nil 416 } 417 418 // implements madmin.listTiers() 419 func (ac AdminClient) listTiers(ctx context.Context) ([]*madmin.TierConfig, error) { 420 return ac.Client.ListTiers(ctx) 421 } 422 423 // implements madmin.tierStats() 424 func (ac AdminClient) tierStats(ctx context.Context) ([]madmin.TierInfo, error) { 425 return ac.Client.TierStats(ctx) 426 } 427 428 // implements madmin.AddTier() 429 func (ac AdminClient) addTier(ctx context.Context, cfg *madmin.TierConfig) error { 430 return ac.Client.AddTier(ctx, cfg) 431 } 432 433 // implements madmin.Inspect() 434 func (ac AdminClient) inspect(ctx context.Context, insOpts madmin.InspectOptions) ([]byte, io.ReadCloser, error) { 435 return ac.Client.Inspect(ctx, insOpts) 436 } 437 438 // implements madmin.EditTier() 439 func (ac AdminClient) editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error { 440 return ac.Client.EditTier(ctx, tierName, creds) 441 } 442 443 // implements madmin.VerifyTier() 444 func (ac AdminClient) verifyTierStatus(ctx context.Context, tierName string) error { 445 return ac.Client.VerifyTier(ctx, tierName) 446 } 447 448 func NewMinioAdminClient(ctx context.Context, sessionClaims *models.Principal) (*madmin.AdminClient, error) { 449 clientIP := utils.ClientIPFromContext(ctx) 450 adminClient, err := newAdminFromClaims(sessionClaims, clientIP) 451 if err != nil { 452 return nil, err 453 } 454 adminClient.SetAppInfo(globalAppName, pkg.Version) 455 return adminClient, nil 456 } 457 458 // newAdminFromClaims creates a minio admin from Decrypted claims using Assume role credentials 459 func newAdminFromClaims(claims *models.Principal, clientIP string) (*madmin.AdminClient, error) { 460 tlsEnabled := getMinIOEndpointIsSecure() 461 endpoint := getMinIOEndpoint() 462 463 adminClient, err := madmin.NewWithOptions(endpoint, &madmin.Options{ 464 Creds: credentials.NewStaticV4(claims.STSAccessKeyID, claims.STSSecretAccessKey, claims.STSSessionToken), 465 Secure: tlsEnabled, 466 }) 467 if err != nil { 468 return nil, err 469 } 470 adminClient.SetAppInfo(globalAppName, pkg.Version) 471 adminClient.SetCustomTransport(GetConsoleHTTPClient(getMinIOServer(), clientIP).Transport) 472 return adminClient, nil 473 } 474 475 // newAdminFromCreds Creates a minio client using custom credentials for connecting to a remote host 476 func newAdminFromCreds(accessKey, secretKey, endpoint string, tlsEnabled bool) (*madmin.AdminClient, error) { 477 minioClient, err := madmin.NewWithOptions(endpoint, &madmin.Options{ 478 Creds: credentials.NewStaticV4(accessKey, secretKey, ""), 479 Secure: tlsEnabled, 480 }) 481 if err != nil { 482 return nil, err 483 } 484 minioClient.SetAppInfo(globalAppName, pkg.Version) 485 return minioClient, nil 486 } 487 488 // isLocalAddress returns true if the url contains an IPv4/IPv6 hostname 489 // that points to the local machine - FQDN are not supported 490 func isLocalIPEndpoint(addr string) bool { 491 u, err := url.Parse(addr) 492 if err != nil { 493 return false 494 } 495 return isLocalIPAddress(u.Hostname()) 496 } 497 498 // isLocalAddress returns true if the url contains an IPv4/IPv6 hostname 499 // that points to the local machine - FQDN are not supported 500 func isLocalIPAddress(ipAddr string) bool { 501 if ipAddr == "" { 502 return false 503 } 504 ip := net.ParseIP(ipAddr) 505 return ip != nil && ip.IsLoopback() 506 } 507 508 // GetConsoleHTTPClient caches different http clients depending on the target endpoint while taking 509 // in consideration CA certs stored in ${HOME}/.console/certs/CAs and ${HOME}/.minio/certs/CAs 510 // If the target endpoint points to a loopback device, skip the TLS verification. 511 func GetConsoleHTTPClient(address string, clientIP string) *http.Client { 512 u, err := url.Parse(address) 513 if err == nil { 514 address = u.Hostname() 515 } 516 517 client := PrepareConsoleHTTPClient(isLocalIPAddress(address), clientIP) 518 519 return client 520 } 521 522 func getClientIP(r *http.Request) string { 523 // Try to get the IP address from the X-Real-IP header 524 // If the X-Real-IP header is not present, then it will return an empty string 525 xRealIP := r.Header.Get("X-Real-IP") 526 if xRealIP != "" { 527 return xRealIP 528 } 529 530 // Try to get the IP address from the X-Forwarded-For header 531 // If the X-Forwarded-For header is not present, then it will return an empty string 532 xForwardedFor := r.Header.Get("X-Forwarded-For") 533 if xForwardedFor != "" { 534 // X-Forwarded-For can contain multiple addresses, we return the first one 535 split := strings.Split(xForwardedFor, ",") 536 if len(split) > 0 { 537 return strings.TrimSpace(split[0]) 538 } 539 } 540 541 // If neither header is present (or they were empty), then fall back to the connection's remote address 542 ip, _, err := net.SplitHostPort(r.RemoteAddr) 543 if err != nil { 544 // In case there's an error, return an empty string 545 return "" 546 } 547 return ip 548 } 549 550 func (ac AdminClient) speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) { 551 return ac.Client.Speedtest(ctx, opts) 552 } 553 554 // Site Replication 555 func (ac AdminClient) getSiteReplicationInfo(ctx context.Context) (*madmin.SiteReplicationInfo, error) { 556 res, err := ac.Client.SiteReplicationInfo(ctx) 557 if err != nil { 558 return nil, err 559 } 560 return &madmin.SiteReplicationInfo{ 561 Enabled: res.Enabled, 562 Name: res.Name, 563 Sites: res.Sites, 564 ServiceAccountAccessKey: res.ServiceAccountAccessKey, 565 }, nil 566 } 567 568 func (ac AdminClient) addSiteReplicationInfo(ctx context.Context, sites []madmin.PeerSite, opts madmin.SRAddOptions) (*madmin.ReplicateAddStatus, error) { 569 res, err := ac.Client.SiteReplicationAdd(ctx, sites, opts) 570 if err != nil { 571 return nil, err 572 } 573 574 return &madmin.ReplicateAddStatus{ 575 Success: res.Success, 576 Status: res.Status, 577 ErrDetail: res.ErrDetail, 578 InitialSyncErrorMessage: res.InitialSyncErrorMessage, 579 }, nil 580 } 581 582 func (ac AdminClient) editSiteReplicationInfo(ctx context.Context, site madmin.PeerInfo, opts madmin.SREditOptions) (*madmin.ReplicateEditStatus, error) { 583 res, err := ac.Client.SiteReplicationEdit(ctx, site, opts) 584 if err != nil { 585 return nil, err 586 } 587 return &madmin.ReplicateEditStatus{ 588 Success: res.Success, 589 Status: res.Status, 590 ErrDetail: res.ErrDetail, 591 }, nil 592 } 593 594 func (ac AdminClient) deleteSiteReplicationInfo(ctx context.Context, removeReq madmin.SRRemoveReq) (*madmin.ReplicateRemoveStatus, error) { 595 res, err := ac.Client.SiteReplicationRemove(ctx, removeReq) 596 if err != nil { 597 return nil, err 598 } 599 return &madmin.ReplicateRemoveStatus{ 600 Status: res.Status, 601 ErrDetail: res.ErrDetail, 602 }, nil 603 } 604 605 func (ac AdminClient) getSiteReplicationStatus(ctx context.Context, params madmin.SRStatusOptions) (*madmin.SRStatusInfo, error) { 606 res, err := ac.Client.SRStatusInfo(ctx, params) 607 if err != nil { 608 return nil, err 609 } 610 return &res, nil 611 } 612 613 func (ac AdminClient) kmsStatus(ctx context.Context) (madmin.KMSStatus, error) { 614 return ac.Client.KMSStatus(ctx) 615 } 616 617 func (ac AdminClient) kmsMetrics(ctx context.Context) (*madmin.KMSMetrics, error) { 618 return ac.Client.KMSMetrics(ctx) 619 } 620 621 func (ac AdminClient) kmsAPIs(ctx context.Context) ([]madmin.KMSAPI, error) { 622 return ac.Client.KMSAPIs(ctx) 623 } 624 625 func (ac AdminClient) kmsVersion(ctx context.Context) (*madmin.KMSVersion, error) { 626 return ac.Client.KMSVersion(ctx) 627 } 628 629 func (ac AdminClient) createKey(ctx context.Context, key string) error { 630 return ac.Client.CreateKey(ctx, key) 631 } 632 633 func (ac AdminClient) importKey(ctx context.Context, key string, content []byte) error { 634 return ac.Client.ImportKey(ctx, key, content) 635 } 636 637 func (ac AdminClient) listKeys(ctx context.Context, pattern string) ([]madmin.KMSKeyInfo, error) { 638 return ac.Client.ListKeys(ctx, pattern) 639 } 640 641 func (ac AdminClient) keyStatus(ctx context.Context, key string) (*madmin.KMSKeyStatus, error) { 642 return ac.Client.GetKeyStatus(ctx, key) 643 } 644 645 func (ac AdminClient) deleteKey(ctx context.Context, key string) error { 646 return ac.Client.DeleteKey(ctx, key) 647 } 648 649 func (ac AdminClient) setKMSPolicy(ctx context.Context, policy string, content []byte) error { 650 return ac.Client.SetKMSPolicy(ctx, policy, content) 651 } 652 653 func (ac AdminClient) assignPolicy(ctx context.Context, policy string, content []byte) error { 654 return ac.Client.AssignPolicy(ctx, policy, content) 655 } 656 657 func (ac AdminClient) describePolicy(ctx context.Context, policy string) (*madmin.KMSDescribePolicy, error) { 658 return ac.Client.DescribePolicy(ctx, policy) 659 } 660 661 func (ac AdminClient) getKMSPolicy(ctx context.Context, policy string) (*madmin.KMSPolicy, error) { 662 return ac.Client.GetPolicy(ctx, policy) 663 } 664 665 func (ac AdminClient) listKMSPolicies(ctx context.Context, pattern string) ([]madmin.KMSPolicyInfo, error) { 666 return ac.Client.ListPolicies(ctx, pattern) 667 } 668 669 func (ac AdminClient) deletePolicy(ctx context.Context, policy string) error { 670 return ac.Client.DeletePolicy(ctx, policy) 671 } 672 673 func (ac AdminClient) describeIdentity(ctx context.Context, identity string) (*madmin.KMSDescribeIdentity, error) { 674 return ac.Client.DescribeIdentity(ctx, identity) 675 } 676 677 func (ac AdminClient) describeSelfIdentity(ctx context.Context) (*madmin.KMSDescribeSelfIdentity, error) { 678 return ac.Client.DescribeSelfIdentity(ctx) 679 } 680 681 func (ac AdminClient) deleteIdentity(ctx context.Context, identity string) error { 682 return ac.Client.DeleteIdentity(ctx, identity) 683 } 684 685 func (ac AdminClient) listIdentities(ctx context.Context, pattern string) ([]madmin.KMSIdentityInfo, error) { 686 return ac.Client.ListIdentities(ctx, pattern) 687 } 688 689 func (ac AdminClient) addOrUpdateIDPConfig(ctx context.Context, idpType, cfgName, cfgData string, update bool) (restart bool, err error) { 690 return ac.Client.AddOrUpdateIDPConfig(ctx, idpType, cfgName, cfgData, update) 691 } 692 693 func (ac AdminClient) listIDPConfig(ctx context.Context, idpType string) ([]madmin.IDPListItem, error) { 694 return ac.Client.ListIDPConfig(ctx, idpType) 695 } 696 697 func (ac AdminClient) deleteIDPConfig(ctx context.Context, idpType, cfgName string) (restart bool, err error) { 698 return ac.Client.DeleteIDPConfig(ctx, idpType, cfgName) 699 } 700 701 func (ac AdminClient) getIDPConfig(ctx context.Context, idpType, cfgName string) (c madmin.IDPConfig, err error) { 702 return ac.Client.GetIDPConfig(ctx, idpType, cfgName) 703 } 704 705 func (ac AdminClient) getLDAPPolicyEntities(ctx context.Context, query madmin.PolicyEntitiesQuery) (madmin.PolicyEntitiesResult, error) { 706 return ac.Client.GetLDAPPolicyEntities(ctx, query) 707 }