Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws\EndpointDiscovery;
3
 
4
use Aws\AbstractConfigurationProvider;
5
use Aws\CacheInterface;
6
use Aws\ConfigurationProviderInterface;
7
use Aws\EndpointDiscovery\Exception\ConfigurationException;
8
use GuzzleHttp\Promise;
9
use GuzzleHttp\Promise\PromiseInterface;
10
 
11
/**
12
 * A configuration provider is a function that returns a promise that is
13
 * fulfilled with a {@see \Aws\EndpointDiscovery\ConfigurationInterface}
14
 * or rejected with an {@see \Aws\EndpointDiscovery\Exception\ConfigurationException}.
15
 *
16
 * <code>
17
 * use Aws\EndpointDiscovery\ConfigurationProvider;
18
 * $provider = ConfigurationProvider::defaultProvider();
19
 * // Returns a ConfigurationInterface or throws.
20
 * $config = $provider()->wait();
21
 * </code>
22
 *
23
 * Configuration providers can be composed to create configuration using
24
 * conditional logic that can create different configurations in different
25
 * environments. You can compose multiple providers into a single provider using
26
 * {@see Aws\EndpointDiscovery\ConfigurationProvider::chain}. This function
27
 * accepts providers as variadic arguments and returns a new function that will
28
 * invoke each provider until a successful configuration is returned.
29
 *
30
 * <code>
31
 * // First try an INI file at this location.
32
 * $a = ConfigurationProvider::ini(null, '/path/to/file.ini');
33
 * // Then try an INI file at this location.
34
 * $b = ConfigurationProvider::ini(null, '/path/to/other-file.ini');
35
 * // Then try loading from environment variables.
36
 * $c = ConfigurationProvider::env();
37
 * // Combine the three providers together.
38
 * $composed = ConfigurationProvider::chain($a, $b, $c);
39
 * // Returns a promise that is fulfilled with a configuration or throws.
40
 * $promise = $composed();
41
 * // Wait on the configuration to resolve.
42
 * $config = $promise->wait();
43
 * </code>
44
 */
45
class ConfigurationProvider extends AbstractConfigurationProvider
46
    implements ConfigurationProviderInterface
