Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package minio-client for openSUSE:Factory checked in at 2024-10-16 23:54:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/minio-client (Old) and /work/SRC/openSUSE:Factory/.minio-client.new.19354 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "minio-client" Wed Oct 16 23:54:29 2024 rev:98 rq:1208485 version:20241008T093726Z Changes: -------- --- /work/SRC/openSUSE:Factory/minio-client/minio-client.changes 2024-10-03 17:45:02.735900750 +0200 +++ /work/SRC/openSUSE:Factory/.minio-client.new.19354/minio-client.changes 2024-10-16 23:55:02.533725027 +0200 @@ -1,0 +2,8 @@ +Wed Oct 16 15:36:06 UTC 2024 - opensuse_buildserv...@ojkastl.de + +- Update to version 20241008T093726Z: + * Do not fail mc-admin-policy-attach if policy already + attached/detached (#5058) + * Add `mc admin accesskey` commands (#5038) + +------------------------------------------------------------------- Old: ---- minio-client-20241002T082728Z.obscpio New: ---- minio-client-20241008T093726Z.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ minio-client.spec ++++++ --- /var/tmp/diff_new_pack.kg4zvb/_old 2024-10-16 23:55:05.109832463 +0200 +++ /var/tmp/diff_new_pack.kg4zvb/_new 2024-10-16 23:55:05.113832630 +0200 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: minio-client -Version: 20241002T082728Z +Version: 20241008T093726Z Release: 0 Summary: Client for MinIO License: AGPL-3.0-only ++++++ _service ++++++ --- /var/tmp/diff_new_pack.kg4zvb/_old 2024-10-16 23:55:05.149834132 +0200 +++ /var/tmp/diff_new_pack.kg4zvb/_new 2024-10-16 23:55:05.149834132 +0200 @@ -5,7 +5,7 @@ <param name="exclude">.git</param> <param name="changesgenerate">enable</param> <param name="versionformat">@PARENT_TAG@</param> - <param name="revision">RELEASE.2024-10-02T08-27-28Z</param> + <param name="revision">RELEASE.2024-10-08T09-37-26Z</param> <param name="match-tag">RELEASE.*</param> <param name="versionrewrite-pattern">RELEASE\.(.*)-(.*)-(.*)-(.*)-(.*)</param> <param name="versionrewrite-replacement">\1\2\3\4\5</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.kg4zvb/_old 2024-10-16 23:55:05.169834966 +0200 +++ /var/tmp/diff_new_pack.kg4zvb/_new 2024-10-16 23:55:05.173835133 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/minio/mc</param> - <param name="changesrevision">ce0b4341521de16ae2172d42054bbe054f9c9651</param></service></servicedata> + <param name="changesrevision">cf128de2cf42e763e7bd30c6df8b749fa94e0c10</param></service></servicedata> (No newline at EOF) ++++++ minio-client-20241002T082728Z.obscpio -> minio-client-20241008T093726Z.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey-create.go new/minio-client-20241008T093726Z/cmd/admin-accesskey-create.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey-create.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey-create.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,94 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import ( + "github.com/minio/cli" +) + +var adminAccesskeyCreateFlags = []cli.Flag{ + cli.StringFlag{ + Name: "access-key", + Usage: "set an access key for the account", + }, + cli.StringFlag{ + Name: "secret-key", + Usage: "set a secret key for the account", + }, + cli.StringFlag{ + Name: "policy", + Usage: "path to a JSON policy file", + }, + cli.StringFlag{ + Name: "name", + Usage: "friendly name for the account", + }, + cli.StringFlag{ + Name: "description", + Usage: "description for the account", + }, + cli.StringFlag{ + Name: "expiry-duration", + Usage: "duration before the access key expires", + }, + cli.StringFlag{ + Name: "expiry", + Usage: "expiry date for the access key", + }, +} + +var adminAccesskeyCreateCmd = cli.Command{ + Name: "create", + Usage: "create access key pairs for users", + Action: mainAdminAccesskeyCreate, + Before: setGlobalsFromContext, + Flags: append(adminAccesskeyCreateFlags, globalFlags...), + OnUsageError: onUsageError, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] [TARGET] + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Create a new access key pair with the same policy as the authenticated user + {{.Prompt}} {{.HelpName}} myminio/ + + 2. Create a new access key pair with custom access key and secret key + {{.Prompt}} {{.HelpName}} myminio/ --access-key myaccesskey --secret-key mysecretkey + + 3. Create a new access key pair for user 'tester' that expires in 1 day + {{.Prompt}} {{.HelpName}} myminio/ tester --expiry-duration 24h + + 4. Create a new access key pair for authenticated user that expires on 2025-01-01 + {{.Prompt}} {{.HelpName}} --expiry 2025-01-01 + + 5. Create a new access key pair for user 'tester' with a custom policy + {{.Prompt}} {{.HelpName}} myminio/ tester --policy /path/to/policy.json + + 6. Create a new access key pair for user 'tester' with a custom name and description + {{.Prompt}} {{.HelpName}} myminio/ tester --name "Tester's Access Key" --description "Access key for tester" +`, +} + +func mainAdminAccesskeyCreate(ctx *cli.Context) error { + return commonAccesskeyCreate(ctx, false) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey-disable.go new/minio-client-20241008T093726Z/cmd/admin-accesskey-disable.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey-disable.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey-disable.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,48 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import ( + "github.com/minio/cli" +) + +var adminAccesskeyDisableCmd = cli.Command{ + Name: "disable", + Usage: "disable an access key", + Action: mainAdminAccesskeyDisable, + Before: setGlobalsFromContext, + Flags: globalFlags, + OnUsageError: onUsageError, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] [TARGET] + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Disable access key + {{.Prompt}} {{.HelpName}} myminio myaccesskey +`, +} + +func mainAdminAccesskeyDisable(ctx *cli.Context) error { + return enableDisableAccesskey(ctx, false) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey-edit.go new/minio-client-20241008T093726Z/cmd/admin-accesskey-edit.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey-edit.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey-edit.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,77 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import ( + "github.com/minio/cli" +) + +var adminAccesskeyEditFlags = []cli.Flag{ + cli.StringFlag{ + Name: "secret-key", + Usage: "set a secret key for the account", + }, + cli.StringFlag{ + Name: "policy", + Usage: "path to a JSON policy file", + }, + cli.StringFlag{ + Name: "name", + Usage: "friendly name for the account", + }, + cli.StringFlag{ + Name: "description", + Usage: "description for the account", + }, + cli.StringFlag{ + Name: "expiry-duration", + Usage: "duration before the access key expires", + }, + cli.StringFlag{ + Name: "expiry", + Usage: "expiry date for the access key", + }, +} + +var adminAccesskeyEditCmd = cli.Command{ + Name: "edit", + Usage: "edit existing access keys", + Action: mainAdminAccesskeyEdit, + Before: setGlobalsFromContext, + Flags: append(adminAccesskeyEditFlags, globalFlags...), + OnUsageError: onUsageError, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] [TARGET] + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Change the secret key for the access key "testkey" + {{.Prompt}} {{.HelpName}} myminio/ testkey --secret-key 'xxxxxxx' + 2. Change the expiry duration for the access key "testkey" + {{.Prompt}} {{.HelpName}} myminio/ testkey ---expiry-duration 24h +`, +} + +func mainAdminAccesskeyEdit(ctx *cli.Context) error { + return commonAccesskeyEdit(ctx) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey-enable.go new/minio-client-20241008T093726Z/cmd/admin-accesskey-enable.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey-enable.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey-enable.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,48 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import ( + "github.com/minio/cli" +) + +var adminAccesskeyEnableCmd = cli.Command{ + Name: "enable", + Usage: "enable an access key", + Action: mainAdminAccesskeyEnable, + Before: setGlobalsFromContext, + Flags: globalFlags, + OnUsageError: onUsageError, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] [TARGET] + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Enable access key + {{.Prompt}} {{.HelpName}} myminio myaccesskey +`, +} + +func mainAdminAccesskeyEnable(ctx *cli.Context) error { + return enableDisableAccesskey(ctx, true) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey-info.go new/minio-client-20241008T093726Z/cmd/admin-accesskey-info.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey-info.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey-info.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,50 @@ +// Copyright (c) 2015-2023 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import ( + "github.com/minio/cli" +) + +var adminAccesskeyInfoCmd = cli.Command{ + Name: "info", + Usage: "info about given access key pairs", + Action: mainAdminAccesskeyInfo, + Before: setGlobalsFromContext, + Flags: globalFlags, + OnUsageError: onUsageError, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] TARGET ACCESSKEY [ACCESSKEY...] + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Get info for the access key "testkey" + {{.Prompt}} {{.HelpName}} local/ testkey + 2. Get info for the access keys "testkey" and "testkey2" + {{.Prompt}} {{.HelpName}} local/ testkey testkey2 + `, +} + +func mainAdminAccesskeyInfo(ctx *cli.Context) error { + return commonAccesskeyInfo(ctx) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey-list.go new/minio-client-20241008T093726Z/cmd/admin-accesskey-list.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey-list.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey-list.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,168 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import ( + "strings" + + "github.com/charmbracelet/lipgloss" + humanize "github.com/dustin/go-humanize" + "github.com/minio/cli" + json "github.com/minio/colorjson" + "github.com/minio/madmin-go/v3" + "github.com/minio/mc/pkg/probe" +) + +var adminAccesskeyListFlags = []cli.Flag{ + cli.BoolFlag{ + Name: "users-only", + Usage: "only list user DNs", + }, + cli.BoolFlag{ + Name: "temp-only", + Usage: "only list temporary access keys", + }, + cli.BoolFlag{ + Name: "svcacc-only", + Usage: "only list service account access keys", + }, + cli.BoolFlag{ + Name: "self", + Usage: "list access keys for the authenticated user", + }, + cli.BoolFlag{ + Name: "all", + Usage: "list all access keys for all builtin users", + }, +} + +var adminAccesskeyListCmd = cli.Command{ + Name: "list", + ShortName: "ls", + Usage: "list access key pairs for builtin users", + Action: mainAdminAccesskeyList, + Before: setGlobalsFromContext, + Flags: append(adminAccesskeyListFlags, globalFlags...), + OnUsageError: onUsageError, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] TARGET [DN...] + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Get list of all builtin users and associated access keys in local server + {{.Prompt}} {{.HelpName}} local/ --all + + 2. Get list of access keys for the authenticated user in local server + {{.Prompt}} {{.HelpName}} local/ --self + + 3. Get list of builtin users in local server + {{.Prompt}} {{.HelpName}} local/ --all --users-only + + 4. Get list of all builtin users and associated temporary access keys in play server (if admin) + {{.Prompt}} {{.HelpName}} play/ --temp-only + + 5. Get list of access keys associated with user 'foobar' + {{.Prompt}} {{.HelpName}} play/ foobar + + 6. Get list of access keys associated with users 'foobar' and 'tester' + {{.Prompt}} {{.HelpName}} play/ foobar tester + + 7. Get all users and access keys if admin, else get authenticated user and associated access keys + {{.Prompt}} {{.HelpName}} local/ +`, +} + +type userAccesskeyList struct { + Status string `json:"status"` + User string `json:"user"` + STSKeys []madmin.ServiceAccountInfo `json:"stsKeys"` + ServiceAccounts []madmin.ServiceAccountInfo `json:"svcaccs"` + LDAP bool `json:"ldap,omitempty"` +} + +func (m userAccesskeyList) String() string { + labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")) + o := strings.Builder{} + + userStr := "User" + if m.LDAP { + userStr = "DN" + } + o.WriteString(iFmt(0, "%s %s\n", labelStyle.Render(userStr+":"), m.User)) + if len(m.STSKeys) > 0 || len(m.ServiceAccounts) > 0 { + o.WriteString(iFmt(2, "%s\n", labelStyle.Render("Access Keys:"))) + } + for _, k := range m.STSKeys { + expiration := "never" + if nilExpiry(k.Expiration) != nil { + expiration = humanize.Time(*k.Expiration) + } + o.WriteString(iFmt(4, "%s, expires: %s, sts: true\n", k.AccessKey, expiration)) + } + for _, k := range m.ServiceAccounts { + expiration := "never" + if nilExpiry(k.Expiration) != nil { + expiration = humanize.Time(*k.Expiration) + } + o.WriteString(iFmt(4, "%s, expires: %s, sts: false\n", k.AccessKey, expiration)) + } + + return o.String() +} + +func (m userAccesskeyList) JSON() string { + jsonMessageBytes, e := json.MarshalIndent(m, "", " ") + fatalIf(probe.NewError(e), "Unable to marshal into JSON.") + + return string(jsonMessageBytes) +} + +func mainAdminAccesskeyList(ctx *cli.Context) error { + aliasedURL, tentativeAll, users, opts := commonAccesskeyList(ctx) + + // Create a new MinIO Admin Client + client, err := newAdminClient(aliasedURL) + fatalIf(err, "Unable to initialize admin connection.") + + accessKeysMap, e := client.ListAccessKeysBulk(globalContext, users, opts) + if e != nil { + if e.Error() == "Access Denied." && tentativeAll { + // retry with self + opts.All = false + accessKeysMap, e = client.ListAccessKeysBulk(globalContext, users, opts) + } + fatalIf(probe.NewError(e), "Unable to list access keys.") + } + + for user, accessKeys := range accessKeysMap { + m := userAccesskeyList{ + Status: "success", + User: user, + ServiceAccounts: accessKeys.ServiceAccounts, + STSKeys: accessKeys.STSKeys, + LDAP: false, + } + printMsg(m) + } + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey-remove.go new/minio-client-20241008T093726Z/cmd/admin-accesskey-remove.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey-remove.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey-remove.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,49 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import ( + "github.com/minio/cli" +) + +var adminAccesskeyRemoveCmd = cli.Command{ + Name: "remove", + ShortName: "rm", + Usage: "delete access key pairs for builtin users", + Action: mainAdminAccesskeyRemove, + Before: setGlobalsFromContext, + Flags: globalFlags, + OnUsageError: onUsageError, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} [FLAGS] TARGET ACCESSKEY + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Remove the access key "testkey" from local server + {{.Prompt}} {{.HelpName}} local/ testkey + `, +} + +func mainAdminAccesskeyRemove(ctx *cli.Context) error { + return commonAccesskeyRemove(ctx) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-accesskey.go new/minio-client-20241008T093726Z/cmd/admin-accesskey.go --- old/minio-client-20241002T082728Z/cmd/admin-accesskey.go 1970-01-01 01:00:00.000000000 +0100 +++ new/minio-client-20241008T093726Z/cmd/admin-accesskey.go 2024-10-08 11:37:26.000000000 +0200 @@ -0,0 +1,45 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package cmd + +import "github.com/minio/cli" + +var adminAccesskeySubcommands = []cli.Command{ + adminAccesskeyListCmd, + adminAccesskeyRemoveCmd, + adminAccesskeyInfoCmd, + adminAccesskeyCreateCmd, + adminAccesskeyEditCmd, + adminAccesskeyEnableCmd, + adminAccesskeyDisableCmd, +} + +var adminAccesskeyCmd = cli.Command{ + Name: "accesskey", + Usage: "manage access keys defined in the MinIO server", + Action: mainAdminAccesskey, + Before: setGlobalsFromContext, + Flags: globalFlags, + Subcommands: adminAccesskeySubcommands, + HideHelpCommand: true, +} + +func mainAdminAccesskey(ctx *cli.Context) error { + commandNotFound(ctx, adminAccesskeySubcommands) + return nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-main.go new/minio-client-20241008T093726Z/cmd/admin-main.go --- old/minio-client-20241002T082728Z/cmd/admin-main.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/admin-main.go 2024-10-08 11:37:26.000000000 +0200 @@ -56,6 +56,7 @@ adminClusterCmd, adminRebalanceCmd, adminLogsCmd, + adminAccesskeyCmd, } var adminCmd = cli.Command{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/admin-policy-attach.go new/minio-client-20241008T093726Z/cmd/admin-policy-attach.go --- old/minio-client-20241002T082728Z/cmd/admin-policy-attach.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/admin-policy-attach.go 2024-10-08 11:37:26.000000000 +0200 @@ -23,6 +23,10 @@ "github.com/minio/mc/pkg/probe" ) +const ( + errCodeChangeAlreadyApplied = "XMinioAdminPolicyChangeAlreadyApplied" +) + var adminAttachPolicyFlags = []cli.Flag{ cli.StringFlag{ Name: "user, u", @@ -97,7 +101,10 @@ } else { res, e = client.DetachPolicy(globalContext, req) } - fatalIf(probe.NewError(e), "Unable to make user/group policy association") + + if e != nil && madmin.ToErrorResponse(e).Code != errCodeChangeAlreadyApplied { + fatalIf(probe.NewError(e), "Unable to make user/group policy association") + } var emptyResp madmin.PolicyAssociationResp if res.UpdatedAt == emptyResp.UpdatedAt { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/auto-complete.go new/minio-client-20241008T093726Z/cmd/auto-complete.go --- old/minio-client-20241002T082728Z/cmd/auto-complete.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/auto-complete.go 2024-10-08 11:37:26.000000000 +0200 @@ -392,6 +392,16 @@ "/idp/ldap/accesskey/enable": aliasCompleter, "/idp/ldap/accesskey/disable": aliasCompleter, + "/admin/accesskey/create": aliasCompleter, + "/admin/accesskey/list": aliasCompleter, + "/admin/accesskey/ls": aliasCompleter, + "/admin/accesskey/remove": aliasCompleter, + "/admin/accesskey/rm": aliasCompleter, + "/admin/accesskey/info": aliasCompleter, + "/admin/accesskey/edit": aliasCompleter, + "/admin/accesskey/enable": aliasCompleter, + "/admin/accesskey/disable": aliasCompleter, + "/admin/policy/info": aliasCompleter, "/admin/policy/update": aliasCompleter, "/admin/policy/add": aliasCompleter, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-create.go new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-create.go --- old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-create.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-create.go 2024-10-08 11:37:26.000000000 +0200 @@ -98,6 +98,10 @@ } func mainIDPLdapAccesskeyCreate(ctx *cli.Context) error { + return commonAccesskeyCreate(ctx, true) +} + +func commonAccesskeyCreate(ctx *cli.Context, ldap bool) error { if len(ctx.Args()) == 0 || len(ctx.Args()) > 2 { showCommandHelpAndExit(ctx, 1) // last argument is exit code } @@ -114,7 +118,13 @@ client, err := newAdminClient(aliasedURL) fatalIf(err, "Unable to initialize admin connection.") - res, e := client.AddServiceAccountLDAP(globalContext, opts) + var res madmin.Credentials + var e error + if ldap { + res, e = client.AddServiceAccountLDAP(globalContext, opts) + } else { + res, e = client.AddServiceAccount(globalContext, opts) + } fatalIf(probe.NewError(e), "Unable to add service account.") m := ldapAccesskeyMessage{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-edit.go new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-edit.go --- old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-edit.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-edit.go 2024-10-08 11:37:26.000000000 +0200 @@ -82,6 +82,10 @@ } func mainIDPLdapAccesskeyEdit(ctx *cli.Context) error { + return commonAccesskeyEdit(ctx) +} + +func commonAccesskeyEdit(ctx *cli.Context) error { if len(ctx.Args()) == 0 || len(ctx.Args()) > 2 { showCommandHelpAndExit(ctx, 1) // last argument is exit code } @@ -115,6 +119,10 @@ description := ctx.String("description") expDurVal := ctx.Duration("expiry-duration") + if name == "" && expVal == "" && expDurVal == 0 && policyPath == "" && secretKey == "" && description == "" { + fatalIf(probe.NewError(errors.New("At least one property must be edited")), "invalid flags") + } + if expVal != "" && expDurVal != 0 { fatalIf(probe.NewError(errors.New("Only one of --expiry or --expiry-duration can be specified")), "invalid flags") } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-info.go new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-info.go --- old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-info.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-info.go 2024-10-08 11:37:26.000000000 +0200 @@ -120,6 +120,11 @@ } func mainIDPLdapAccesskeyInfo(ctx *cli.Context) error { + return commonAccesskeyInfo(ctx) +} + +// currently no difference between ldap and builtin accesskey info +func commonAccesskeyInfo(ctx *cli.Context) error { if len(ctx.Args()) < 2 { showCommandHelpAndExit(ctx, 1) // last argument is exit code } @@ -151,9 +156,8 @@ Policy: json.RawMessage(tempRes.Policy), Name: tempRes.Name, Description: tempRes.Description, - Expiration: tempRes.Expiration, + Expiration: nilExpiry(tempRes.Expiration), } - printMsg(m) } } else { @@ -167,12 +171,18 @@ Policy: json.RawMessage(res.Policy), Name: res.Name, Description: res.Description, - Expiration: res.Expiration, + Expiration: nilExpiry(res.Expiration), } - printMsg(m) } } return nil } + +func nilExpiry(expiry *time.Time) *time.Time { + if expiry != nil && expiry.Equal(timeSentinel) { + return nil + } + return expiry +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-list.go new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-list.go --- old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-list.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-list.go 2024-10-08 11:37:26.000000000 +0200 @@ -19,12 +19,8 @@ import ( "errors" - "strings" - "github.com/charmbracelet/lipgloss" - "github.com/dustin/go-humanize" "github.com/minio/cli" - json "github.com/minio/colorjson" "github.com/minio/madmin-go/v3" "github.com/minio/mc/pkg/probe" ) @@ -70,10 +66,10 @@ {{range .VisibleFlags}}{{.}} {{end}} EXAMPLES: - 1. Get list of all users and associated access keys in local server (if admin) + 1. Get list of all LDAP users and associated access keys in local server (if admin) {{.Prompt}} {{.HelpName}} local/ - 2. Get list of users in local server (if admin) + 2. Get list of LDAP users in local server (if admin) {{.Prompt}} {{.HelpName}} local/ --users-only 3. Get list of all users and associated temporary access keys in play server (if admin) @@ -93,47 +89,37 @@ `, } -type ldapUsersList struct { - Status string `json:"status"` - DN string `json:"dn"` - STSKeys []madmin.ServiceAccountInfo `json:"stsKeys"` - ServiceAccounts []madmin.ServiceAccountInfo `json:"svcaccs"` -} +func mainIDPLdapAccesskeyList(ctx *cli.Context) error { + aliasedURL, tentativeAll, users, opts := commonAccesskeyList(ctx) + + // Create a new MinIO Admin Client + client, err := newAdminClient(aliasedURL) + fatalIf(err, "Unable to initialize admin connection.") -func (m ldapUsersList) String() string { - labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")) - o := strings.Builder{} - - o.WriteString(iFmt(0, "%s %s\n", labelStyle.Render("DN:"), m.DN)) - if len(m.STSKeys) > 0 || len(m.ServiceAccounts) > 0 { - o.WriteString(iFmt(2, "%s\n", labelStyle.Render("Access Keys:"))) - } - for _, k := range m.STSKeys { - expiration := "never" - if k.Expiration != nil { - expiration = humanize.Time(*k.Expiration) + accessKeysMap, e := client.ListAccessKeysLDAPBulkWithOpts(globalContext, users, opts) + if e != nil { + if e.Error() == "Access Denied." && tentativeAll { + // retry with self + opts.All = false + accessKeysMap, e = client.ListAccessKeysLDAPBulkWithOpts(globalContext, users, opts) } - o.WriteString(iFmt(4, "%s, expires: %s, sts: true\n", k.AccessKey, expiration)) + fatalIf(probe.NewError(e), "Unable to list access keys.") } - for _, k := range m.ServiceAccounts { - expiration := "never" - if k.Expiration != nil { - expiration = humanize.Time(*k.Expiration) + + for dn, accessKeys := range accessKeysMap { + m := userAccesskeyList{ + Status: "success", + User: dn, + ServiceAccounts: accessKeys.ServiceAccounts, + STSKeys: accessKeys.STSKeys, + LDAP: true, } - o.WriteString(iFmt(4, "%s, expires: %s, sts: false\n", k.AccessKey, expiration)) + printMsg(m) } - - return o.String() -} - -func (m ldapUsersList) JSON() string { - jsonMessageBytes, e := json.MarshalIndent(m, "", " ") - fatalIf(probe.NewError(e), "Unable to marshal into JSON.") - - return string(jsonMessageBytes) + return nil } -func mainIDPLdapAccesskeyList(ctx *cli.Context) error { +func commonAccesskeyList(ctx *cli.Context) (aliasedURL string, tentativeAll bool, users []string, opts madmin.ListAccessKeysOpts) { if len(ctx.Args()) == 0 { showCommandHelpAndExit(ctx, 1) // last argument is exit code } @@ -142,18 +128,18 @@ stsOnly := ctx.Bool("temp-only") svcaccOnly := ctx.Bool("svcacc-only") selfFlag := ctx.Bool("self") - allFlag := ctx.Bool("all") + opts.All = ctx.Bool("all") args := ctx.Args() - aliasedURL := args.Get(0) - users := args.Tail() + aliasedURL = args.Get(0) + users = args.Tail() var e error if (usersOnly && svcaccOnly) || (usersOnly && stsOnly) || (svcaccOnly && stsOnly) { e = errors.New("only one of --users-only, --temp-only, or --permanent-only can be specified") - } else if selfFlag && allFlag { + } else if selfFlag && opts.All { e = errors.New("only one of --self or --all can be specified") - } else if (selfFlag || allFlag) && len(users) > 0 { + } else if (selfFlag || opts.All) && len(users) > 0 { e = errors.New("user DNs cannot be specified with --self or --all") } fatalIf(probe.NewError(e), "Invalid flags.") @@ -161,45 +147,21 @@ // If no users/self/all flags are specified, tentatively assume --all // If access is denied on tentativeAll, retry with self // This is to maintain compatibility with the previous behavior - tentativeAll := false - if !selfFlag && !allFlag && len(users) == 0 { + if !selfFlag && !opts.All && len(users) == 0 { tentativeAll = true - allFlag = true + opts.All = true } - var listType string switch { case usersOnly: - listType = madmin.AccessKeyListUsersOnly + opts.ListType = madmin.AccessKeyListUsersOnly case stsOnly: - listType = madmin.AccessKeyListSTSOnly + opts.ListType = madmin.AccessKeyListSTSOnly case svcaccOnly: - listType = madmin.AccessKeyListSvcaccOnly + opts.ListType = madmin.AccessKeyListSvcaccOnly default: - listType = madmin.AccessKeyListAll - } - - // Create a new MinIO Admin Client - client, err := newAdminClient(aliasedURL) - fatalIf(err, "Unable to initialize admin connection.") - - accessKeysMap, e := client.ListAccessKeysLDAPBulk(globalContext, users, listType, allFlag) - if e != nil { - if e.Error() == "Access Denied." && tentativeAll { - // retry with self - accessKeysMap, e = client.ListAccessKeysLDAPBulk(globalContext, users, listType, false) - } - fatalIf(probe.NewError(e), "Unable to list access keys.") + opts.ListType = madmin.AccessKeyListAll } - for dn, accessKeys := range accessKeysMap { - m := ldapUsersList{ - Status: "success", - DN: dn, - ServiceAccounts: accessKeys.ServiceAccounts, - STSKeys: accessKeys.STSKeys, - } - printMsg(m) - } - return nil + return aliasedURL, tentativeAll, users, opts } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-remove.go new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-remove.go --- old/minio-client-20241002T082728Z/cmd/idp-ldap-accesskey-remove.go 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/cmd/idp-ldap-accesskey-remove.go 2024-10-08 11:37:26.000000000 +0200 @@ -46,6 +46,11 @@ } func mainIDPLdapAccesskeyRemove(ctx *cli.Context) error { + return commonAccesskeyRemove(ctx) +} + +// No difference between ldap and builtin accesskey remove for now +func commonAccesskeyRemove(ctx *cli.Context) error { if len(ctx.Args()) != 2 { showCommandHelpAndExit(ctx, 1) // last argument is exit code } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/minio-client-20241002T082728Z/functional-tests.sh new/minio-client-20241008T093726Z/functional-tests.sh --- old/minio-client-20241002T082728Z/functional-tests.sh 2024-10-02 10:27:28.000000000 +0200 +++ new/minio-client-20241008T093726Z/functional-tests.sh 2024-10-08 11:37:26.000000000 +0200 @@ -967,6 +967,9 @@ # check that the user can write objects with readwrite policy assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy attach "$SERVER_ALIAS" readwrite --user="${username}" + # verify that re-attaching an already attached policy to a user does not result in a failure. + assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy attach "$SERVER_ALIAS" readwrite --user="${username}" + # Validate that the correct policy has been added to the user "${MC_CMD[@]}" --json admin user list "${SERVER_ALIAS}" | jq -r '.policyName' | grep --quiet "^readwrite$" rv=$? ++++++ minio-client.obsinfo ++++++ --- /var/tmp/diff_new_pack.kg4zvb/_old 2024-10-16 23:55:05.465847311 +0200 +++ /var/tmp/diff_new_pack.kg4zvb/_new 2024-10-16 23:55:05.469847478 +0200 @@ -1,5 +1,5 @@ name: minio-client -version: 20241002T082728Z -mtime: 1727857648 -commit: ce0b4341521de16ae2172d42054bbe054f9c9651 +version: 20241008T093726Z +mtime: 1728380246 +commit: cf128de2cf42e763e7bd30c6df8b749fa94e0c10 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/minio-client/vendor.tar.gz /work/SRC/openSUSE:Factory/.minio-client.new.19354/vendor.tar.gz differ: char 5, line 1