github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/config/lambda/parse.go (about) 1 // Copyright (c) 2015-2023 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package lambda 19 20 import ( 21 "context" 22 "errors" 23 "fmt" 24 "net/http" 25 26 "github.com/minio/minio/internal/config" 27 "github.com/minio/minio/internal/config/lambda/event" 28 "github.com/minio/minio/internal/config/lambda/target" 29 "github.com/minio/minio/internal/logger" 30 "github.com/minio/pkg/v2/env" 31 xnet "github.com/minio/pkg/v2/net" 32 ) 33 34 // ErrTargetsOffline - Indicates single/multiple target failures. 35 var ErrTargetsOffline = errors.New("one or more targets are offline. Please use `mc admin info --json` to check the offline targets") 36 37 // TestSubSysLambdaTargets - tests notification targets of given subsystem 38 func TestSubSysLambdaTargets(ctx context.Context, cfg config.Config, subSys string, transport *http.Transport) error { 39 if err := checkValidLambdaKeysForSubSys(subSys, cfg[subSys]); err != nil { 40 return err 41 } 42 43 targetList, err := fetchSubSysTargets(ctx, cfg, subSys, transport) 44 if err != nil { 45 return err 46 } 47 48 for _, target := range targetList { 49 defer target.Close() 50 } 51 52 for _, target := range targetList { 53 yes, err := target.IsActive() 54 if err == nil && !yes { 55 err = ErrTargetsOffline 56 } 57 if err != nil { 58 return fmt.Errorf("error (%s): %w", target.ID(), err) 59 } 60 } 61 62 return nil 63 } 64 65 func fetchSubSysTargets(ctx context.Context, cfg config.Config, subSys string, transport *http.Transport) (targets []event.Target, err error) { 66 if err := checkValidLambdaKeysForSubSys(subSys, cfg[subSys]); err != nil { 67 return nil, err 68 } 69 70 if subSys == config.LambdaWebhookSubSys { 71 webhookTargets, err := GetLambdaWebhook(cfg[config.LambdaWebhookSubSys], transport) 72 if err != nil { 73 return nil, err 74 } 75 for id, args := range webhookTargets { 76 if !args.Enable { 77 continue 78 } 79 t, err := target.NewWebhookTarget(ctx, id, args, logger.LogOnceIf, transport) 80 if err != nil { 81 return nil, err 82 } 83 targets = append(targets, t) 84 } 85 } 86 return targets, nil 87 } 88 89 // FetchEnabledTargets - Returns a set of configured TargetList 90 func FetchEnabledTargets(ctx context.Context, cfg config.Config, transport *http.Transport) (*event.TargetList, error) { 91 targetList := event.NewTargetList() 92 for _, subSys := range config.LambdaSubSystems.ToSlice() { 93 targets, err := fetchSubSysTargets(ctx, cfg, subSys, transport) 94 if err != nil { 95 return nil, err 96 } 97 for _, t := range targets { 98 if err = targetList.Add(t); err != nil { 99 return nil, err 100 } 101 } 102 } 103 return targetList, nil 104 } 105 106 // DefaultLambdaKVS - default notification list of kvs. 107 var ( 108 DefaultLambdaKVS = map[string]config.KVS{ 109 config.LambdaWebhookSubSys: DefaultWebhookKVS, 110 } 111 ) 112 113 // DefaultWebhookKVS - default KV for webhook config 114 var ( 115 DefaultWebhookKVS = config.KVS{ 116 config.KV{ 117 Key: config.Enable, 118 Value: config.EnableOff, 119 }, 120 config.KV{ 121 Key: target.WebhookEndpoint, 122 Value: "", 123 }, 124 config.KV{ 125 Key: target.WebhookAuthToken, 126 Value: "", 127 }, 128 config.KV{ 129 Key: target.WebhookClientCert, 130 Value: "", 131 }, 132 config.KV{ 133 Key: target.WebhookClientKey, 134 Value: "", 135 }, 136 } 137 ) 138 139 func checkValidLambdaKeysForSubSys(subSys string, tgt map[string]config.KVS) error { 140 validKVS, ok := DefaultLambdaKVS[subSys] 141 if !ok { 142 return nil 143 } 144 for tname, kv := range tgt { 145 subSysTarget := subSys 146 if tname != config.Default { 147 subSysTarget = subSys + config.SubSystemSeparator + tname 148 } 149 if v, ok := kv.Lookup(config.Enable); ok && v == config.EnableOn { 150 if err := config.CheckValidKeys(subSysTarget, kv, validKVS); err != nil { 151 return err 152 } 153 } 154 } 155 return nil 156 } 157 158 // GetLambdaWebhook - returns a map of registered notification 'webhook' targets 159 func GetLambdaWebhook(webhookKVS map[string]config.KVS, transport *http.Transport) ( 160 map[string]target.WebhookArgs, error, 161 ) { 162 webhookTargets := make(map[string]target.WebhookArgs) 163 for k, kv := range config.Merge(webhookKVS, target.EnvWebhookEnable, DefaultWebhookKVS) { 164 enableEnv := target.EnvWebhookEnable 165 if k != config.Default { 166 enableEnv = enableEnv + config.Default + k 167 } 168 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 169 if err != nil { 170 return nil, err 171 } 172 if !enabled { 173 continue 174 } 175 urlEnv := target.EnvWebhookEndpoint 176 if k != config.Default { 177 urlEnv = urlEnv + config.Default + k 178 } 179 url, err := xnet.ParseHTTPURL(env.Get(urlEnv, kv.Get(target.WebhookEndpoint))) 180 if err != nil { 181 return nil, err 182 } 183 authEnv := target.EnvWebhookAuthToken 184 if k != config.Default { 185 authEnv = authEnv + config.Default + k 186 } 187 clientCertEnv := target.EnvWebhookClientCert 188 if k != config.Default { 189 clientCertEnv = clientCertEnv + config.Default + k 190 } 191 192 clientKeyEnv := target.EnvWebhookClientKey 193 if k != config.Default { 194 clientKeyEnv = clientKeyEnv + config.Default + k 195 } 196 197 webhookArgs := target.WebhookArgs{ 198 Enable: enabled, 199 Endpoint: *url, 200 Transport: transport, 201 AuthToken: env.Get(authEnv, kv.Get(target.WebhookAuthToken)), 202 ClientCert: env.Get(clientCertEnv, kv.Get(target.WebhookClientCert)), 203 ClientKey: env.Get(clientKeyEnv, kv.Get(target.WebhookClientKey)), 204 } 205 if err = webhookArgs.Validate(); err != nil { 206 return nil, err 207 } 208 webhookTargets[k] = webhookArgs 209 } 210 return webhookTargets, nil 211 }