47
{
48
    const DEFAULT_ENABLED = false;
49
    const DEFAULT_CACHE_LIMIT = 1000;
50
    const ENV_ENABLED = 'AWS_ENDPOINT_DISCOVERY_ENABLED';
51
    const ENV_ENABLED_ALT = 'AWS_ENABLE_ENDPOINT_DISCOVERY';
52
    const ENV_PROFILE = 'AWS_PROFILE';
53
 
54
    public static $cacheKey = 'aws_cached_endpoint_discovery_config';
55
 
56
    protected static $interfaceClass = ConfigurationInterface::class;
57
    protected static $exceptionClass = ConfigurationException::class;
58
 
59
    /**
60
     * Create a default config provider that first checks for environment
61
     * variables, then checks for a specified profile in the environment-defined
62
     * config file location (env variable is 'AWS_CONFIG_FILE', file location
63
     * defaults to ~/.aws/config), then checks for the "default" profile in the
64
     * environment-defined config file location, and failing those uses a default
65
     * fallback set of configuration options.
66
     *
67
     * This provider is automatically wrapped in a memoize function that caches
68
     * previously provided config options.
69
     *
70
     * @param array $config
71
     *
72
     * @return callable
73
     */
74
    public static function defaultProvider(array $config = [])
75
    {
76
        $configProviders = [self::env()];
77
        if (
78
            !isset($config['use_aws_shared_config_files'])
79
            || $config['use_aws_shared_config_files'] != false
80
        ) {
81
            $configProviders[] = self::ini();
82
        }
83
        $configProviders[] = self::fallback($config);
84
 
85
        $memo = self::memoize(
86
            call_user_func_array([ConfigurationProvider::class, 'chain'], $configProviders)
87
        );
88
 
89
        if (isset($config['endpoint_discovery'])
90
            && $config['endpoint_discovery'] instanceof CacheInterface
91
        ) {
92
            return self::cache($memo, $config['endpoint_discovery'], self::$cacheKey);
93
        }
94
 
95
        return $memo;
96
    }
97
 
98
    /**
99
     * Provider that creates config from environment variables.
100
     *
101
     * @param $cacheLimit
102
     * @return callable
103
     */
104
    public static function env($cacheLimit = self::DEFAULT_CACHE_LIMIT)
105
    {
106
        return function () use ($cacheLimit) {
107
            // Use config from environment variables, if available
108
            $enabled = getenv(self::ENV_ENABLED);
109
            if ($enabled === false || $enabled === '') {
110
                $enabled = getenv(self::ENV_ENABLED_ALT);
111
            }
112
            if ($enabled !== false && $enabled !== '') {
113
                return Promise\Create::promiseFor(
114
                    new Configuration($enabled, $cacheLimit)
115
                );
116
            }
117
 
118
            return self::reject('Could not find environment variable config'
119
                . ' in ' . self::ENV_ENABLED);
120
        };
121
    }
122
 
123
    /**
124
     * Fallback config options when other sources are not set. Will check the
125
     * service model for any endpoint discovery required operations, and enable
126
     * endpoint discovery in that case. If no required operations found, will use
127
     * the class default values.
128
     *
129
     * @param array $config
130
     * @return callable
131
     */
132
    public static function fallback($config = [])
133
    {
134
        $enabled = self::DEFAULT_ENABLED;
135
        if (!empty($config['api_provider'])
136
            && !empty($config['service'])
137
            && !empty($config['version'])
138
        ) {
139
            $provider = $config['api_provider'];
140
            $apiData = $provider('api', $config['service'], $config['version']);
141
            if (!empty($apiData['operations'])) {
142
                foreach ($apiData['operations'] as $operation) {
143
                    if (!empty($operation['endpointdiscovery']['required'])) {
144
                        $enabled = true;
145
                    }
146
                }
147
            }
148
        }
149
 
150
        return function () use ($enabled) {
151
            return Promise\Create::promiseFor(
152
                new Configuration(
153
                    $enabled,
154
                    self::DEFAULT_CACHE_LIMIT
155
                )
156
            );
157
        };
158
    }
159
 
160
    /**
161
     * Config provider that creates config using a config file whose location
162
     * is specified by an environment variable 'AWS_CONFIG_FILE', defaulting to
163
     * ~/.aws/config if not specified
164
     *
165
     * @param string|null $profile  Profile to use. If not specified will use
166
     *                              the "default" profile.
167
     * @param string|null $filename If provided, uses a custom filename rather
168
     *                              than looking in the default directory.
169
     * @param int         $cacheLimit
170
     *
171
     * @return callable
172
     */
173
    public static function ini(
174
        $profile = null,
175
        $filename = null,
176
        $cacheLimit = self::DEFAULT_CACHE_LIMIT
177
    ) {
178
        $filename = $filename ?: (self::getDefaultConfigFilename());
179
        $profile = $profile ?: (getenv(self::ENV_PROFILE) ?: 'default');
180
 
181
        return function () use ($profile, $filename, $cacheLimit) {
182
            if (!@is_readable($filename)) {
183
                return self::reject("Cannot read configuration from $filename");
184
            }
185
            $data = \Aws\parse_ini_file($filename, true);
186
            if ($data === false) {
187
                return self::reject("Invalid config file: $filename");
188
            }
189
            if (!isset($data[$profile])) {
190
                return self::reject("'$profile' not found in config file");
191
            }
192
            if (!isset($data[$profile]['endpoint_discovery_enabled'])) {
193
                return self::reject("Required endpoint discovery config values
194
                    not present in INI profile '{$profile}' ({$filename})");
195
            }
196
 
197
            return Promise\Create::promiseFor(
198
                new Configuration(
199
                    $data[$profile]['endpoint_discovery_enabled'],
200
                    $cacheLimit
201
                )
202
            );
203
        };
204
    }
205
 
206
    /**
207
     * Unwraps a configuration object in whatever valid form it is in,
208
     * always returning a ConfigurationInterface object.
209
     *
210
     * @param  mixed $config
211
     * @return ConfigurationInterface
212
     * @throws \InvalidArgumentException
213
     */
214
    public static function unwrap($config)
215
    {
216
        if (is_callable($config)) {
217
            $config = $config();
218
        }
219
        if ($config instanceof PromiseInterface) {
220
            $config = $config->wait();
221
        }
222
        if ($config instanceof ConfigurationInterface) {
223
            return $config;
224
        } elseif (is_array($config) && isset($config['enabled'])) {
225
            if (isset($config['cache_limit'])) {
226
                return new Configuration(
227
                    $config['enabled'],
228
                    $config['cache_limit']
229
                );
230
            }
231
            return new Configuration(
232
                $config['enabled'],
233
                self::DEFAULT_CACHE_LIMIT
234
            );
235
        }
236
 
237
        throw new \InvalidArgumentException('Not a valid endpoint_discovery '
238
            . 'configuration argument.');
239
    }
240
}