diff --git a/cmd/admin-handlers-idp-config.go b/cmd/admin-handlers-idp-config.go
new file mode 100644
index 000000000..52444da90
--- /dev/null
+++ b/cmd/admin-handlers-idp-config.go
@@ -0,0 +1,321 @@
+// Copyright (c) 2015-2022 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 .
+
+package cmd
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ "github.com/gorilla/mux"
+ "github.com/minio/madmin-go"
+ "github.com/minio/minio-go/v7/pkg/set"
+ "github.com/minio/minio/internal/config"
+ "github.com/minio/minio/internal/config/identity/openid"
+ "github.com/minio/minio/internal/logger"
+ iampolicy "github.com/minio/pkg/iam/policy"
+)
+
+// List of implemented ID config types.
+var idCfgTypes = set.CreateStringSet("openid")
+
+// SetIdentityProviderCfg:
+//
+// PUT /id-cfg?type=openid&name=dex1
+func (a adminAPIHandlers) SetIdentityProviderCfg(w http.ResponseWriter, r *http.Request) {
+ ctx := newContext(r, w, "SetIdentityCfg")
+
+ defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
+
+ objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
+ if objectAPI == nil {
+ return
+ }
+
+ if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 {
+ // More than maxConfigSize bytes were available
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL)
+ return
+ }
+
+ password := cred.SecretKey
+ reqBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
+ if err != nil {
+ logger.LogIf(ctx, err, logger.Application)
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL)
+ return
+ }
+
+ cfgType := mux.Vars(r)["type"]
+ if !idCfgTypes.Contains(cfgType) {
+ // TODO: change this to invalid type error when implementation
+ // is complete.
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
+ return
+ }
+
+ var cfgDataBuilder strings.Builder
+ switch cfgType {
+ case "openid":
+ fmt.Fprintf(&cfgDataBuilder, "identity_openid")
+ }
+
+ // Ensure body content type is opaque.
+ contentType := r.Header.Get("Content-Type")
+ if contentType != "application/octet-stream" {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrBadRequest), r.URL)
+ return
+ }
+
+ // Subsystem configuration name could be empty.
+ cfgName := mux.Vars(r)["name"]
+ if cfgName != "" {
+ fmt.Fprintf(&cfgDataBuilder, "%s%s", config.SubSystemSeparator, cfgName)
+ }
+
+ fmt.Fprintf(&cfgDataBuilder, "%s%s", config.KvSpaceSeparator, string(reqBytes))
+
+ cfgData := cfgDataBuilder.String()
+ subSys, _, _, err := config.GetSubSys(cfgData)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ cfg, err := readServerConfig(ctx, objectAPI)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ dynamic, err := cfg.ReadConfig(strings.NewReader(cfgData))
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ // IDP config is not dynamic. Sanity check.
+ if dynamic {
+ writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL)
+ return
+ }
+
+ if err = validateConfig(cfg, subSys); err != nil {
+ writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
+ return
+ }
+
+ // Update the actual server config on disk.
+ if err = saveServerConfig(ctx, objectAPI, cfg); err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ // Write to the config input KV to history.
+ if err = saveServerConfigHistory(ctx, objectAPI, []byte(cfgData)); err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ writeSuccessResponseHeadersOnly(w)
+}
+
+// GetIdentityProviderCfg:
+//
+// GET /id-cfg?type=openid&name=dex_test
+//
+// GetIdentityProviderCfg returns a list of configured IDPs on the server if
+// name is empty. If name is non-empty, returns the configuration details for
+// the IDP of the given type and configuration name. The configuration name for
+// the default ("un-named") configuration target is `_`.
+func (a adminAPIHandlers) GetIdentityProviderCfg(w http.ResponseWriter, r *http.Request) {
+ ctx := newContext(r, w, "GetIdentityProviderCfg")
+
+ defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
+
+ objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
+ if objectAPI == nil {
+ return
+ }
+
+ cfgType := mux.Vars(r)["type"]
+ cfgName := r.Form.Get("name")
+ password := cred.SecretKey
+
+ if !idCfgTypes.Contains(cfgType) {
+ // TODO: change this to invalid type error when implementation
+ // is complete.
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
+ return
+ }
+
+ // If no cfgName is provided, we list.
+ if cfgName == "" {
+ a.listIdentityProviders(ctx, w, r, cfgType, password)
+ return
+ }
+
+ cfg := globalServerConfig.Clone()
+
+ cfgInfos, err := globalOpenIDConfig.GetConfigInfo(cfg, cfgName)
+ if err != nil {
+ if err == openid.ErrProviderConfigNotFound {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminNoSuchConfigTarget), r.URL)
+ return
+ }
+
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ res := madmin.IDPConfig{
+ Type: cfgType,
+ Name: cfgName,
+ Info: cfgInfos,
+ }
+ data, err := json.Marshal(res)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ econfigData, err := madmin.EncryptData(password, data)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ writeSuccessResponseJSON(w, econfigData)
+}
+
+func (a adminAPIHandlers) listIdentityProviders(ctx context.Context, w http.ResponseWriter, r *http.Request, cfgType, password string) {
+ // var subSys string
+ switch cfgType {
+ case "openid":
+ // subSys = config.IdentityOpenIDSubSys
+ default:
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
+ return
+ }
+
+ cfg := globalServerConfig.Clone()
+ cfgList, err := globalOpenIDConfig.GetConfigList(cfg)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ data, err := json.Marshal(cfgList)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ econfigData, err := madmin.EncryptData(password, data)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ writeSuccessResponseJSON(w, econfigData)
+}
+
+// DeleteIdentityProviderCfg:
+//
+// DELETE /id-cfg?type=openid&name=dex_test
+func (a adminAPIHandlers) DeleteIdentityProviderCfg(w http.ResponseWriter, r *http.Request) {
+ ctx := newContext(r, w, "DeleteIdentityProviderCfg")
+
+ defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
+
+ objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
+ if objectAPI == nil {
+ return
+ }
+
+ cfgType := mux.Vars(r)["type"]
+ cfgName := mux.Vars(r)["name"]
+ if !idCfgTypes.Contains(cfgType) {
+ // TODO: change this to invalid type error when implementation
+ // is complete.
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
+ return
+ }
+
+ cfg := globalServerConfig.Clone()
+
+ cfgInfos, err := globalOpenIDConfig.GetConfigInfo(cfg, cfgName)
+ if err != nil {
+ if err == openid.ErrProviderConfigNotFound {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminNoSuchConfigTarget), r.URL)
+ return
+ }
+
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ hasEnv := false
+ for _, ci := range cfgInfos {
+ if ci.IsCfg && ci.IsEnv {
+ hasEnv = true
+ break
+ }
+ }
+
+ if hasEnv {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigEnvOverridden), r.URL)
+ return
+ }
+
+ var subSys string
+ switch cfgType {
+ case "openid":
+ subSys = config.IdentityOpenIDSubSys
+ default:
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
+ return
+ }
+
+ cfg, err = readServerConfig(ctx, objectAPI)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ if err = cfg.DelKVS(fmt.Sprintf("%s:%s", subSys, cfgName)); err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+ if err = validateConfig(cfg, subSys); err != nil {
+ writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
+ return
+ }
+ if err = saveServerConfig(ctx, objectAPI, cfg); err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ dynamic := config.SubSystemsDynamic.Contains(subSys)
+ if dynamic {
+ applyDynamic(ctx, objectAPI, cfg, subSys, r, w)
+ }
+}
diff --git a/cmd/admin-router.go b/cmd/admin-router.go
index 2e9a96897..d1a633e1c 100644
--- a/cmd/admin-router.go
+++ b/cmd/admin-router.go
@@ -178,6 +178,13 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
// Import IAM info
adminRouter.Methods(http.MethodPut).Path(adminVersion + "/import-iam").HandlerFunc(httpTraceHdrs(adminAPI.ImportIAM))
+ // IDentity Provider configuration APIs
+ adminRouter.Methods(http.MethodPut).Path(adminVersion+"/idp-config").HandlerFunc(gz(httpTraceHdrs(adminAPI.SetIdentityProviderCfg))).Queries("type", "{type:.*}").Queries("name", "{name:.*}")
+ adminRouter.Methods(http.MethodGet).Path(adminVersion+"/idp-config").HandlerFunc(gz(httpTraceHdrs(adminAPI.GetIdentityProviderCfg))).Queries("type", "{type:.*}")
+ adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/idp-config").HandlerFunc(gz(httpTraceHdrs(adminAPI.DeleteIdentityProviderCfg))).Queries("type", "{type:.*}").Queries("name", "{name:.*}")
+
+ // -- END IAM APIs --
+
// GetBucketQuotaConfig
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-bucket-quota").HandlerFunc(
gz(httpTraceHdrs(adminAPI.GetBucketQuotaConfigHandler))).Queries("bucket", "{bucket:.*}")
diff --git a/cmd/api-errors.go b/cmd/api-errors.go
index b02fa0b73..ae4dacf51 100644
--- a/cmd/api-errors.go
+++ b/cmd/api-errors.go
@@ -267,6 +267,8 @@ const (
ErrAdminConfigNoQuorum
ErrAdminConfigTooLarge
ErrAdminConfigBadJSON
+ ErrAdminNoSuchConfigTarget
+ ErrAdminConfigEnvOverridden
ErrAdminConfigDuplicateKeys
ErrAdminCredentialsMismatch
ErrInsecureClientRequest
@@ -1240,11 +1242,21 @@ var errorCodes = errorCodeMap{
maxEConfigJSONSize),
HTTPStatusCode: http.StatusBadRequest,
},
+ ErrAdminNoSuchConfigTarget: {
+ Code: "XMinioAdminNoSuchConfigTarget",
+ Description: "No such named configuration target exists",
+ HTTPStatusCode: http.StatusBadRequest,
+ },
ErrAdminConfigBadJSON: {
Code: "XMinioAdminConfigBadJSON",
Description: "JSON configuration provided is of incorrect format",
HTTPStatusCode: http.StatusBadRequest,
},
+ ErrAdminConfigEnvOverridden: {
+ Code: "XMinioAdminConfigEnvOverridden",
+ Description: "Unable to update config via Admin API due to environment variable override",
+ HTTPStatusCode: http.StatusBadRequest,
+ },
ErrAdminConfigDuplicateKeys: {
Code: "XMinioAdminConfigDuplicateKeys",
Description: "JSON configuration provided has objects with duplicate keys",
diff --git a/cmd/apierrorcode_string.go b/cmd/apierrorcode_string.go
index f5cfefd2c..4552d751f 100644
--- a/cmd/apierrorcode_string.go
+++ b/cmd/apierrorcode_string.go
@@ -183,125 +183,127 @@ func _() {
_ = x[ErrAdminConfigNoQuorum-172]
_ = x[ErrAdminConfigTooLarge-173]
_ = x[ErrAdminConfigBadJSON-174]
- _ = x[ErrAdminConfigDuplicateKeys-175]
- _ = x[ErrAdminCredentialsMismatch-176]
- _ = x[ErrInsecureClientRequest-177]
- _ = x[ErrObjectTampered-178]
- _ = x[ErrSiteReplicationInvalidRequest-179]
- _ = x[ErrSiteReplicationPeerResp-180]
- _ = x[ErrSiteReplicationBackendIssue-181]
- _ = x[ErrSiteReplicationServiceAccountError-182]
- _ = x[ErrSiteReplicationBucketConfigError-183]
- _ = x[ErrSiteReplicationBucketMetaError-184]
- _ = x[ErrSiteReplicationIAMError-185]
- _ = x[ErrSiteReplicationConfigMissing-186]
- _ = x[ErrAdminBucketQuotaExceeded-187]
- _ = x[ErrAdminNoSuchQuotaConfiguration-188]
- _ = x[ErrHealNotImplemented-189]
- _ = x[ErrHealNoSuchProcess-190]
- _ = x[ErrHealInvalidClientToken-191]
- _ = x[ErrHealMissingBucket-192]
- _ = x[ErrHealAlreadyRunning-193]
- _ = x[ErrHealOverlappingPaths-194]
- _ = x[ErrIncorrectContinuationToken-195]
- _ = x[ErrEmptyRequestBody-196]
- _ = x[ErrUnsupportedFunction-197]
- _ = x[ErrInvalidExpressionType-198]
- _ = x[ErrBusy-199]
- _ = x[ErrUnauthorizedAccess-200]
- _ = x[ErrExpressionTooLong-201]
- _ = x[ErrIllegalSQLFunctionArgument-202]
- _ = x[ErrInvalidKeyPath-203]
- _ = x[ErrInvalidCompressionFormat-204]
- _ = x[ErrInvalidFileHeaderInfo-205]
- _ = x[ErrInvalidJSONType-206]
- _ = x[ErrInvalidQuoteFields-207]
- _ = x[ErrInvalidRequestParameter-208]
- _ = x[ErrInvalidDataType-209]
- _ = x[ErrInvalidTextEncoding-210]
- _ = x[ErrInvalidDataSource-211]
- _ = x[ErrInvalidTableAlias-212]
- _ = x[ErrMissingRequiredParameter-213]
- _ = x[ErrObjectSerializationConflict-214]
- _ = x[ErrUnsupportedSQLOperation-215]
- _ = x[ErrUnsupportedSQLStructure-216]
- _ = x[ErrUnsupportedSyntax-217]
- _ = x[ErrUnsupportedRangeHeader-218]
- _ = x[ErrLexerInvalidChar-219]
- _ = x[ErrLexerInvalidOperator-220]
- _ = x[ErrLexerInvalidLiteral-221]
- _ = x[ErrLexerInvalidIONLiteral-222]
- _ = x[ErrParseExpectedDatePart-223]
- _ = x[ErrParseExpectedKeyword-224]
- _ = x[ErrParseExpectedTokenType-225]
- _ = x[ErrParseExpected2TokenTypes-226]
- _ = x[ErrParseExpectedNumber-227]
- _ = x[ErrParseExpectedRightParenBuiltinFunctionCall-228]
- _ = x[ErrParseExpectedTypeName-229]
- _ = x[ErrParseExpectedWhenClause-230]
- _ = x[ErrParseUnsupportedToken-231]
- _ = x[ErrParseUnsupportedLiteralsGroupBy-232]
- _ = x[ErrParseExpectedMember-233]
- _ = x[ErrParseUnsupportedSelect-234]
- _ = x[ErrParseUnsupportedCase-235]
- _ = x[ErrParseUnsupportedCaseClause-236]
- _ = x[ErrParseUnsupportedAlias-237]
- _ = x[ErrParseUnsupportedSyntax-238]
- _ = x[ErrParseUnknownOperator-239]
- _ = x[ErrParseMissingIdentAfterAt-240]
- _ = x[ErrParseUnexpectedOperator-241]
- _ = x[ErrParseUnexpectedTerm-242]
- _ = x[ErrParseUnexpectedToken-243]
- _ = x[ErrParseUnexpectedKeyword-244]
- _ = x[ErrParseExpectedExpression-245]
- _ = x[ErrParseExpectedLeftParenAfterCast-246]
- _ = x[ErrParseExpectedLeftParenValueConstructor-247]
- _ = x[ErrParseExpectedLeftParenBuiltinFunctionCall-248]
- _ = x[ErrParseExpectedArgumentDelimiter-249]
- _ = x[ErrParseCastArity-250]
- _ = x[ErrParseInvalidTypeParam-251]
- _ = x[ErrParseEmptySelect-252]
- _ = x[ErrParseSelectMissingFrom-253]
- _ = x[ErrParseExpectedIdentForGroupName-254]
- _ = x[ErrParseExpectedIdentForAlias-255]
- _ = x[ErrParseUnsupportedCallWithStar-256]
- _ = x[ErrParseNonUnaryAgregateFunctionCall-257]
- _ = x[ErrParseMalformedJoin-258]
- _ = x[ErrParseExpectedIdentForAt-259]
- _ = x[ErrParseAsteriskIsNotAloneInSelectList-260]
- _ = x[ErrParseCannotMixSqbAndWildcardInSelectList-261]
- _ = x[ErrParseInvalidContextForWildcardInSelectList-262]
- _ = x[ErrIncorrectSQLFunctionArgumentType-263]
- _ = x[ErrValueParseFailure-264]
- _ = x[ErrEvaluatorInvalidArguments-265]
- _ = x[ErrIntegerOverflow-266]
- _ = x[ErrLikeInvalidInputs-267]
- _ = x[ErrCastFailed-268]
- _ = x[ErrInvalidCast-269]
- _ = x[ErrEvaluatorInvalidTimestampFormatPattern-270]
- _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbolForParsing-271]
- _ = x[ErrEvaluatorTimestampFormatPatternDuplicateFields-272]
- _ = x[ErrEvaluatorTimestampFormatPatternHourClockAmPmMismatch-273]
- _ = x[ErrEvaluatorUnterminatedTimestampFormatPatternToken-274]
- _ = x[ErrEvaluatorInvalidTimestampFormatPatternToken-275]
- _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbol-276]
- _ = x[ErrEvaluatorBindingDoesNotExist-277]
- _ = x[ErrMissingHeaders-278]
- _ = x[ErrInvalidColumnIndex-279]
- _ = x[ErrAdminConfigNotificationTargetsFailed-280]
- _ = x[ErrAdminProfilerNotEnabled-281]
- _ = x[ErrInvalidDecompressedSize-282]
- _ = x[ErrAddUserInvalidArgument-283]
- _ = x[ErrAdminResourceInvalidArgument-284]
- _ = x[ErrAdminAccountNotEligible-285]
- _ = x[ErrAccountNotEligible-286]
- _ = x[ErrAdminServiceAccountNotFound-287]
- _ = x[ErrPostPolicyConditionInvalidFormat-288]
+ _ = x[ErrAdminNoSuchConfigTarget-175]
+ _ = x[ErrAdminConfigEnvOverridden-176]
+ _ = x[ErrAdminConfigDuplicateKeys-177]
+ _ = x[ErrAdminCredentialsMismatch-178]
+ _ = x[ErrInsecureClientRequest-179]
+ _ = x[ErrObjectTampered-180]
+ _ = x[ErrSiteReplicationInvalidRequest-181]
+ _ = x[ErrSiteReplicationPeerResp-182]
+ _ = x[ErrSiteReplicationBackendIssue-183]
+ _ = x[ErrSiteReplicationServiceAccountError-184]
+ _ = x[ErrSiteReplicationBucketConfigError-185]
+ _ = x[ErrSiteReplicationBucketMetaError-186]
+ _ = x[ErrSiteReplicationIAMError-187]
+ _ = x[ErrSiteReplicationConfigMissing-188]
+ _ = x[ErrAdminBucketQuotaExceeded-189]
+ _ = x[ErrAdminNoSuchQuotaConfiguration-190]
+ _ = x[ErrHealNotImplemented-191]
+ _ = x[ErrHealNoSuchProcess-192]
+ _ = x[ErrHealInvalidClientToken-193]
+ _ = x[ErrHealMissingBucket-194]
+ _ = x[ErrHealAlreadyRunning-195]
+ _ = x[ErrHealOverlappingPaths-196]
+ _ = x[ErrIncorrectContinuationToken-197]
+ _ = x[ErrEmptyRequestBody-198]
+ _ = x[ErrUnsupportedFunction-199]
+ _ = x[ErrInvalidExpressionType-200]
+ _ = x[ErrBusy-201]
+ _ = x[ErrUnauthorizedAccess-202]
+ _ = x[ErrExpressionTooLong-203]
+ _ = x[ErrIllegalSQLFunctionArgument-204]
+ _ = x[ErrInvalidKeyPath-205]
+ _ = x[ErrInvalidCompressionFormat-206]
+ _ = x[ErrInvalidFileHeaderInfo-207]
+ _ = x[ErrInvalidJSONType-208]
+ _ = x[ErrInvalidQuoteFields-209]
+ _ = x[ErrInvalidRequestParameter-210]
+ _ = x[ErrInvalidDataType-211]
+ _ = x[ErrInvalidTextEncoding-212]
+ _ = x[ErrInvalidDataSource-213]
+ _ = x[ErrInvalidTableAlias-214]
+ _ = x[ErrMissingRequiredParameter-215]
+ _ = x[ErrObjectSerializationConflict-216]
+ _ = x[ErrUnsupportedSQLOperation-217]
+ _ = x[ErrUnsupportedSQLStructure-218]
+ _ = x[ErrUnsupportedSyntax-219]
+ _ = x[ErrUnsupportedRangeHeader-220]
+ _ = x[ErrLexerInvalidChar-221]
+ _ = x[ErrLexerInvalidOperator-222]
+ _ = x[ErrLexerInvalidLiteral-223]
+ _ = x[ErrLexerInvalidIONLiteral-224]
+ _ = x[ErrParseExpectedDatePart-225]
+ _ = x[ErrParseExpectedKeyword-226]
+ _ = x[ErrParseExpectedTokenType-227]
+ _ = x[ErrParseExpected2TokenTypes-228]
+ _ = x[ErrParseExpectedNumber-229]
+ _ = x[ErrParseExpectedRightParenBuiltinFunctionCall-230]
+ _ = x[ErrParseExpectedTypeName-231]
+ _ = x[ErrParseExpectedWhenClause-232]
+ _ = x[ErrParseUnsupportedToken-233]
+ _ = x[ErrParseUnsupportedLiteralsGroupBy-234]
+ _ = x[ErrParseExpectedMember-235]
+ _ = x[ErrParseUnsupportedSelect-236]
+ _ = x[ErrParseUnsupportedCase-237]
+ _ = x[ErrParseUnsupportedCaseClause-238]
+ _ = x[ErrParseUnsupportedAlias-239]
+ _ = x[ErrParseUnsupportedSyntax-240]
+ _ = x[ErrParseUnknownOperator-241]
+ _ = x[ErrParseMissingIdentAfterAt-242]
+ _ = x[ErrParseUnexpectedOperator-243]
+ _ = x[ErrParseUnexpectedTerm-244]
+ _ = x[ErrParseUnexpectedToken-245]
+ _ = x[ErrParseUnexpectedKeyword-246]
+ _ = x[ErrParseExpectedExpression-247]
+ _ = x[ErrParseExpectedLeftParenAfterCast-248]
+ _ = x[ErrParseExpectedLeftParenValueConstructor-249]
+ _ = x[ErrParseExpectedLeftParenBuiltinFunctionCall-250]
+ _ = x[ErrParseExpectedArgumentDelimiter-251]
+ _ = x[ErrParseCastArity-252]
+ _ = x[ErrParseInvalidTypeParam-253]
+ _ = x[ErrParseEmptySelect-254]
+ _ = x[ErrParseSelectMissingFrom-255]
+ _ = x[ErrParseExpectedIdentForGroupName-256]
+ _ = x[ErrParseExpectedIdentForAlias-257]
+ _ = x[ErrParseUnsupportedCallWithStar-258]
+ _ = x[ErrParseNonUnaryAgregateFunctionCall-259]
+ _ = x[ErrParseMalformedJoin-260]
+ _ = x[ErrParseExpectedIdentForAt-261]
+ _ = x[ErrParseAsteriskIsNotAloneInSelectList-262]
+ _ = x[ErrParseCannotMixSqbAndWildcardInSelectList-263]
+ _ = x[ErrParseInvalidContextForWildcardInSelectList-264]
+ _ = x[ErrIncorrectSQLFunctionArgumentType-265]
+ _ = x[ErrValueParseFailure-266]
+ _ = x[ErrEvaluatorInvalidArguments-267]
+ _ = x[ErrIntegerOverflow-268]
+ _ = x[ErrLikeInvalidInputs-269]
+ _ = x[ErrCastFailed-270]
+ _ = x[ErrInvalidCast-271]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPattern-272]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbolForParsing-273]
+ _ = x[ErrEvaluatorTimestampFormatPatternDuplicateFields-274]
+ _ = x[ErrEvaluatorTimestampFormatPatternHourClockAmPmMismatch-275]
+ _ = x[ErrEvaluatorUnterminatedTimestampFormatPatternToken-276]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPatternToken-277]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbol-278]
+ _ = x[ErrEvaluatorBindingDoesNotExist-279]
+ _ = x[ErrMissingHeaders-280]
+ _ = x[ErrInvalidColumnIndex-281]
+ _ = x[ErrAdminConfigNotificationTargetsFailed-282]
+ _ = x[ErrAdminProfilerNotEnabled-283]
+ _ = x[ErrInvalidDecompressedSize-284]
+ _ = x[ErrAddUserInvalidArgument-285]
+ _ = x[ErrAdminResourceInvalidArgument-286]
+ _ = x[ErrAdminAccountNotEligible-287]
+ _ = x[ErrAccountNotEligible-288]
+ _ = x[ErrAdminServiceAccountNotFound-289]
+ _ = x[ErrPostPolicyConditionInvalidFormat-290]
}
-const _APIErrorCode_name = "NoneAccessDeniedBadDigestEntityTooSmallEntityTooLargePolicyTooLargeIncompleteBodyInternalErrorInvalidAccessKeyIDAccessKeyDisabledInvalidBucketNameInvalidDigestInvalidRangeInvalidRangePartNumberInvalidCopyPartRangeInvalidCopyPartRangeSourceInvalidMaxKeysInvalidEncodingMethodInvalidMaxUploadsInvalidMaxPartsInvalidPartNumberMarkerInvalidPartNumberInvalidRequestBodyInvalidCopySourceInvalidMetadataDirectiveInvalidCopyDestInvalidPolicyDocumentInvalidObjectStateMalformedXMLMissingContentLengthMissingContentMD5MissingRequestBodyErrorMissingSecurityHeaderNoSuchBucketNoSuchBucketPolicyNoSuchBucketLifecycleNoSuchLifecycleConfigurationInvalidLifecycleWithObjectLockNoSuchBucketSSEConfigNoSuchCORSConfigurationNoSuchWebsiteConfigurationReplicationConfigurationNotFoundErrorRemoteDestinationNotFoundErrorReplicationDestinationMissingLockRemoteTargetNotFoundErrorReplicationRemoteConnectionErrorReplicationBandwidthLimitErrorBucketRemoteIdenticalToSourceBucketRemoteAlreadyExistsBucketRemoteLabelInUseBucketRemoteArnTypeInvalidBucketRemoteArnInvalidBucketRemoteRemoveDisallowedRemoteTargetNotVersionedErrorReplicationSourceNotVersionedErrorReplicationNeedsVersioningErrorReplicationBucketNeedsVersioningErrorReplicationDenyEditErrorReplicationNoExistingObjectsObjectRestoreAlreadyInProgressNoSuchKeyNoSuchUploadInvalidVersionIDNoSuchVersionNotImplementedPreconditionFailedRequestTimeTooSkewedSignatureDoesNotMatchMethodNotAllowedInvalidPartInvalidPartOrderAuthorizationHeaderMalformedMalformedPOSTRequestPOSTFileRequiredSignatureVersionNotSupportedBucketNotEmptyAllAccessDisabledMalformedPolicyMissingFieldsMissingCredTagCredMalformedInvalidRegionInvalidServiceS3InvalidServiceSTSInvalidRequestVersionMissingSignTagMissingSignHeadersTagMalformedDateMalformedPresignedDateMalformedCredentialDateMalformedCredentialRegionMalformedExpiresNegativeExpiresAuthHeaderEmptyExpiredPresignRequestRequestNotReadyYetUnsignedHeadersMissingDateHeaderInvalidQuerySignatureAlgoInvalidQueryParamsBucketAlreadyOwnedByYouInvalidDurationBucketAlreadyExistsMetadataTooLargeUnsupportedMetadataMaximumExpiresSlowDownInvalidPrefixMarkerBadRequestKeyTooLongErrorInvalidBucketObjectLockConfigurationObjectLockConfigurationNotFoundObjectLockConfigurationNotAllowedNoSuchObjectLockConfigurationObjectLockedInvalidRetentionDatePastObjectLockRetainDateUnknownWORMModeDirectiveBucketTaggingNotFoundObjectLockInvalidHeadersInvalidTagDirectiveInvalidEncryptionMethodInsecureSSECustomerRequestSSEMultipartEncryptedSSEEncryptedObjectInvalidEncryptionParametersInvalidSSECustomerAlgorithmInvalidSSECustomerKeyMissingSSECustomerKeyMissingSSECustomerKeyMD5SSECustomerKeyMD5MismatchInvalidSSECustomerParametersIncompatibleEncryptionMethodKMSNotConfiguredKMSKeyNotFoundExceptionNoAccessKeyInvalidTokenEventNotificationARNNotificationRegionNotificationOverlappingFilterNotificationFilterNameInvalidFilterNamePrefixFilterNameSuffixFilterValueInvalidOverlappingConfigsUnsupportedNotificationContentSHA256MismatchReadQuorumWriteQuorumStorageFullRequestBodyParseObjectExistsAsDirectoryInvalidObjectNameInvalidObjectNamePrefixSlashInvalidResourceNameServerNotInitializedOperationTimedOutClientDisconnectedOperationMaxedOutInvalidRequestTransitionStorageClassNotFoundErrorInvalidStorageClassBackendDownMalformedJSONAdminNoSuchUserAdminNoSuchGroupAdminGroupNotEmptyAdminNoSuchPolicyAdminInvalidArgumentAdminInvalidAccessKeyAdminInvalidSecretKeyAdminConfigNoQuorumAdminConfigTooLargeAdminConfigBadJSONAdminConfigDuplicateKeysAdminCredentialsMismatchInsecureClientRequestObjectTamperedSiteReplicationInvalidRequestSiteReplicationPeerRespSiteReplicationBackendIssueSiteReplicationServiceAccountErrorSiteReplicationBucketConfigErrorSiteReplicationBucketMetaErrorSiteReplicationIAMErrorSiteReplicationConfigMissingAdminBucketQuotaExceededAdminNoSuchQuotaConfigurationHealNotImplementedHealNoSuchProcessHealInvalidClientTokenHealMissingBucketHealAlreadyRunningHealOverlappingPathsIncorrectContinuationTokenEmptyRequestBodyUnsupportedFunctionInvalidExpressionTypeBusyUnauthorizedAccessExpressionTooLongIllegalSQLFunctionArgumentInvalidKeyPathInvalidCompressionFormatInvalidFileHeaderInfoInvalidJSONTypeInvalidQuoteFieldsInvalidRequestParameterInvalidDataTypeInvalidTextEncodingInvalidDataSourceInvalidTableAliasMissingRequiredParameterObjectSerializationConflictUnsupportedSQLOperationUnsupportedSQLStructureUnsupportedSyntaxUnsupportedRangeHeaderLexerInvalidCharLexerInvalidOperatorLexerInvalidLiteralLexerInvalidIONLiteralParseExpectedDatePartParseExpectedKeywordParseExpectedTokenTypeParseExpected2TokenTypesParseExpectedNumberParseExpectedRightParenBuiltinFunctionCallParseExpectedTypeNameParseExpectedWhenClauseParseUnsupportedTokenParseUnsupportedLiteralsGroupByParseExpectedMemberParseUnsupportedSelectParseUnsupportedCaseParseUnsupportedCaseClauseParseUnsupportedAliasParseUnsupportedSyntaxParseUnknownOperatorParseMissingIdentAfterAtParseUnexpectedOperatorParseUnexpectedTermParseUnexpectedTokenParseUnexpectedKeywordParseExpectedExpressionParseExpectedLeftParenAfterCastParseExpectedLeftParenValueConstructorParseExpectedLeftParenBuiltinFunctionCallParseExpectedArgumentDelimiterParseCastArityParseInvalidTypeParamParseEmptySelectParseSelectMissingFromParseExpectedIdentForGroupNameParseExpectedIdentForAliasParseUnsupportedCallWithStarParseNonUnaryAgregateFunctionCallParseMalformedJoinParseExpectedIdentForAtParseAsteriskIsNotAloneInSelectListParseCannotMixSqbAndWildcardInSelectListParseInvalidContextForWildcardInSelectListIncorrectSQLFunctionArgumentTypeValueParseFailureEvaluatorInvalidArgumentsIntegerOverflowLikeInvalidInputsCastFailedInvalidCastEvaluatorInvalidTimestampFormatPatternEvaluatorInvalidTimestampFormatPatternSymbolForParsingEvaluatorTimestampFormatPatternDuplicateFieldsEvaluatorTimestampFormatPatternHourClockAmPmMismatchEvaluatorUnterminatedTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternSymbolEvaluatorBindingDoesNotExistMissingHeadersInvalidColumnIndexAdminConfigNotificationTargetsFailedAdminProfilerNotEnabledInvalidDecompressedSizeAddUserInvalidArgumentAdminResourceInvalidArgumentAdminAccountNotEligibleAccountNotEligibleAdminServiceAccountNotFoundPostPolicyConditionInvalidFormat"
+const _APIErrorCode_name = "NoneAccessDeniedBadDigestEntityTooSmallEntityTooLargePolicyTooLargeIncompleteBodyInternalErrorInvalidAccessKeyIDAccessKeyDisabledInvalidBucketNameInvalidDigestInvalidRangeInvalidRangePartNumberInvalidCopyPartRangeInvalidCopyPartRangeSourceInvalidMaxKeysInvalidEncodingMethodInvalidMaxUploadsInvalidMaxPartsInvalidPartNumberMarkerInvalidPartNumberInvalidRequestBodyInvalidCopySourceInvalidMetadataDirectiveInvalidCopyDestInvalidPolicyDocumentInvalidObjectStateMalformedXMLMissingContentLengthMissingContentMD5MissingRequestBodyErrorMissingSecurityHeaderNoSuchBucketNoSuchBucketPolicyNoSuchBucketLifecycleNoSuchLifecycleConfigurationInvalidLifecycleWithObjectLockNoSuchBucketSSEConfigNoSuchCORSConfigurationNoSuchWebsiteConfigurationReplicationConfigurationNotFoundErrorRemoteDestinationNotFoundErrorReplicationDestinationMissingLockRemoteTargetNotFoundErrorReplicationRemoteConnectionErrorReplicationBandwidthLimitErrorBucketRemoteIdenticalToSourceBucketRemoteAlreadyExistsBucketRemoteLabelInUseBucketRemoteArnTypeInvalidBucketRemoteArnInvalidBucketRemoteRemoveDisallowedRemoteTargetNotVersionedErrorReplicationSourceNotVersionedErrorReplicationNeedsVersioningErrorReplicationBucketNeedsVersioningErrorReplicationDenyEditErrorReplicationNoExistingObjectsObjectRestoreAlreadyInProgressNoSuchKeyNoSuchUploadInvalidVersionIDNoSuchVersionNotImplementedPreconditionFailedRequestTimeTooSkewedSignatureDoesNotMatchMethodNotAllowedInvalidPartInvalidPartOrderAuthorizationHeaderMalformedMalformedPOSTRequestPOSTFileRequiredSignatureVersionNotSupportedBucketNotEmptyAllAccessDisabledMalformedPolicyMissingFieldsMissingCredTagCredMalformedInvalidRegionInvalidServiceS3InvalidServiceSTSInvalidRequestVersionMissingSignTagMissingSignHeadersTagMalformedDateMalformedPresignedDateMalformedCredentialDateMalformedCredentialRegionMalformedExpiresNegativeExpiresAuthHeaderEmptyExpiredPresignRequestRequestNotReadyYetUnsignedHeadersMissingDateHeaderInvalidQuerySignatureAlgoInvalidQueryParamsBucketAlreadyOwnedByYouInvalidDurationBucketAlreadyExistsMetadataTooLargeUnsupportedMetadataMaximumExpiresSlowDownInvalidPrefixMarkerBadRequestKeyTooLongErrorInvalidBucketObjectLockConfigurationObjectLockConfigurationNotFoundObjectLockConfigurationNotAllowedNoSuchObjectLockConfigurationObjectLockedInvalidRetentionDatePastObjectLockRetainDateUnknownWORMModeDirectiveBucketTaggingNotFoundObjectLockInvalidHeadersInvalidTagDirectiveInvalidEncryptionMethodInsecureSSECustomerRequestSSEMultipartEncryptedSSEEncryptedObjectInvalidEncryptionParametersInvalidSSECustomerAlgorithmInvalidSSECustomerKeyMissingSSECustomerKeyMissingSSECustomerKeyMD5SSECustomerKeyMD5MismatchInvalidSSECustomerParametersIncompatibleEncryptionMethodKMSNotConfiguredKMSKeyNotFoundExceptionNoAccessKeyInvalidTokenEventNotificationARNNotificationRegionNotificationOverlappingFilterNotificationFilterNameInvalidFilterNamePrefixFilterNameSuffixFilterValueInvalidOverlappingConfigsUnsupportedNotificationContentSHA256MismatchReadQuorumWriteQuorumStorageFullRequestBodyParseObjectExistsAsDirectoryInvalidObjectNameInvalidObjectNamePrefixSlashInvalidResourceNameServerNotInitializedOperationTimedOutClientDisconnectedOperationMaxedOutInvalidRequestTransitionStorageClassNotFoundErrorInvalidStorageClassBackendDownMalformedJSONAdminNoSuchUserAdminNoSuchGroupAdminGroupNotEmptyAdminNoSuchPolicyAdminInvalidArgumentAdminInvalidAccessKeyAdminInvalidSecretKeyAdminConfigNoQuorumAdminConfigTooLargeAdminConfigBadJSONAdminNoSuchConfigTargetAdminConfigEnvOverriddenAdminConfigDuplicateKeysAdminCredentialsMismatchInsecureClientRequestObjectTamperedSiteReplicationInvalidRequestSiteReplicationPeerRespSiteReplicationBackendIssueSiteReplicationServiceAccountErrorSiteReplicationBucketConfigErrorSiteReplicationBucketMetaErrorSiteReplicationIAMErrorSiteReplicationConfigMissingAdminBucketQuotaExceededAdminNoSuchQuotaConfigurationHealNotImplementedHealNoSuchProcessHealInvalidClientTokenHealMissingBucketHealAlreadyRunningHealOverlappingPathsIncorrectContinuationTokenEmptyRequestBodyUnsupportedFunctionInvalidExpressionTypeBusyUnauthorizedAccessExpressionTooLongIllegalSQLFunctionArgumentInvalidKeyPathInvalidCompressionFormatInvalidFileHeaderInfoInvalidJSONTypeInvalidQuoteFieldsInvalidRequestParameterInvalidDataTypeInvalidTextEncodingInvalidDataSourceInvalidTableAliasMissingRequiredParameterObjectSerializationConflictUnsupportedSQLOperationUnsupportedSQLStructureUnsupportedSyntaxUnsupportedRangeHeaderLexerInvalidCharLexerInvalidOperatorLexerInvalidLiteralLexerInvalidIONLiteralParseExpectedDatePartParseExpectedKeywordParseExpectedTokenTypeParseExpected2TokenTypesParseExpectedNumberParseExpectedRightParenBuiltinFunctionCallParseExpectedTypeNameParseExpectedWhenClauseParseUnsupportedTokenParseUnsupportedLiteralsGroupByParseExpectedMemberParseUnsupportedSelectParseUnsupportedCaseParseUnsupportedCaseClauseParseUnsupportedAliasParseUnsupportedSyntaxParseUnknownOperatorParseMissingIdentAfterAtParseUnexpectedOperatorParseUnexpectedTermParseUnexpectedTokenParseUnexpectedKeywordParseExpectedExpressionParseExpectedLeftParenAfterCastParseExpectedLeftParenValueConstructorParseExpectedLeftParenBuiltinFunctionCallParseExpectedArgumentDelimiterParseCastArityParseInvalidTypeParamParseEmptySelectParseSelectMissingFromParseExpectedIdentForGroupNameParseExpectedIdentForAliasParseUnsupportedCallWithStarParseNonUnaryAgregateFunctionCallParseMalformedJoinParseExpectedIdentForAtParseAsteriskIsNotAloneInSelectListParseCannotMixSqbAndWildcardInSelectListParseInvalidContextForWildcardInSelectListIncorrectSQLFunctionArgumentTypeValueParseFailureEvaluatorInvalidArgumentsIntegerOverflowLikeInvalidInputsCastFailedInvalidCastEvaluatorInvalidTimestampFormatPatternEvaluatorInvalidTimestampFormatPatternSymbolForParsingEvaluatorTimestampFormatPatternDuplicateFieldsEvaluatorTimestampFormatPatternHourClockAmPmMismatchEvaluatorUnterminatedTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternSymbolEvaluatorBindingDoesNotExistMissingHeadersInvalidColumnIndexAdminConfigNotificationTargetsFailedAdminProfilerNotEnabledInvalidDecompressedSizeAddUserInvalidArgumentAdminResourceInvalidArgumentAdminAccountNotEligibleAccountNotEligibleAdminServiceAccountNotFoundPostPolicyConditionInvalidFormat"
-var _APIErrorCode_index = [...]uint16{0, 4, 16, 25, 39, 53, 67, 81, 94, 112, 129, 146, 159, 171, 193, 213, 239, 253, 274, 291, 306, 329, 346, 364, 381, 405, 420, 441, 459, 471, 491, 508, 531, 552, 564, 582, 603, 631, 661, 682, 705, 731, 768, 798, 831, 856, 888, 918, 947, 972, 994, 1020, 1042, 1070, 1099, 1133, 1164, 1201, 1225, 1253, 1283, 1292, 1304, 1320, 1333, 1347, 1365, 1385, 1406, 1422, 1433, 1449, 1477, 1497, 1513, 1541, 1555, 1572, 1587, 1600, 1614, 1627, 1640, 1656, 1673, 1694, 1708, 1729, 1742, 1764, 1787, 1812, 1828, 1843, 1858, 1879, 1897, 1912, 1929, 1954, 1972, 1995, 2010, 2029, 2045, 2064, 2078, 2086, 2105, 2115, 2130, 2166, 2197, 2230, 2259, 2271, 2291, 2315, 2339, 2360, 2384, 2403, 2426, 2452, 2473, 2491, 2518, 2545, 2566, 2587, 2611, 2636, 2664, 2692, 2708, 2731, 2742, 2754, 2771, 2786, 2804, 2833, 2850, 2866, 2882, 2900, 2918, 2941, 2962, 2972, 2983, 2994, 3010, 3033, 3050, 3078, 3097, 3117, 3134, 3152, 3169, 3183, 3218, 3237, 3248, 3261, 3276, 3292, 3310, 3327, 3347, 3368, 3389, 3408, 3427, 3445, 3469, 3493, 3514, 3528, 3557, 3580, 3607, 3641, 3673, 3703, 3726, 3754, 3778, 3807, 3825, 3842, 3864, 3881, 3899, 3919, 3945, 3961, 3980, 4001, 4005, 4023, 4040, 4066, 4080, 4104, 4125, 4140, 4158, 4181, 4196, 4215, 4232, 4249, 4273, 4300, 4323, 4346, 4363, 4385, 4401, 4421, 4440, 4462, 4483, 4503, 4525, 4549, 4568, 4610, 4631, 4654, 4675, 4706, 4725, 4747, 4767, 4793, 4814, 4836, 4856, 4880, 4903, 4922, 4942, 4964, 4987, 5018, 5056, 5097, 5127, 5141, 5162, 5178, 5200, 5230, 5256, 5284, 5317, 5335, 5358, 5393, 5433, 5475, 5507, 5524, 5549, 5564, 5581, 5591, 5602, 5640, 5694, 5740, 5792, 5840, 5883, 5927, 5955, 5969, 5987, 6023, 6046, 6069, 6091, 6119, 6142, 6160, 6187, 6219}
+var _APIErrorCode_index = [...]uint16{0, 4, 16, 25, 39, 53, 67, 81, 94, 112, 129, 146, 159, 171, 193, 213, 239, 253, 274, 291, 306, 329, 346, 364, 381, 405, 420, 441, 459, 471, 491, 508, 531, 552, 564, 582, 603, 631, 661, 682, 705, 731, 768, 798, 831, 856, 888, 918, 947, 972, 994, 1020, 1042, 1070, 1099, 1133, 1164, 1201, 1225, 1253, 1283, 1292, 1304, 1320, 1333, 1347, 1365, 1385, 1406, 1422, 1433, 1449, 1477, 1497, 1513, 1541, 1555, 1572, 1587, 1600, 1614, 1627, 1640, 1656, 1673, 1694, 1708, 1729, 1742, 1764, 1787, 1812, 1828, 1843, 1858, 1879, 1897, 1912, 1929, 1954, 1972, 1995, 2010, 2029, 2045, 2064, 2078, 2086, 2105, 2115, 2130, 2166, 2197, 2230, 2259, 2271, 2291, 2315, 2339, 2360, 2384, 2403, 2426, 2452, 2473, 2491, 2518, 2545, 2566, 2587, 2611, 2636, 2664, 2692, 2708, 2731, 2742, 2754, 2771, 2786, 2804, 2833, 2850, 2866, 2882, 2900, 2918, 2941, 2962, 2972, 2983, 2994, 3010, 3033, 3050, 3078, 3097, 3117, 3134, 3152, 3169, 3183, 3218, 3237, 3248, 3261, 3276, 3292, 3310, 3327, 3347, 3368, 3389, 3408, 3427, 3445, 3468, 3492, 3516, 3540, 3561, 3575, 3604, 3627, 3654, 3688, 3720, 3750, 3773, 3801, 3825, 3854, 3872, 3889, 3911, 3928, 3946, 3966, 3992, 4008, 4027, 4048, 4052, 4070, 4087, 4113, 4127, 4151, 4172, 4187, 4205, 4228, 4243, 4262, 4279, 4296, 4320, 4347, 4370, 4393, 4410, 4432, 4448, 4468, 4487, 4509, 4530, 4550, 4572, 4596, 4615, 4657, 4678, 4701, 4722, 4753, 4772, 4794, 4814, 4840, 4861, 4883, 4903, 4927, 4950, 4969, 4989, 5011, 5034, 5065, 5103, 5144, 5174, 5188, 5209, 5225, 5247, 5277, 5303, 5331, 5364, 5382, 5405, 5440, 5480, 5522, 5554, 5571, 5596, 5611, 5628, 5638, 5649, 5687, 5741, 5787, 5839, 5887, 5930, 5974, 6002, 6016, 6034, 6070, 6093, 6116, 6138, 6166, 6189, 6207, 6234, 6266}
func (i APIErrorCode) String() string {
if i < 0 || i >= APIErrorCode(len(_APIErrorCode_index)-1) {
diff --git a/internal/config/config.go b/internal/config/config.go
index 4be94ee51..52052cc34 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -1100,6 +1100,10 @@ func (c Config) ResolveConfigParam(subSys, target, cfgParam string) (value strin
}
defValue, isFound := defKVS.Lookup(cfgParam)
+ // Comments usually are absent from `defKVS`, so we handle it specially.
+ if cfgParam == Comment {
+ defValue, isFound = "", true
+ }
if !isFound {
return
}
@@ -1134,3 +1138,54 @@ func (c Config) ResolveConfigParam(subSys, target, cfgParam string) (value strin
cs = ValueSourceDef
return
}
+
+// KVSrc represents a configuration parameter key and value along with the
+// source of the value.
+type KVSrc struct {
+ Key string
+ Value string
+ Src ValueSource
+}
+
+// GetResolvedConfigParams returns all applicable config parameters with their
+// value sources.
+func (c Config) GetResolvedConfigParams(subSys, target string) ([]KVSrc, error) {
+ // Initially only support OpenID
+ if !resolvableSubsystems.Contains(subSys) {
+ return nil, fmt.Errorf("unsupported subsystem: %s", subSys)
+ }
+
+ // Check if config param requested is valid.
+ defKVS, ok := DefaultKVS[subSys]
+ if !ok {
+ return nil, fmt.Errorf("unknown subsystem: %s", subSys)
+ }
+
+ r := make([]KVSrc, 0, len(defKVS)+1)
+ for _, kv := range defKVS {
+ v, vs := c.ResolveConfigParam(subSys, target, kv.Key)
+
+ // Fix `vs` when default.
+ if v == kv.Value {
+ vs = ValueSourceDef
+ }
+
+ r = append(r, KVSrc{
+ Key: kv.Key,
+ Value: v,
+ Src: vs,
+ })
+ }
+
+ // Add the comment key as well if non-empty.
+ v, vs := c.ResolveConfigParam(subSys, target, Comment)
+ if vs != ValueSourceDef {
+ r = append(r, KVSrc{
+ Key: Comment,
+ Value: v,
+ Src: vs,
+ })
+ }
+
+ return r, nil
+}
diff --git a/internal/config/identity/openid/help.go b/internal/config/identity/openid/help.go
index 6ad718540..57d1b2f51 100644
--- a/internal/config/identity/openid/help.go
+++ b/internal/config/identity/openid/help.go
@@ -52,6 +52,7 @@ var (
config.HelpKV{
Key: ClientSecret,
Description: `secret for the unique public identifier for apps` + defaultHelpPostfix(ClientSecret),
+ Sensitive: true,
Type: "string",
},
config.HelpKV{
diff --git a/internal/config/identity/openid/openid.go b/internal/config/identity/openid/openid.go
index 752e5cd0b..fd77b0510 100644
--- a/internal/config/identity/openid/openid.go
+++ b/internal/config/identity/openid/openid.go
@@ -24,6 +24,7 @@ import (
"errors"
"io"
"net/http"
+ "sort"
"strconv"
"strings"
"sync"
@@ -391,6 +392,107 @@ func LookupConfig(s config.Config, transport http.RoundTripper, closeRespFn func
return c, nil
}
+// ErrProviderConfigNotFound - represents a non-existing provider error.
+var ErrProviderConfigNotFound = errors.New("provider configuration not found")
+
+// GetConfigInfo - returns configuration and related info for the given IDP
+// provider.
+func (r *Config) GetConfigInfo(s config.Config, cfgName string) ([]madmin.IDPCfgInfo, error) {
+ openIDConfigs, err := s.GetAvailableTargets(config.IdentityOpenIDSubSys)
+ if err != nil {
+ return nil, err
+ }
+
+ present := false
+ for _, cfg := range openIDConfigs {
+ if cfg == cfgName {
+ present = true
+ break
+ }
+ }
+
+ if !present {
+ return nil, ErrProviderConfigNotFound
+ }
+
+ kvsrcs, err := s.GetResolvedConfigParams(config.IdentityOpenIDSubSys, cfgName)
+ if err != nil {
+ return nil, err
+ }
+
+ res := make([]madmin.IDPCfgInfo, 0, len(kvsrcs)+1)
+ for _, kvsrc := range kvsrcs {
+ // skip default values.
+ if kvsrc.Src == config.ValueSourceDef {
+ if kvsrc.Key != madmin.EnableKey {
+ continue
+ }
+ // set an explicit on/off from live configuration.
+ kvsrc.Value = "off"
+ if _, ok := r.ProviderCfgs[cfgName]; ok {
+ if r.Enabled {
+ kvsrc.Value = "on"
+ }
+ }
+ }
+ res = append(res, madmin.IDPCfgInfo{
+ Key: kvsrc.Key,
+ Value: kvsrc.Value,
+ IsCfg: true,
+ IsEnv: kvsrc.Src == config.ValueSourceEnv,
+ })
+ }
+
+ if provCfg, exists := r.ProviderCfgs[cfgName]; exists && provCfg.RolePolicy != "" {
+ // Append roleARN
+ res = append(res, madmin.IDPCfgInfo{
+ Key: "roleARN",
+ Value: provCfg.roleArn.String(),
+ IsCfg: false,
+ })
+ }
+
+ // sort the structs by the key
+ sort.Slice(res, func(i, j int) bool {
+ return res[i].Key < res[j].Key
+ })
+
+ return res, nil
+}
+
+// GetConfigList - list openID configurations
+func (r *Config) GetConfigList(s config.Config) ([]madmin.IDPListItem, error) {
+ openIDConfigs, err := s.GetAvailableTargets(config.IdentityOpenIDSubSys)
+ if err != nil {
+ return nil, err
+ }
+
+ var res []madmin.IDPListItem
+ for _, cfg := range openIDConfigs {
+ pcfg, ok := r.ProviderCfgs[cfg]
+ if !ok {
+ res = append(res, madmin.IDPListItem{
+ Type: "openid",
+ Name: cfg,
+ Enabled: false,
+ })
+ } else {
+ var roleARN string
+ if pcfg.RolePolicy != "" {
+ roleARN = pcfg.roleArn.String()
+ }
+ res = append(res, madmin.IDPListItem{
+ Type: "openid",
+ Name: cfg,
+ Enabled: r.Enabled,
+ RoleARN: roleARN,
+ })
+ }
+ }
+
+ return res, nil
+}
+
// Enabled returns if configURL is enabled.
func Enabled(kvs config.KVS) bool {
return kvs.Get(ConfigURL) != ""