icingaweb2-module-aws icon indicating copy to clipboard operation
icingaweb2-module-aws copied to clipboard

Version mismatch for "Guzzle"

Open widhalmt opened this issue 3 years ago • 3 comments

Summary

When updating the AWS SDK to 3.181.1 a newer version of guzzle becomes a dependency. The Icinga Web 2 module reactbundle brings guzzle in an older version which has precedence when loading.

Details

AWS SDK version that worked: 3.112.25 AWS SDK version that broke dependencies: 3.181.1

Further investigation showed that the problem first occurs with version 3.131.0 for the first time.

Other versions

composer

Output of composer show -I

aws/aws-sdk-php           3.181.1 AWS SDK for PHP - Use Amazon Web Services in your PHP pr...
guzzlehttp/guzzle         7.3.0   Guzzle is a PHP HTTP client library
guzzlehttp/promises       1.4.1   Guzzle promises library
guzzlehttp/psr7           1.8.2   PSR-7 message implementation that also provides common u...
mtdowling/jmespath.php    2.6.0   Declaratively specify how to extract elements from a JSO...
psr/http-client           1.0.1   Common interface for HTTP clients
psr/http-message          1.0.1   Common interface for HTTP messages
ralouphie/getallheaders   3.0.3   A polyfill for getallheaders.
symfony/polyfill-mbstring v1.22.1 Symfony polyfill for the Mbstring extension

Icinga Web 2

Icingaweb2: 2.8.2
Icingaweb2-aws-module: 1.1.0
Icingaweb2-reactbundle-module: 0.9.0

Errormessages

There were two different messages when navigating to "Preview" on /icingaweb2/director/importsources

Uncaught TypeError: Argument 1 passed to Aws\Credentials\AssumeRoleCredentialProvider::Aws\Credentials\{closure}() must be an instance of RuntimeException, instance of Error given, called in /usr/share/icingaweb2/modules/aws/library/vendor/guzzlehttp/promises/src/Promise.php on line 204 and defined in /usr/share/icingaweb2/modules/aws/library/vendor/aws/aws-sdk-php/src/Credentials/AssumeRoleCredentialProvider.php:56
Stack trace:
#0 /usr/share/icingaweb2/modules/aws/library/vendor/guzzlehttp/promises/src/Promise.php(204): Aws\Credentials\AssumeRoleCredentialProvider->Aws\Credentials\{closure}(Object(Error))
#1 /usr/share/icingaweb2/modules/aws/library/vendor/guzzlehttp/promises/src/Promise.php(153): GuzzleHttp\Promise\Promise::callHandler(2, Object(Error), NULL)
#2 /usr/share/icingaweb2/modules/aws/library/vendor/guzzlehttp/promises/src/TaskQueue.php(48): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()

and

Uncaught Error: Undefined class constant 'VERSION' in /usr/share/icingaweb2/modules/reactbundle/vendor/guzzlehttp/guzzle/src/functions.php:136
Stack trace:
#0 /usr/share/icingaweb2/modules/aws/library/vendor/aws/aws-sdk-php/src/functions.php(300): GuzzleHttp\default_user_agent()
#1 /usr/share/icingaweb2/modules/aws/library/vendor/aws/aws-sdk-php/src/Credentials/InstanceProfileProvider.php(206): Aws\default_user_agent()
#2 /usr/share/icingaweb2/modules/aws/library/vendor/aws/aws-sdk-php/src/Credentials/InstanceProfileProvider.php(82): Aws\Credentials\InstanceProfileProvider->request('api/token', 'PUT', Array)
#3 [internal function]: Aws\Credentials\InstanceProfileProvider->Aws\Credentials\{closure}()
#4 /usr/share/icingaweb2/modules/aws/library/vendor/guzzlehttp/promises/src/Coroutine.php(71): Generator->current()
#5 /usr/share/icingaweb2/modules/aws/library/vendor/guzzlehttp/promises/src/Coroutine.php(86): GuzzleHttp\Promise\Coroutine->__construct(Object(Closure))
#6 /usr/share/icingaweb2/modules/reactbundle/

Misc

/ref/NC/724192

widhalmt avatar May 17 '21 15:05 widhalmt

reactbundle depends on version guzzle v6 due to compatibility with PHP 5.6. Guzzle v7 is not compatible with that. The AWS SDK however is compatible with guzzle v6. It obviously isn't possible to run both versions in parallel (albeit both versions are installed separately), so the only solution for future installations of this module is to include the dependencies already with the release. The dependencies then need to be installed while on PHP 5.6, to make sure it's the same environment in which the reactbundle (or whatever its library successor is called) is built. Then we have still two separate guzzle installations, but they should be the same so it doesn't matter.

Though, I have still no idea what's the reason for the second error. #0 is clearly v3.181.1 of the SDK, which is calling guzzle's default_user_agent function, residing in reactbundle's guzzle v6.5.x, which then accesses aws' guzzle v7.3 :exploding_head:

nilmerg avatar May 18 '21 12:05 nilmerg

Hi @widhalmt

I have the same issue after upgrading all my Icinga servers. AWS module was not working anymore. image

Uncaught Error: Undefined class constant 'VERSION' in /usr/share/icinga-php/vendor/vendor/guzzlehttp/guzzle/src/functions.php:136
Stack trace:
#0 /opt/icingaweb2-module-aws-1.0.0/library/vendor/aws/aws-sdk-php/src/functions.php(300): GuzzleHttp\default_user_agent()
#1 /opt/icingaweb2-module-aws-1.0.0/library/vendor/aws/aws-sdk-php/src/Credentials/InstanceProfileProvider.php(206): Aws\default_user_agent()
#2 /opt/icingaweb2-module-aws-1.0.0/library/vendor/aws/aws-sdk-php/src/Credentials/InstanceProfileProvider.php(82): Aws\Credentials\InstanceProfileProvider->request('api/token', 'PUT', Array)
#3 [internal function]: Aws\Credentials\InstanceProfileProvider->Aws\Credentials\{closure}()
#4 /opt/icingaweb2-module-aws-1.0.0/library/vendor/guzzlehttp/promises/src/Coroutine.php(71): Generator->current()
#5 /opt/icingaweb2-module-aws-1.0.0/library/vendor/guzzlehttp/promises/src/Coroutine.php(86): GuzzleHttp\Promise\Coroutine->__construct(Object(Closure))
#6 /usr/share/icinga-php/vendor/vendor/guzzlehttp/promises/src/ (functions.php:136)
#0 [internal function]: Icinga\Application\Web->Icinga\Application\{closure}()
#1 {main}

I managed to work around this problem by updating all my Icinga modules (just in case of) and editing the line 136 of /usr/share/icinga-php/vendor/vendor/guzzlehttp/guzzle/src/functions.php.

vim +136 /usr/share/icinga-php/vendor/vendor/guzzlehttp/guzzle/src/functions.php
#        $defaultAgent = 'GuzzleHttp/' . Client::VERSION;
        $defaultAgent = 'GuzzleHttp/7.3.0';

After that, the AWS module manages to import EC2 instances.

Hope that can help someone.

mickael-ange avatar Aug 13 '21 15:08 mickael-ange

I created a pull request for aws-sdk-php which should fix the problem by using the Utils::defaultUserAgent() https://github.com/aws/aws-sdk-php/pull/2780

moreamazingnick avatar Sep 21 '23 08:09 moreamazingnick