Compare commits

..

156 Commits

Author SHA1 Message Date
Tom Jefferson
10beb2b36c Merge pull request #440 from mq-cloudpak/tadj-update-go-mod-cd
Update go mod to 1.19
2023-05-18 09:32:36 +01:00
Tom Jefferson
8e9e0dad15 Update go mod to 1.19 2023-05-17 15:29:06 +01:00
Tom Jefferson
a28eb92b79 Merge pull request #435 from mq-cloudpak/tadj-update-go-cd
Update GO and UBI (CD)
2023-05-17 11:37:16 +01:00
Tom Jefferson
86d3463b79 Update GO and UBI (CD) 2023-05-17 10:36:06 +01:00
Tom Jefferson
30c81a6279 Merge pull request #430 from mq-cloudpak/tadj-update-go-cd
Update go version (CD)
2023-05-05 12:59:42 +01:00
Tom Jefferson
91c44ffa0d Update go version (CD) 2023-05-05 09:54:50 +01:00
Tom Jefferson
9ce5b7f390 Merge pull request #427 from mq-cloudpak/tadj-update-may-version-932
Update version for 9.3.2.1-r2 (May 2.3.3 release)
2023-05-04 12:52:01 +01:00
Tom Jefferson
e621b3d43e Update version for 9.3.2.1-r2 (May 2.3.3 release) 2023-05-04 11:27:35 +01:00
Alec Painter
96135e8d10 Merge pull request #422 from mq-cloudpak/ahp-9.3.2.1-april
updated missed go version
2023-04-11 13:58:15 +01:00
Alec Painter
c2d2168839 Merge branch 'v9.3.2' into ahp-9.3.2.1-april 2023-04-11 13:00:59 +01:00
Alec-Painter
582030e190 updated missed go version 2023-04-11 12:56:53 +01:00
Alec Painter
9c1ebb35c5 Merge pull request #419 from mq-cloudpak/ahp-9.3.2.1-april
Updated to 9.3.2.1
2023-04-11 10:01:33 +01:00
Alec-Painter
b134bd301b Updated to 9.3.2.1 2023-04-11 08:25:51 +01:00
Tom Jefferson
b3c486bd87 Merge pull request #413 from mq-cloudpak/tadj-update-9320-r2
Update version to 9.3.2.0-r2
2023-03-06 15:38:22 +00:00
Tom Jefferson
78483d58fa Update version to 9.3.2.0-r2 2023-03-06 14:14:34 +00:00
Tom Jefferson
db73055203 [ci skip]: Setting up v9.3.2 branch 2023-02-13 17:25:20 +00:00
Tom Jefferson
53790e17c1 Merge pull request #406 from mq-cloudpak/tadj-update-go-ubi-master
Update go and ubi versions
2023-02-09 17:36:08 +00:00
Tom Jefferson
319c120625 Update go and ubi versions 2023-02-09 17:10:07 +00:00
arthur.barr@uk.ibm.com
8d7adc8581 Documentation for MQ_QMGR_LOG_FILE_PAGES 2023-02-08 14:35:42 +00:00
Alex Mirski-Fitton
60f7225442 Merge pull request #403 from mq-cloudpak/amf-consistent-go-version
Ensure consistent use of go 1.18
2023-02-08 12:49:29 +00:00
arthur.barr@uk.ibm.com
38c55eae86 Add new logging vars to README and CHANGELOG 2023-02-08 12:04:17 +00:00
arthur.barr@uk.ibm.com
6084af2386 Update README to disallow pull requests 2023-02-08 12:04:17 +00:00
Alex Mirski-Fitton
d2f7d3764e Ensure consistent use of go 1.18 2023-02-08 11:58:26 +00:00
Avinash Ganesh
b47ad7fde2 Make 'qmgr' logs as default (#401)
* Required updates

* Update docker_api_test.go
2023-02-08 16:34:10 +05:30
arthur.barr@uk.ibm.com
167ec03f04 Multi-line messages squashed to one line in basic format 2023-02-07 14:07:11 +00:00
arthur.barr@uk.ibm.com
98129eb660 Always read Liberty log from start 2023-02-07 14:07:11 +00:00
Tom Jefferson
9c7f49d8d3 Update gosec behaviour and version (#396)
* Update gosec behaviour to fail if unable to install

* fixing gosec issues (#394)

Co-authored-by: KIRAN DARBHA <kirandarbha@in.ibm.com>
2023-02-06 14:33:59 +00:00
BHAVYA K R
572e883841 Bk-1949-fix (#393)
* fixing test failrues

* made changes

* corrected indentation

* incorporated review comments
2023-02-06 17:13:47 +05:30
SHASHIKANTH THAMBRAHALLI
26195d1bd9 Fix certificate relabel issue (#385)
* Fix certificate relabel issue

* Address review comments

* Pull in changes from master

* More merge changes from master

* Update copyright year

* Updated change log. Attempting to get WhiteSource scan run successfully
2023-02-03 14:46:59 +05:30
arthur.barr@uk.ibm.com
c8d13e36e6 Improve basic log format for web server 2023-02-02 18:11:19 +00:00
Tom Jefferson
ca719539a7 Merge pull request #387 from mq-cloudpak/sjh-update-gosec
Updating gosec to 2.14.0
2023-02-02 09:51:19 +00:00
Simon Hirst
b281d59577 Updating gosec to 2.14.0 2023-02-01 12:40:32 +00:00
KIRAN DARBHA
5f0142acdc Kd ws fixes (#386)
* configuing ws

* configuing ws for path exlude
2023-02-01 16:21:15 +05:30
Avinash Ganesh
4588cd44f9 Enhanced console logging
Introduce new environment variables:
  * MQ_LOGGING_CONSOLE_SOURCE
  * MQ_LOGGING_CONSOLE_FORMAT
  * MQ_LOGGING_CONSOLE_EXCLUDE_ID

Authored-by: Avinash Ganesh <avinash.v.g@in.ibm.com> and BHAVYA K R <bhavkris@in.ibm.com>
2023-01-30 14:19:58 +00:00
arthur.barr@uk.ibm.com
5c4422badf Upgrade to Go 1.18 and re-vendor dependencies 2023-01-30 10:16:08 +00:00
arthur.barr@uk.ibm.com
f2842d7eee Update MQ_ARCHIVE in Dockerfile from make target 2023-01-26 17:29:29 +00:00
Alex Mirski-Fitton
4e9877722a Merge pull request #349 from mq-cloudpak/amf-dedup-ready-cmd
Dedup subcommand calls for readiness check
2023-01-26 15:49:01 +00:00
Alex Mirski-Fitton
8efaa55c4f Dedup subcommand calls for readiness check 2023-01-26 14:57:31 +00:00
arthur.barr@uk.ibm.com
537320a32d Use build context instead of network during build
The use of networks in the build process means that Podman cannot be used in rootless mode.  This commit changes the build to use standard podman/docker build context.  This makes the build simpler, but does introduce a pause at the beginning of the build, while the context is uploaded.  This pause is reduced by dynamically creating the .dockerignore file, to prevent unnecessary large files from being uploaded.
2023-01-25 11:11:35 +00:00
Nicholas Daffern
ed618dc6f6 Add logic to set custom Log File Page number (#371)
* Add logic to set custom Log File Page number

Signed-off-by: Nicholas-Daffern <Nicholas.Daffern@ibm.com>
2023-01-25 10:33:24 +00:00
SHASHIKANTH THAMBRAHALLI
862427306b Srt 1928 fipsbugfix (#373)
* FIPS message bug fix

* FIPS message bug fix
2023-01-25 15:56:07 +05:30
Alex Mirski-Fitton
e08a8121f1 Merge pull request #374 from mq-cloudpak/amf-1831-version-length
Handle multi-digit portions of VRMF
2023-01-24 13:29:51 +00:00
Alex Mirski-Fitton
7c4598bd87 Handle multi-digit portions of VRMF 2023-01-23 11:20:41 +00:00
Stephen Marshall
d3a197e0f2 Tidy-up FIPS changes for consistency 2023-01-20 11:14:42 +00:00
SHASHIKANTH THAMBRAHALLI
9518a6d3ed Srt 1899 fipsmessage (#367)
* Fix FIPS message

* Modify function name

* Update FIPS message
2023-01-14 05:45:11 +05:30
Alec Painter
53af11ff0d Merge pull request #369 from mq-cloudpak/ahp-master-ubi
Updated UBI to version 8.7-1031
2023-01-11 09:10:16 +00:00
Alec-Painter
88f72409e4 Updated UBI 2023-01-11 08:49:22 +00:00
Stephen Marshall
ecb71fcca7 Update license for IBM MQ Advanced 9.3 – 02/2023 2023-01-04 11:09:59 +00:00
SHASHIKANTH THAMBRAHALLI
794d1ed2b2 PR for FIPS implemenation (#351)
* Part 1 of FIPS Compliance

* MQ Web Server FIPSs changes

* Remove function param

* Updates to FIPS MQ WebServer

* Fix build error

* Merge latest code from private-master

* Rename fips variable

* Fix build break

* Fix build break

* Fix build break

* Add new docker tests

* First cut of fips metrics

* First cut of fips metrics

* Second part of metrics fips

* Second part of metrics fips

* Added NativeHA FIPS

* Updated test

* Add Native HA tests

* Optimze FIPS handling

* Update comments

* Apply changes from private-master

* Undo metrics changes

* Merge latest changes

* Pull in changes from master

* Update copyright year

* Resolve merge conflicts
2022-12-17 10:09:41 +05:30
Tom Jefferson
1ead807326 Merge pull request #359 from mq-cloudpak/sjh-dec-update
Updating ubi version
2022-12-09 15:41:49 +00:00
Simon Hirst
046517af63 Updating ubi version 2022-12-09 15:22:04 +00:00
SHASHIKANTH THAMBRAHALLI
13b4e0772d Srt-1840- intermittent build failure in LTS builds (#353)
* Add additional logs

* Improve error logging

* Wait before rerunning attribute checks

* Modify retry logic
2022-12-02 14:06:02 +05:30
Stephen Marshall
4af8458ba5 Update to MQ 9.3.2.0 2022-12-01 19:40:44 +00:00
Alec Painter
7ecb80540e Merge pull request #347 from mq-cloudpak/ahp-931-ubi
updated go-version & ubi
2022-11-14 10:34:35 +00:00
Alec-Painter
00648afa87 updated go-version & ubi 2022-11-14 10:09:39 +00:00
SHASHIKANTH THAMBRAHALLI
98a1939577 Updating changelog (#346)
* Updating changelog

* Updating changelog
2022-11-10 09:31:50 +05:30
SHASHIKANTH THAMBRAHALLI
0ddccb971d Fix issue1766 and add test case (#336)
* Fix issue1766 and add test case

* Address review comments

* Updated copyright year

* Resolve merge conflicts
2022-11-01 16:04:07 +05:30
SHASHIKANTH THAMBRAHALLI
50260e1f57 Fix JMS test build issue (#340)
* Fix JMS test build issue

* Remove ciphername where not required
2022-11-01 05:52:25 +05:30
SHASHIKANTH THAMBRAHALLI
a824b75bfa First part of the changes for SSLKEYR (#328)
* Squashed all commits

* Addressed review comments
2022-11-01 05:50:46 +05:30
Stephen Marshall
336d542ff1 Update MQ version to 9.3.1.0-r2 2022-10-21 10:24:57 +01:00
Tom Jefferson
4a9fd2965c Merge pull request #337 from mq-cloudpak/tadj-ipgate-go-toolset-master
Update go toolset
2022-10-10 15:57:29 +01:00
Tom Jefferson
ffd72e8b31 Update go toolset 2022-10-10 15:06:57 +01:00
Tom Jefferson
8182fc43ab Merge pull request #331 from mq-cloudpak/tadj-create-9.3.1.0
Update ubi/go
2022-09-28 19:45:00 +01:00
Tom Jefferson
63a05ad8e4 Update ubi/go 2022-09-28 18:45:32 +01:00
Manisha Kohli
f6b1ff2afd Updating mq-container docs for issue 1727 (#319)
* Updating mq-container docs for issue 1727

* Update building.md

Modified building.md

* Update building.md

Modified building.md along with relative path
2022-09-15 14:27:45 +05:30
David McCann
8d996081cc Merge pull request #322 from mq-cloudpak/djm-use-print-in-logging
Update logging.go to avoid Printf thinking there are missing arguments
2022-09-12 11:25:43 +01:00
BHAVYA K R
15d21c594f Merge pull request #317 from mq-cloudpak/bkr-1728-fix-docupdate
Updating mq-container docs
2022-09-12 14:31:10 +05:30
davidjmccann
bfd37e39c5 Update logging.go
Prevent attempting to directly print strings that may contain embedded percent characters.
2022-09-12 09:43:59 +01:00
Avinash Ganesh
3adb91d9bb Updating mq-container docs (#318) 2022-09-12 12:57:30 +05:30
SHASHIKANTH THAMBRAHALLI
391f4b66d7 Srt issue1710 remove unused test security vulnerabilities (#320)
* Removed unused docker test

* Removed unused docker test

* Added comments on a test

* Removed unused docker test

* Added comments on a test

Co-authored-by: vagrant <vagrant@vagrant.vm>
2022-09-12 08:04:51 +01:00
Bhavya
a8a281db5a Updating mq-container docs 2022-09-08 10:30:29 +00:00
Prerna Srivastava
05d63e3cbf Merge pull request #316 from mq-cloudpak/WS_newFeature
Ws new feature
2022-09-08 15:34:57 +05:30
Prerna Srivastava
467324dd26 Update .whitesource 2022-09-06 14:09:59 +05:30
root
8abe55b86c new feature added 2022-09-06 01:29:07 -07:00
Alex Mirski-Fitton
8db26ebbb0 Merge pull request #311 from mq-cloudpak/amf-credential-helper-go-version
Pin docker-credential-helpers for old go installs
2022-08-22 11:48:20 +01:00
Alex Mirski-Fitton
34831f08a0 Pin docker-credential-helpers for old go installs 2022-08-22 11:16:26 +01:00
Tom Jefferson
e9a3b79a90 Merge pull request #308 from mq-cloudpak/tadj-update-ubi-master
Update go version and ubi
2022-08-09 13:01:50 +01:00
Tom Jefferson
c0a4fb9318 Update go version and ubi 2022-08-08 21:07:08 +01:00
Jack Evans
fb53af6e7b Merge pull request #284 from mq-cloudpak/add-timeout-to-chk-calls
update chkmq* cmds to use context to cancel when taking too long
2022-08-03 13:03:19 +01:00
Jack Evans
65a36fd896 update chkmq* cmds to use context to cancel exec calls if cmd is terminated 2022-08-03 12:07:03 +01:00
arthur.barr@uk.ibm.com
b04ef21071 Allow for slow standby take-over in MIQM test
In TestMultiInstanceContainerStop, if the standby hasn't taken over by the time the active has stopped, the test fails.  This causes problems on slow machines for the CI/CD pipeline.  This commit adds a 30 second timeout on the take-over.
2022-08-03 09:05:30 +01:00
arthur.barr@uk.ibm.com
6acc28125f Use alternative string trimming in auth service
Previous string trimming was changing the strings supplied by MQ to be null-terminated.  MQ uses fixed-width strings, and the changes to the data could cause problems in the queue manager.
2022-08-02 13:40:02 +01:00
arthur.barr@uk.ibm.com
08c533ed99 Remove redundant -r parameter on endmqm
The railroad diagram for endmqm indicates that the  and  flags are mutually exclusive.  Using  implies the behaviour of .
2022-08-02 13:40:02 +01:00
Simon Hirst
45384755bb Fixing indentation in Makefile 2022-07-28 11:23:39 +01:00
Simon Hirst
67b2a690c5 Fixing indentation in Makefile 2022-07-28 10:15:17 +01:00
Nicholas Daffern
cdc2d0b16b Set VOLUME_MOUNT_OPTIONS for macOS at top of makefile or it is not executed (#290)
Signed-off-by: Nicholas-Daffern <Nicholas.Daffern@ibm.com>
2022-07-28 09:18:11 +01:00
arthur.barr@uk.ibm.com
4a66728b79 Initial arm64 changes 2022-07-21 13:01:47 +01:00
Simon Hirst
64e4976a43 Quick fix for checking var values before entering fake master 2022-07-15 09:41:57 +01:00
Simon Hirst
1a45834865 Quick fix for checking var values before entering fake master 2022-07-15 09:21:18 +01:00
Simon Hirst
2ff55a381b Only run a fake master if MAIN_BRANCH and SOURCE_BRANCH are set 2022-07-14 18:07:05 +01:00
Simon Hirst
7c05f4cbcb Only run a fake master if MAIN_BRANCH and SOURCE_BRANCH are set 2022-07-14 17:46:26 +01:00
KIRAN DARBHA
6e10f3ba76 Ws mqc fixes (#276)
* fixing ws issues reported on mqcontainer repo

* updating vendor/modules

* updating vendor/modules

* updating vendor modudles to mark crypto lib as required
2022-07-14 16:20:02 +05:30
Simon Hirst
e7b641cb1b Merge pull request #278 from mq-cloudpak/sjh-fix-master
Removing quotes from SOURCE_BRANCH value
2022-07-14 10:08:55 +01:00
Simon Hirst
37187e5199 Removing quotes from SOURCE_BRANCH value 2022-07-14 09:31:36 +01:00
Simon Hirst
f86dcb1c36 Merge pull request #251 from mq-cloudpak/sjh-fake-master-pushing
Push fake master builds to different namespace
2022-07-13 13:53:04 +01:00
Simon Hirst
ae82196402 Push fake master builds to different namespace 2022-07-13 13:15:04 +01:00
KIRAN DARBHA
bebb8e1559 fixing ws issues reported on 0710 scan (#275)
fixing ws issues reported on 0710 scan

fixing ws issues reported on 0710 scan

reverting back some of the changes to remove two require blocks
2022-07-13 15:52:17 +05:30
Stephen Marshall
a1eda64df3 Update to MQ 9.3.1.0 (#271)
* Update to MQ 9.3.1.0
2022-07-06 11:34:07 +01:00
Alex Mirski-Fitton
813e1ac2dc [ci skip] Update branch name for 9.2.0 LTS (#269) 2022-06-28 15:45:21 +01:00
Alec Painter
3111d48330 Merge pull request #266 from mq-cloudpak/ahp-master-ubi
updated ubi & go toolset
2022-06-15 11:56:48 +01:00
Alec Painter
b8dcbde7b7 updated ubi & go toolset 2022-06-15 10:44:29 +01:00
David Bell
c74cc13a3b [ci skip]: Update building doc link (#262) 2022-06-10 20:41:00 +01:00
arthur.barr@uk.ibm.com
35cc716fcb Update CHANGELOG for 9.3.0 2022-06-08 14:34:35 +01:00
arthur.barr@uk.ibm.com
163873d7a8 Update default TLS cipher for dev config to use TLS12 or higher
The default cipher for the default developer config is ANY_TLS12. This restricts TLS communications to those channels to just TLS 1.2 ciphers and so does not allow people to connect clients with TLS 1.3. This is unnecessarily restrictive and so we should use ANY_TLS12_OR_HIGHER instead.
2022-06-06 13:13:21 +01:00
arthur.barr@uk.ibm.com
0e18f17dc9 Faster build without separate SDK install
Before this change, only the MQ SDK was installed into the go-toolset image, for use at build time.  The genmqpkg command could take around a minute.
2022-05-30 15:47:00 +01:00
arthur.barr@uk.ibm.com
d6ea28ee6b Fix build warning by removing unused variable 2022-05-30 15:47:00 +01:00
David Bell
093c6be85a Merge pull request #254 from mq-cloudpak/drb-remove-extra-lts-builds
Remove extra LTS build from travis
2022-05-27 19:53:12 +01:00
David Bell
28faa252a2 Remove extra LTS build from travis 2022-05-27 13:31:19 +01:00
David Bell
334df22cfd Merge pull request #253 from mq-cloudpak/drb-fixlink
fix doc link
2022-05-27 09:04:35 +01:00
David Bell
b32963854b fix doc link 2022-05-26 20:15:45 +01:00
David Bell
ad153a3fc2 Merge pull request #252 from mq-cloudpak/drb-LTS-build-doc
update building doc for 9.3
2022-05-26 20:12:39 +01:00
David Bell
caa0fd6904 update building doc for 9.3 2022-05-26 16:10:03 +01:00
David Bell
bd7e1193bf Merge pull request #250 from mq-cloudpak/drbsjh-dontpushlts
dont push LTS images to artifactory
2022-05-19 09:00:56 +01:00
David Bell
7c4d95aa2d dont push LTS images to artifactory 2022-05-18 21:15:04 +01:00
Tom Jefferson
7f8ffbf914 Merge pull request #249 from mq-cloudpak/tadj-update-lts-release
Update LTS Version
2022-05-13 10:51:54 +01:00
Tom Jefferson
d3c543a42e Merge pull request #246 from mq-cloudpak/tadj-ubi-go-buffer
Update UBI/Go and add buffer to signals
2022-05-13 10:39:34 +01:00
Tom Jefferson
4931e43b67 Update LTS Version 2022-05-13 10:10:54 +01:00
Tom Jefferson
4e26150542 Update UBI/Go and add buffer to signals 2022-05-12 17:03:47 +01:00
arthur.barr@uk.ibm.com
bf3d8dd26d Use web server build for Podman on macOS 2022-05-12 15:55:10 +01:00
arthur.barr@uk.ibm.com
7c58e2bea2 Make the build faster
Re-use the go-toolset builder image which has the MQ SDK installed, for the C builder image, instead of re-installing the MQ SDK.

Also reduced the number of layers, as each layer was adding time to the build.
2022-05-12 13:48:52 +01:00
KIRAN DARBHA
ae5b736f40 Updating .whitesource file for v9.2.5 (#238) 2022-05-06 16:20:53 +05:30
Tom Jefferson
c1b092e0b1 Merge pull request #236 from mq-cloudpak/tj-update-ubi
Update ubi and go version
2022-05-03 17:33:39 +01:00
Tom Jefferson
adf7582e8b Update ubi and go version 2022-05-03 16:43:46 +01:00
arthur.barr@uk.ibm.com
544c2d1e41 Upgrade Docker API and JUnit 2022-04-28 13:01:32 +01:00
Stephen Marshall
c3f60c5e24 Add default jvm.options file 2022-04-27 12:52:14 +01:00
arthur.barr@uk.ibm.com
b16246455e Remove use of EXTRA_ARGS in Makefile 2022-04-14 15:01:50 +01:00
arthur.barr@uk.ibm.com
fdc447761c Handle failure to download files with curl 2022-04-14 15:01:50 +01:00
arthur.barr@uk.ibm.com
7f5563fa97 Clean up docker network on build failure 2022-04-14 15:01:50 +01:00
arthur.barr@uk.ibm.com
767381b2a0 Change README to reference new sample Helm chart 2022-04-14 11:13:35 +01:00
arthur.barr@uk.ibm.com
3ad3e7ea16 Use icr.io in usage doc 2022-04-14 11:13:35 +01:00
arthur.barr@uk.ibm.com
f6fbc71092 Switch to registry.access.redhat.com registry 2022-04-14 11:13:35 +01:00
Alec Painter
0943d420bc Merge pull request #227 from mq-cloudpak/ahp-ubi-master
Updated UBI
2022-04-12 15:27:35 +01:00
Alec Painter
48cac4fb6c updated ubi 2022-04-12 13:53:33 +01:00
Stephen Marshall
c56ec8cd79 Update to MQ 9.3.0.0 2022-03-29 16:32:43 +01:00
Tom Jefferson
748d2fd11f Merge pull request #221 from mq-cloudpak/tadj-ubi-updates
UBI/Go Update
2022-03-16 13:53:36 +00:00
Tom Jefferson
24eb903b56 UBI/Go Update 2022-03-16 10:06:19 +00:00
Prerna Srivastava
ebbe30ccf9 Merge pull request #220 from mq-cloudpak/WS-14mar22
Ws 14mar22
2022-03-15 16:43:41 +05:30
Prerna Srivastava
65e5d60984 version update 2022-03-14 15:44:20 +05:30
Prerna Srivastava
2279f0b33c Go Version update# 2022-03-14 14:52:14 +05:30
Tom Jefferson
8fa8d8cb2a Merge pull request #217 from mq-cloudpak/tadj-ubi-update
Update ubi and go versions
2022-03-11 11:28:28 +00:00
Tom Jefferson
40d3a9e9ce Update ubi and go versions 2022-03-11 10:30:48 +00:00
KIRAN DARBHA
6a8dcfae79 WSS fixes (#209)
* Random changes

* Updated latest version

* Version update

* Version update

* Version update

* Version update

* updated modules.ext file

* fixing build

Co-authored-by: Prerna Srivastava <prernasrivastava@Prernas-MacBook-Pro.local>
2022-02-28 14:54:13 +05:30
Simon Hirst
85976e1c08 Merge pull request #207 from mq-cloudpak/sjh/remote-qm-fix
Disabling remote queue managers
2022-02-17 15:04:51 +00:00
Simon Hirst
4bf3c81e4e Disabling remote queue managers 2022-02-17 12:45:39 +00:00
David Bell
61e94ed50c Merge pull request #205 from mq-cloudpak/ahp-925-ubis
Updated UBI + go versions
2022-02-04 15:09:12 +00:00
Alec Painter
5c964ef5f7 Updated UBI + go versions 2022-02-04 12:46:30 +00:00
Alec Painter
8db0023815 Merge pull request #202 from mq-cloudpak/ahp-v1.8-ubi
Updated UBI + golang toolset versions to latest for private-master
2022-01-20 16:44:10 +00:00
Alec Painter
060a2e9655 Updated go version in travis file 2022-01-20 16:07:13 +00:00
Alec Painter
d7595f46ff Updated UBI + golang toolset versions to latest 2022-01-20 14:07:50 +00:00
arthur.barr@uk.ibm.com
d2c11089c8 Improve Makefile for podman and SELinux 2022-01-20 10:41:02 +00:00
arthur.barr@uk.ibm.com
d7fd217770 Tolerate nix configuration files 2022-01-20 10:41:02 +00:00
Tom Jefferson
00ada50f06 Fix incorrect variable name 2022-01-13 20:29:31 +00:00
Tom Jefferson
5d88af462f Only lookup level if prereqs met (#197) 2022-01-13 16:31:54 +00:00
Tom Jefferson
eff6ded259 Add MQ build level to the container labels (#195)
* Changes to add MQ build level to the container labels

* Add jq as a dependency
2022-01-13 10:59:02 +00:00
Stephen Marshall
2f103128f3 Fix bug in Makefile for Power support 2021-12-06 20:37:05 +00:00
Stephen Marshall
a48ac18522 Power support (#193)
* MQ 9.2.5.0 & Power Support
2021-12-06 17:51:50 +00:00
554 changed files with 36879 additions and 20849 deletions

View File

@@ -1,2 +0,0 @@
downloads
.git

7
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.dockerignore
.DS_Store
.vscode
test/docker/coverage
@@ -14,3 +15,9 @@ vendor/github.com/prometheus/client_model/.settings*
gosec_results.json
internal/qmgrauth/qmgroam/patch
.tagcache
# Nix
*.nix
.envrc
.direnv
result

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2018, 2020
# © Copyright IBM Corporation 2018, 2023
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -18,18 +18,16 @@ sudo: required
language: go
go:
- "1.16.7"
- "1.19.6"
services:
- docker
env:
global:
- MAIN_BRANCH=v9.2.4
- MQ_LTS_VERSION=9.2.0.2
- MAIN_BRANCH=v9.3.2
- TAGCACHE_FILE=tagcache
- RELEASE=r1
- RELEASE_LTS=r2
- RELEASE=r2
go_import_path: "github.com/ibm-messaging/mq-container"
@@ -40,99 +38,54 @@ go_import_path: "github.com/ibm-messaging/mq-container"
jobs:
include:
- stage: basic-build
if: branch != v9.2.4 AND tag IS blank
if: branch != v9.3.2 AND tag IS blank
name: "Basic AMD64 build"
os: linux
env:
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_924_ARCHIVE_REPOSITORY_DEV_AMD64
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_932_ARCHIVE_REPOSITORY_DEV_AMD64
script: bash -e travis-build-scripts/run.sh
# CD Build
- stage: global-tag
if: branch = v9.2.4 AND type != pull_request OR tag =~ ^release-candidate*
if: branch = v9.3.2 AND type != pull_request OR tag =~ ^release-candidate*
name: "Generate Global Tag"
os: linux
script: bash -e travis-build-scripts/global-tag.sh
- stage: build
if: branch = v9.2.4 OR tag =~ ^release-candidate*
if: branch = v9.3.2 OR tag =~ ^release-candidate*
name: "Multi-Arch AMD64 build"
os: linux
env:
- BUILD_ALL=true
- MQ_ARCHIVE_REPOSITORY=$MQ_924_ARCHIVE_REPOSITORY_AMD64
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_924_ARCHIVE_REPOSITORY_DEV_AMD64
- MQ_ARCHIVE_REPOSITORY=$MQ_932_ARCHIVE_REPOSITORY_AMD64
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_932_ARCHIVE_REPOSITORY_DEV_AMD64
script: bash -e travis-build-scripts/run.sh
# - if: branch = v9.2.4 OR tag =~ ^release-candidate*
# name: "Multi-Arch PPC64LE build"
# os: linux-ppc64le
# env:
# - BUILD_ALL=true
# - TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
# # - MQ_ARCHIVE_REPOSITORY=$MQ_924_ARCHIVE_REPOSITORY_PPC64LE
# - MQ_ARCHIVE_REPOSITORY_DEV=$MQ_924_ARCHIVE_REPOSITORY_DEV_PPC64LE
# script: bash -e travis-build-scripts/run.sh
- stage: build
if: branch = v9.2.4 OR tag =~ ^release-candidate*
if: branch = v9.3.2 OR tag =~ ^release-candidate*
name: "Multi-Arch S390X build"
os: linux-s390
env:
- BUILD_ALL=true
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
- MQ_ARCHIVE_REPOSITORY=$MQ_924_ARCHIVE_REPOSITORY_S390X
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_924_ARCHIVE_REPOSITORY_DEV_S390X
script: bash -e travis-build-scripts/run.sh
- stage: push-manifest
if: branch = v9.2.4 AND type != pull_request OR tag =~ ^release-candidate*
name: "Push Manifest-list to registry"
env:
- PUSH_MANIFEST_ONLY=true
script: bash -e travis-build-scripts/run.sh
# LTS Build
- stage: global-tag
if: branch = v9.2.4 AND type != pull_request OR tag =~ ^release-candidate*
name: "Generate Global Tag"
os: linux
env:
- LTS=true
- TAGCACHE_FILE=tagcache-lts
- MQ_VERSION=$MQ_LTS_VERSION
- RELEASE=$RELEASE_LTS
script: bash -e travis-build-scripts/global-tag.sh
- stage: build
if: branch = v9.2.4 OR tag =~ ^release-candidate*
name: "Multi-Arch AMD64 build"
os: linux
env:
- LTS=true
- TAGCACHE_FILE=tagcache-lts
- MQ_VERSION=$MQ_LTS_VERSION
- MQ_ARCHIVE_REPOSITORY=$MQ_9201_EUS_ARCHIVE_REPOSITORY_AMD64
- RELEASE=$RELEASE_LTS
- MQ_ARCHIVE_REPOSITORY=$MQ_932_ARCHIVE_REPOSITORY_S390X
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_932_ARCHIVE_REPOSITORY_DEV_S390X
script: bash -e travis-build-scripts/run.sh
- stage: build
if: branch = v9.2.4 OR tag =~ ^release-candidate*
name: "Multi-Arch S390X build"
os: linux-s390
if: branch = v9.3.2 OR tag =~ ^release-candidate*
name: "Multi-Arch PPC64LE build"
os: linux-ppc64le
env:
- LTS=true
- TAGCACHE_FILE=tagcache-lts
- MQ_VERSION=$MQ_LTS_VERSION
- BUILD_ALL=true
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
- MQ_ARCHIVE_REPOSITORY=$MQ_9201_EUS_ARCHIVE_REPOSITORY_S390X
- RELEASE=$RELEASE_LTS
- MQ_ARCHIVE_REPOSITORY=$MQ_932_ARCHIVE_REPOSITORY_PPC64LE
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_932_ARCHIVE_REPOSITORY_DEV_PPC64LE
script: bash -e travis-build-scripts/run.sh
- stage: push-manifest
if: branch = v9.2.4 AND type != pull_request OR tag =~ ^release-candidate*
if: branch = v9.3.2 AND type != pull_request OR tag =~ ^release-candidate*
name: "Push Manifest-list to registry"
env:
- LTS=true
- TAGCACHE_FILE=tagcache-lts
- MQ_VERSION=$MQ_LTS_VERSION
- PUSH_MANIFEST_ONLY=true
- RELEASE=$RELEASE_LTS
script: bash -e travis-build-scripts/run.sh
before_install:

View File

@@ -1,6 +1,10 @@
{
"settingsInheritedFrom": "whitesource-config/whitesource-config@master",
"scanSettings": {
"baseBranches": ["private-master", "v9.2.0.x-eus"]
}
"configMode": "LOCAL",
"baseBranches": ["private-master", "v9.2.0.x-eus", "v9.3.0.x"]
},
"issueSettings": {
"issueRepoName": "whitesource-scan-issues"
}
}

View File

@@ -1,6 +1,39 @@
# Change log
## 9.2.4.0 (2021-09-06)
## 9.3.2.1 (2023-04)
* Updated to MQ version 9.3.2.1
## 9.3.2.0 (2023-02)
* Updated to MQ version 9.3.2.0
* Queue manager certificates with the same Subject Distinguished Name (DN) as the issuer (CA) certificate are not supported. A certificate must have a unique Subject Distinguished Name.
* New logging environment variables: MQ_LOGGING_CONSOLE_SOURCE, MQ_LOGGING_CONSOLE_FORMAT, MQ_LOGGING_CONSOLE_EXCLUDE_ID. The LOG_FORMAT variable is deprecated.
* New environment variable: MQ_QMGR_LOG_FILE_PAGES
## 9.3.1.0-r2 (2022-11)
* Queue manager attribute SSLKEYR is now set to blank instead of '/run/runmqserver/tls/key' if key and certificate are not supplied.
## 9.3.1.0 (2022-10)
* Updated to MQ version 9.3.1.0
## 9.3.0.0 (2022-06)
* Updated to MQ version 9.3.0.0
* Use `registry.access.redhat.com` instead of `registry.redhat.io`, so that you don't need to login with a Red Hat account.
* Updated default developer config to use TLS cipher `ANY_TLS12_OR_HIGHER` instead of `ANY_TLS12`
* Added default `jvm.options` file fix issue with missing preferences file causing an error in the web server log.
* Updated to allow building image from Podman on macOS (requires Podman 4.1)
* Container builds are now faster
* Updated signal handling to use a buffer, as recommended by the Go 1.17 vetting tool
## 9.2.5.0 (2022-03)
* Updated to MQ version 9.2.5.0
## 9.2.4.0 (2021-11)
* Updated to MQ version 9.2.4.0

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2015, 2021
# © Copyright IBM Corporation 2015, 2023
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,88 +12,111 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG BASE_IMAGE=registry.redhat.io/ubi8/ubi-minimal
ARG BASE_TAG=8.5-204
ARG BUILDER_IMAGE=registry.redhat.io/ubi8/go-toolset
ARG BUILDER_TAG=1.16.7-5
ARG BASE_IMAGE=registry.access.redhat.com/ubi8/ubi-minimal
ARG BASE_TAG=8.8-860
ARG BUILDER_IMAGE=registry.access.redhat.com/ubi8/go-toolset
ARG BUILDER_TAG=1.19.6-4
ARG GO_WORKDIR=/opt/app-root/src/go/src/github.com/ibm-messaging/mq-container
ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/9.2.4.0-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"
ARG MQ_ARCHIVE="downloads/9.3.2.1-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"
###############################################################################
# Build stage to build Go code
###############################################################################
FROM $BUILDER_IMAGE:$BUILDER_TAG as builder
# The URL to download the MQ installer from in tar.gz format
# This assumes an archive containing the MQ Non-Install packages
ARG MQ_URL
ARG IMAGE_REVISION="Not specified"
ARG IMAGE_SOURCE="Not specified"
ARG IMAGE_TAG="Not specified"
ARG GO_WORKDIR
ARG MQ_ARCHIVE
USER 0
COPY install-mq.sh /usr/local/bin/
RUN mkdir /opt/mqm \
&& chmod a+x /usr/local/bin/install-mq.sh \
&& sleep 1 \
&& INSTALL_SDK=1 install-mq.sh \
&& chown -R 1001:root /opt/mqm/*
WORKDIR $GO_WORKDIR/
ADD $MQ_ARCHIVE /opt/mqm
ENV CGO_CFLAGS="-I/opt/mqm/inc/" \
CGO_LDFLAGS_ALLOW="-Wl,-rpath.*" \
PATH="${PATH}:/opt/mqm/bin"
COPY go.mod go.sum ./
COPY cmd/ ./cmd
COPY internal/ ./internal
COPY pkg/ ./pkg
COPY vendor/ ./vendor
ENV CGO_CFLAGS="-I/opt/mqm/inc/" \
CGO_LDFLAGS_ALLOW="-Wl,-rpath.*"
ENV PATH="${PATH}:/opt/mqm/bin"
RUN go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\" -X \"main.ImageTag=$IMAGE_TAG\"" ./cmd/runmqserver/
RUN go build ./cmd/chkmqready/
RUN go build ./cmd/chkmqhealthy/
RUN go build ./cmd/chkmqstarted/
RUN go build ./cmd/runmqdevserver/
RUN go test -v ./cmd/runmqdevserver/...
RUN go test -v ./cmd/runmqserver/
RUN go test -v ./cmd/chkmqready/
RUN go test -v ./cmd/chkmqhealthy/
RUN go test -v ./cmd/chkmqstarted/
RUN go test -v ./pkg/...
RUN go test -v ./internal/...
RUN go vet ./cmd/... ./internal/...
RUN go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\" -X \"main.ImageTag=$IMAGE_TAG\"" ./cmd/runmqserver/ \
&& go build ./cmd/chkmqready/ \
&& go build ./cmd/chkmqhealthy/ \
&& go build ./cmd/chkmqstarted/ \
&& go build ./cmd/runmqdevserver/ \
&& go test -v ./cmd/runmqdevserver/... \
&& go test -v ./cmd/runmqserver/ \
&& go test -v ./cmd/chkmqready/ \
&& go test -v ./cmd/chkmqhealthy/ \
&& go test -v ./cmd/chkmqstarted/ \
&& go test -v ./pkg/... \
&& go test -v ./internal/... \
&& go vet ./cmd/... ./internal/...
###############################################################################
# Build stage to reduce MQ packages included using genmqpkg
###############################################################################
FROM $BASE_IMAGE:$BASE_TAG AS mq-redux
ARG BASE_IMAGE
ARG BASE_TAG
ARG MQ_ARCHIVE
WORKDIR /tmp/mq
ENV genmqpkg_inc32=0 \
genmqpkg_incadm=1 \
genmqpkg_incamqp=0 \
genmqpkg_incams=1 \
genmqpkg_inccbl=0 \
genmqpkg_inccics=0 \
genmqpkg_inccpp=0 \
genmqpkg_incdnet=0 \
genmqpkg_incjava=1 \
genmqpkg_incjre=1 \
genmqpkg_incman=0 \
genmqpkg_incmqbc=0 \
genmqpkg_incmqft=0 \
genmqpkg_incmqsf=0 \
genmqpkg_incmqxr=0 \
genmqpkg_incnls=1 \
genmqpkg_incras=1 \
genmqpkg_incsamp=1 \
genmqpkg_incsdk=0 \
genmqpkg_inctls=1 \
genmqpkg_incunthrd=0 \
genmqpkg_incweb=1
ADD $MQ_ARCHIVE /opt/mqm-noinstall
# Run genmqpkg to reduce the MQ packages included
RUN /opt/mqm-noinstall/bin/genmqpkg.sh -b /opt/mqm-redux
###############################################################################
# Main build stage, to build MQ image
###############################################################################
FROM $BASE_IMAGE:$BASE_TAG AS mq-server
# The MQ packages to install - see install-mq.sh for default value
ARG MQ_URL
ARG BASE_IMAGE
ARG BASE_TAG
ARG GO_WORKDIR
LABEL summary="IBM MQ Advanced Server"
LABEL description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises"
LABEL vendor="IBM"
LABEL maintainer="IBM"
LABEL distribution-scope="private"
LABEL authoritative-source-url="https://www.ibm.com/software/passportadvantage/"
LABEL url="https://www.ibm.com/products/mq/advanced"
LABEL io.openshift.tags="mq messaging"
LABEL io.k8s.display-name="IBM MQ Advanced Server"
LABEL io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises"
LABEL base-image=$BASE_IMAGE
LABEL base-image-release=$BASE_TAG
COPY install-mq.sh /usr/local/bin/
LABEL summary="IBM MQ Advanced Server" \
description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises" \
vendor="IBM" \
maintainer="IBM" \
distribution-scope="private" \
authoritative-source-url="https://www.ibm.com/software/passportadvantage/" \
url="https://www.ibm.com/products/mq/advanced" \
io.openshift.tags="mq messaging" \
io.k8s.display-name="IBM MQ Advanced Server" \
io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises" \
base-image=$BASE_IMAGE \
base-image-release=$BASE_TAG
COPY --from=mq-redux /opt/mqm-redux/ /opt/mqm/
COPY setup-image.sh /usr/local/bin/
COPY install-mq-server-prereqs.sh /usr/local/bin/
# Install MQ. To avoid a "text file busy" error here, we sleep before installing.
RUN env \
&& mkdir /opt/mqm \
&& chmod u+x /usr/local/bin/install-*.sh \
&& sleep 1 \
&& chmod u+x /usr/local/bin/setup-image.sh \
&& install-mq-server-prereqs.sh \
&& install-mq.sh \
&& setup-image.sh \
&& /opt/mqm/bin/security/amqpamcf \
&& chown -R 1001:root /opt/mqm/*
# Create a directory for runtime data from runmqserver
RUN mkdir -p /run/runmqserver \
&& chown 1001:root /run/runmqserver
COPY --from=builder $GO_WORKDIR/runmqserver /usr/local/bin/
COPY --from=builder $GO_WORKDIR/chkmq* /usr/local/bin/
COPY NOTICES.txt /opt/mqm/licenses/notices-container.txt
@@ -114,7 +137,9 @@ RUN chmod ug+x /usr/local/bin/runmqserver \
EXPOSE 1414 9157 9443
ENV MQ_OVERRIDE_DATA_PATH=/mnt/mqm/data MQ_OVERRIDE_INSTALLATION_NAME=Installation1 MQ_USER_NAME="mqm" PATH="${PATH}:/opt/mqm/bin"
ENV MQ_GRACE_PERIOD=30
ENV LANG=en_US.UTF-8 AMQ_DIAGNOSTIC_MSG_SEVERITY=1 AMQ_ADDITIONAL_JSON_LOG=1 LOG_FORMAT=basic
ENV LANG=en_US.UTF-8 AMQ_DIAGNOSTIC_MSG_SEVERITY=1 AMQ_ADDITIONAL_JSON_LOG=1
ENV MQ_LOGGING_CONSOLE_EXCLUDE_ID=AMQ5041I,AMQ5052I,AMQ5051I,AMQ5037I,AMQ5975I
ENV WLP_LOGGING_MESSAGE_FORMAT=json
# We can run as any UID
USER 1001
ENV MQ_CONNAUTH_USE_HTP=false
@@ -123,20 +148,11 @@ ENTRYPOINT ["runmqserver"]
###############################################################################
# Build stage to build C code for custom authorization service (developer-only)
###############################################################################
FROM registry.redhat.io/rhel8/gcc-toolset-9-toolchain as cbuilder
# The URL to download the MQ installer from in tar.gz format
# This assumes an archive containing the MQ Non-Install packages
ARG MQ_URL
# Use the Go toolset image, which already includes gcc and the MQ SDK
FROM builder as cbuilder
USER 0
# Install the Apache Portable Runtime code (used for htpasswd hash checking)
RUN yum -y install apr-devel apr-util-openssl apr-util-devel
# Install MQ client
COPY install-mq.sh /usr/local/bin/
RUN mkdir /opt/mqm \
&& chmod a+x /usr/local/bin/install-mq.sh \
&& sleep 1 \
&& INSTALL_SDK=1 install-mq.sh \
&& chown -R 1001:root /opt/mqm/*
RUN yum --assumeyes --disableplugin=subscription-manager install apr-devel apr-util-openssl apr-util-devel
COPY authservice/ /opt/app-root/src/authservice/
WORKDIR /opt/app-root/src/authservice/mqhtpass
RUN make all
@@ -148,31 +164,25 @@ FROM mq-server AS mq-dev-server
ARG BASE_IMAGE
ARG BASE_TAG
ARG GO_WORKDIR
# Enable MQ developer default configuration
ENV MQ_DEV=true
LABEL summary="IBM MQ Advanced for Developers Server"
LABEL description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises"
LABEL vendor="IBM"
LABEL distribution-scope="private"
LABEL authoritative-source-url="https://www.ibm.com/software/passportadvantage/"
LABEL url="https://www.ibm.com/products/mq/advanced"
LABEL io.openshift.tags="mq messaging"
LABEL io.k8s.display-name="IBM MQ Advanced for Developers Server"
LABEL io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises"
LABEL base-image=$BASE_IMAGE
LABEL base-image-release=$BASE_TAG
LABEL summary="IBM MQ Advanced for Developers Server" \
description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises" \
vendor="IBM" \
distribution-scope="private" \
authoritative-source-url="https://www.ibm.com/software/passportadvantage/" \
url="https://www.ibm.com/products/mq/advanced" \
io.openshift.tags="mq messaging" \
io.k8s.display-name="IBM MQ Advanced for Developers Server" \
io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises" \
base-image=$BASE_IMAGE \
base-image-release=$BASE_TAG
USER 0
COPY --from=cbuilder /opt/app-root/src/authservice/mqhtpass/build/mqhtpass.so /opt/mqm/lib64/
COPY etc/mqm/*.ini /etc/mqm/
COPY etc/mqm/mq.htpasswd /etc/mqm/
RUN chmod 0660 /etc/mqm/mq.htpasswd
COPY incubating/mqadvanced-server-dev/install-extra-packages.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/install-extra-packages.sh \
&& sleep 1 \
&& install-extra-packages.sh
# Create a directory for runtime data from runmqserver
RUN mkdir -p /run/runmqdevserver \
&& chown 1001:root /run/runmqdevserver
COPY --from=builder $GO_WORKDIR/runmqdevserver /usr/local/bin/
# Copy template files
COPY incubating/mqadvanced-server-dev/*.tpl /etc/mqm/
@@ -181,10 +191,13 @@ COPY incubating/mqadvanced-server-dev/web /etc/mqm/web
RUN chown -R 1001:root /etc/mqm/* \
&& chmod -R g+w /etc/mqm/web \
&& chmod +x /usr/local/bin/runmq* \
&& chmod 0660 /etc/mqm/mq.htpasswd \
&& install --directory --mode 2775 --owner 1001 --group root /run/runmqdevserver
ENV MQ_ENABLE_EMBEDDED_WEB_SERVER=1 MQ_GENERATE_CERTIFICATE_HOSTNAME=localhost
ENV LD_LIBRARY_PATH=/opt/mqm/lib64
ENV MQ_CONNAUTH_USE_HTP=true
ENV MQS_PERMIT_UNKNOWN_ID=true
ENV MQ_DEV=true \
MQ_ENABLE_EMBEDDED_WEB_SERVER=1 \
MQ_GENERATE_CERTIFICATE_HOSTNAME=localhost \
LD_LIBRARY_PATH=/opt/mqm/lib64 \
MQ_CONNAUTH_USE_HTP=true \
MQS_PERMIT_UNKNOWN_ID=true
USER 1001
ENTRYPOINT ["runmqdevserver"]

241
Makefile
View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2017, 2021
# © Copyright IBM Corporation 2017, 2023
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -18,7 +18,15 @@
###############################################################################
include config.env
include source-branch.env
# arch_uname is the platform architecture according to the uname program. Can be differ by OS, e.g. `arm64` on macOS, but `aarch64` on Linux.
arch_uname := $(shell uname -m)
# arch_go is the platform architecture in Go-style (e.g. amd64, ppc64le, s390x or arm64).
arch_go := $(if $(findstring x86_64,$(arch_uname)),amd64,$(if $(findstring aarch64,$(arch_uname)),arm64,$(arch_uname)))
# ARCH is the platform architecture in Go-style (e.g. amd64, ppc64le, s390x or arm64).
# Override this to build an image for a different architecture. Note that RUN instructions will not be able to succeed without the help of emulation provided by packages like qemu-user-static.
ARCH ?= $(arch_go)
# RELEASE shows what release of the container code has been built
RELEASE ?=
# MQ_ARCHIVE_REPOSITORY is a remote repository from which to pull the MQ_ARCHIVE (if required)
@@ -40,7 +48,7 @@ MQ_SDK_ARCHIVE ?= $(MQ_ARCHIVE_DEV_$(MQ_VERSION))
# Options to `go test` for the Docker tests
TEST_OPTS_DOCKER ?=
# Timeout for the Docker tests
TEST_TIMEOUT_DOCKER ?= 30m
TEST_TIMEOUT_DOCKER ?= 45m
# MQ_IMAGE_ADVANCEDSERVER is the name of the built MQ Advanced image
MQ_IMAGE_ADVANCEDSERVER ?=ibm-mqadvanced-server
# MQ_IMAGE_DEVSERVER is the name of the built MQ Advanced for Developers image
@@ -59,28 +67,26 @@ MQ_DELIVERY_REGISTRY_NAMESPACE ?=
MQ_DELIVERY_REGISTRY_USER ?=
# MQ_DELIVERY_REGISTRY_CREDENTIAL is the password/API key for the remote registry (if required)
MQ_DELIVERY_REGISTRY_CREDENTIAL ?=
# REGISTRY_USER is the username used to login to the Red Hat registry
REGISTRY_USER ?=
# REGISTRY_PASS is the password used to login to the Red Hat registry
REGISTRY_PASS ?=
# ARCH is the platform architecture (e.g. amd64, ppc64le or s390x)
ARCH ?= $(if $(findstring x86_64,$(shell uname -m)),amd64,$(shell uname -m))
# LTS is a boolean value to enable/disable LTS container build
LTS ?= false
# VOLUME_MOUNT_OPTIONS is used when bind-mounting files from the "downloads" directory into the container. By default, SELinux labels are automatically re-written, but this doesn't work on some filesystems with extended attributes (xattrs). You can turn off the label re-writing by setting this variable to be blank.
VOLUME_MOUNT_OPTIONS ?= :Z
###############################################################################
# Other variables
###############################################################################
# Build doesn't work if BuildKit is enabled
DOCKER_BUILDKIT=0
# Lock Docker API version for compatibility with Podman and with the Docker version in Travis' Ubuntu Bionic
DOCKER_API_VERSION=1.40
GO_PKG_DIRS = ./cmd ./internal ./test
MQ_ARCHIVE_TYPE=LINUX
MQ_ARCHIVE_DEV_TYPE=Linux
# BUILD_SERVER_CONTAINER is the name of the web server container used at build time
BUILD_SERVER_CONTAINER=build-server
# BUILD_SERVER_NETWORK is the name of the network to use for the web server container used at build time
BUILD_SERVER_NETWORK=build
# NUM_CPU is the number of CPUs available to Docker. Used to control how many
# test run in parallel
NUM_CPU ?= $(or $(shell docker info --format "{{ .NCPU }}"),2)
NUM_CPU ?= $(or $(shell $(COMMAND) info --format "{{ .NCPU }}"),2)
# BASE_IMAGE_TAG is a normalized version of BASE_IMAGE, suitable for use in a Docker tag
BASE_IMAGE_TAG=$(lastword $(subst /, ,$(subst :,-,$(BASE_IMAGE))))
#BASE_IMAGE_TAG=$(subst /,-,$(subst :,-,$(BASE_IMAGE)))
@@ -105,12 +111,22 @@ endif
# Try to figure out which archive to use from the architecture
ifeq "$(ARCH)" "amd64"
MQ_ARCHIVE_ARCH=X86-64
MQ_ARCHIVE_DEV_ARCH=X64
MQ_ARCHIVE_ARCH:=X86-64
MQ_ARCHIVE_DEV_ARCH:=X64
else ifeq "$(ARCH)" "ppc64le"
MQ_ARCHIVE_ARCH=PPC64LE
MQ_ARCHIVE_ARCH:=PPC64LE
MQ_ARCHIVE_DEV_ARCH:=PPC64LE
else ifeq "$(ARCH)" "s390x"
MQ_ARCHIVE_ARCH=S390X
MQ_ARCHIVE_ARCH:=S390X
MQ_ARCHIVE_DEV_ARCH:=S390X
else ifeq "$(ARCH)" "arm64"
MQ_ARCHIVE_ARCH:=ARM64
MQ_ARCHIVE_DEV_ARCH:=ARM64
endif
# If this is a fake master build, push images to alternative location (pipeline wont consider these images GA candidates)
ifeq ($(shell [ "$(TRAVIS)" = "true" ] && [ -n "$(MAIN_BRANCH)" ] && [ -n "$(SOURCE_BRANCH)" ] && [ "$(MAIN_BRANCH)" != "$(SOURCE_BRANCH)" ] && echo "true"), true)
MQ_DELIVERY_REGISTRY_NAMESPACE="master-fake"
endif
# LTS_TAG is the tag modifier for an LTS container build
@@ -138,10 +154,16 @@ endif
# image tagging
ifneq "$(RELEASE)" "$(EMPTY)"
EXTRA_LABELS=--label release=$(RELEASE)
EXTRA_LABELS_RELEASE=--label "release=$(RELEASE)"
RELEASE_TAG="-$(RELEASE)"
endif
ifneq "$(MQ_ARCHIVE_LEVEL)" "$(EMPTY)"
EXTRA_LABELS_LEVEL=--label "mq-build=$(MQ_ARCHIVE_LEVEL)"
endif
EXTRA_LABELS=$(EXTRA_LABELS_RELEASE) $(EXTRA_LABELS_LEVEL)
ifeq "$(TIMESTAMPFLAT)" "$(EMPTY)"
TIMESTAMPFLAT=$(shell date "+%Y%m%d%H%M%S")
endif
@@ -154,6 +176,13 @@ ifeq ($(shell [ ! -z $(TRAVIS) ] && [ "$(TRAVIS_PULL_REQUEST)" = "false" ] && [
MQ_MANIFEST_TAG_SUFFIX=.$(TIMESTAMPFLAT).$(GIT_COMMIT)
endif
# Make sure we don't use VOLUME_MOUNT_OPTIONS for Podman on macOS
ifeq "$(COMMAND)" "podman"
ifeq "$(shell uname -s)" "Darwin"
VOLUME_MOUNT_OPTIONS:=
endif
endif
PATH_TO_MQ_TAG_CACHE=$(TRAVIS_BUILD_DIR)/.tagcache
ifneq "$(TRAVIS)" "$(EMPTY)"
ifneq ("$(wildcard $(PATH_TO_MQ_TAG_CACHE))","")
@@ -163,6 +192,7 @@ endif
MQ_AMD64_TAG=$(MQ_MANIFEST_TAG)-amd64
MQ_S390X_TAG?=$(MQ_MANIFEST_TAG)-s390x
MQ_PPC64LE_TAG?=$(MQ_MANIFEST_TAG)-ppc64le
# end image tagging
@@ -174,8 +204,10 @@ MQ_IMAGE_DEVSERVER_MANIFEST=$(MQ_IMAGE_DEVSERVER):$(MQ_MANIFEST_TAG)
MQ_IMAGE_ADVANCEDSERVER_MANIFEST=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_MANIFEST_TAG)
MQ_IMAGE_DEVSERVER_AMD64=$(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEVSERVER):$(MQ_AMD64_TAG)
MQ_IMAGE_DEVSERVER_S390X=$(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEVSERVER):$(MQ_S390X_TAG)
MQ_IMAGE_DEVSERVER_PPC64LE=$(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEVSERVER):$(MQ_PPC64LE_TAG)
MQ_IMAGE_ADVANCEDSERVER_AMD64=$(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_AMD64_TAG)
MQ_IMAGE_ADVANCEDSERVER_S390X=$(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_S390X_TAG)
MQ_IMAGE_ADVANCEDSERVER_PPC64LE=$(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_PPC64LE_TAG)
###############################################################################
# Build targets
@@ -205,16 +237,16 @@ downloads/$(MQ_ARCHIVE_DEV):
mkdir -p downloads
ifneq "$(BUILD_RSYNC_SERVER)" "$(EMPTY)"
# Use key which is not stored in the repository to fetch the files from the fileserver
curl -L $(BUILD_RSYNC_ENCRYPTED_KEY_URL) -o ./host.key.gpg
curl --fail --location $(BUILD_RSYNC_ENCRYPTED_KEY_URL) --output ./host.key.gpg
@echo $(BUILD_RSYNC_ENCRYPTION_PASSWORD)|gpg --batch --passphrase-fd 0 ./host.key.gpg
chmod 600 ./host.key
rsync -rv -e "ssh -o BatchMode=yes -q -o StrictHostKeyChecking=no -i ./host.key" --include="*/" --include="*.tar.gz" --exclude="*" $(BUILD_RSYNC_USER)@$(BUILD_RSYNC_SERVER):"$(BUILD_RSYNC_PATH)" downloads/$(MQ_ARCHIVE_DEV)
-@rm host.key.gpg host.key
else
ifneq "$(MQ_ARCHIVE_REPOSITORY_DEV)" "$(EMPTY)"
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" -o downloads/$(MQ_ARCHIVE_DEV)
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" --output downloads/$(MQ_ARCHIVE_DEV)
else
curl -L https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_ARCHIVE_DEV) -o downloads/$(MQ_ARCHIVE_DEV)
curl --fail --location https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_ARCHIVE_DEV) --output downloads/$(MQ_ARCHIVE_DEV)
endif
endif
@@ -224,14 +256,14 @@ downloads/$(MQ_ARCHIVE):
ifneq "$(BUILD_RSYNC_SERVER)" "$(EMPTY)"
# Use key which is not stored in the repository to fetch the files from the fileserver
-@rm host.key.gpg host.key
curl -L $(BUILD_RSYNC_ENCRYPTED_KEY_URL) -o ./host.key.gpg
curl --fail --location $(BUILD_RSYNC_ENCRYPTED_KEY_URL) --output ./host.key.gpg
@echo $(BUILD_RSYNC_ENCRYPTION_PASSWORD)|gpg --batch --passphrase-fd 0 ./host.key.gpg
chmod 600 ./host.key
rsync -rv -e "ssh -o BatchMode=yes -q -o StrictHostKeyChecking=no -i ./host.key" --include="*/" --include="*.tar.gz" --exclude="*" $(BUILD_RSYNC_USER)@$(BUILD_RSYNC_SERVER):"$(BUILD_RSYNC_PATH)" downloads/$(MQ_ARCHIVE)
-@rm host.key.gpg host.key
else
ifneq "$(MQ_ARCHIVE_REPOSITORY)" "$(EMPTY)"
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY)" -o downloads/$(MQ_ARCHIVE)
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY)" --output downloads/$(MQ_ARCHIVE)
endif
endif
@@ -242,6 +274,10 @@ downloads: downloads/$(MQ_ARCHIVE_DEV) downloads/$(MQ_SDK_ARCHIVE)
cache-mq-tag:
@printf "MQ_MANIFEST_TAG=$(MQ_MANIFEST_TAG)\n" | tee $(PATH_TO_MQ_TAG_CACHE)
###############################################################################
# Test targets
###############################################################################
# Vendor Go dependencies for the Docker tests
test/docker/vendor:
cd test/docker && go mod vendor
@@ -249,24 +285,24 @@ test/docker/vendor:
# Shortcut to just run the unit tests
.PHONY: test-unit
test-unit:
docker build --target builder --file Dockerfile-server .
$(COMMAND) build --target builder --file Dockerfile-server .
.PHONY: test-advancedserver
test-advancedserver: test/docker/vendor
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) on $(shell docker --version)"$(END)))
docker inspect $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) EXPECTED_LICENSE=Production go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) $(TEST_OPTS_DOCKER)
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) on $(shell $(COMMAND) --version)"$(END)))
$(COMMAND) inspect $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) EXPECTED_LICENSE=Production DOCKER_API_VERSION=$(DOCKER_API_VERSION) go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) $(TEST_OPTS_DOCKER)
.PHONY: build-devjmstest
build-devjmstest: registry-login
build-devjmstest:
$(info $(SPACER)$(shell printf $(TITLE)"Build JMS tests for developer config"$(END)))
cd test/messaging && docker build --tag $(DEV_JMS_IMAGE) .
.PHONY: test-devserver
test-devserver: test/docker/vendor
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_DEVSERVER):$(MQ_TAG) on $(shell docker --version)"$(END)))
docker inspect $(MQ_IMAGE_DEVSERVER):$(MQ_TAG)
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_DEVSERVER):$(MQ_TAG) EXPECTED_LICENSE=Developer DEV_JMS_IMAGE=$(DEV_JMS_IMAGE) IBMJRE=true go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) -tags mqdev $(TEST_OPTS_DOCKER)
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_DEVSERVER):$(MQ_TAG) on $(shell $(COMMAND) --version)"$(END)))
$(COMMAND) inspect $(MQ_IMAGE_DEVSERVER):$(MQ_TAG)
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_DEVSERVER):$(MQ_TAG) EXPECTED_LICENSE=Developer DEV_JMS_IMAGE=$(DEV_JMS_IMAGE) IBMJRE=false DOCKER_API_VERSION=$(DOCKER_API_VERSION) go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) -tags mqdev $(TEST_OPTS_DOCKER)
.PHONY: coverage
coverage:
@@ -274,7 +310,7 @@ coverage:
.PHONY: test-advancedserver-cover
test-advancedserver-cover: test/docker/vendor coverage
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) with code coverage on $(shell docker --version)"$(END)))
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) with code coverage on $(shell $(COMMAND) --version)"$(END)))
rm -f ./coverage/unit*.cov
# Run unit tests with coverage, for each package under 'internal'
go list -f '{{.Name}}' ./internal/... | xargs -I {} go test -cover -covermode count -coverprofile ./coverage/unit-{}.cov ./internal/{}
@@ -286,7 +322,7 @@ test-advancedserver-cover: test/docker/vendor coverage
rm -f ./test/docker/coverage/*.cov
rm -f ./coverage/docker.*
mkdir -p ./test/docker/coverage/
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)-cover TEST_COVER=true go test $(TEST_OPTS_DOCKER)
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)-cover TEST_COVER=true DOCKER_API_VERSION=$(DOCKER_API_VERSION) go test $(TEST_OPTS_DOCKER)
echo 'mode: count' > ./coverage/docker.cov
tail -q -n +2 ./test/docker/coverage/*.cov >> ./coverage/docker.cov
go tool cover -html=./coverage/docker.cov -o ./coverage/docker.html
@@ -295,53 +331,45 @@ test-advancedserver-cover: test/docker/vendor coverage
tail -q -n +2 ./coverage/unit.cov ./coverage/docker.cov >> ./coverage/combined.cov
go tool cover -html=./coverage/combined.cov -o ./coverage/combined.html
# Build an MQ image. The commands used are slightly different between Docker and Podman
###############################################################################
# Build functions
###############################################################################
# Command to build the image
# Args: imageName, imageTag, dockerfile, extraArgs, dockerfileTarget
# If the ARCH variable has been changed from the default value (arch_go variable), then the `--platform` parameter is added
# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget
define build-mq
$(if $(findstring docker,$(COMMAND)), @docker network create build,)
$(if $(findstring docker,$(COMMAND)), @docker run --rm --name $(BUILD_SERVER_CONTAINER) --network build --network-alias build --volume $(DOWNLOADS_DIR):/opt/app-root/src:ro --detach registry.redhat.io/ubi8/nginx-118 nginx -g "daemon off;",)
$(eval EXTRA_ARGS=$(if $(findstring docker,$(COMMAND)), --network build --build-arg MQ_URL=http://build:8080/$4, --volume $(DOWNLOADS_DIR):/var/downloads --build-arg MQ_URL=file:///var/downloads/$4))
# Build the new image
rm -f .dockerignore && echo ".git\ndownloads\n!downloads/$4" > .dockerignore
$(COMMAND) build \
--tag $1:$2 \
--file $3 \
$(EXTRA_ARGS) \
--build-arg IMAGE_REVISION="$(IMAGE_REVISION)" \
--build-arg IMAGE_SOURCE="$(IMAGE_SOURCE)" \
--build-arg IMAGE_TAG="$1:$2" \
--build-arg MQ_ARCHIVE="downloads/$4" \
--label version=$(MQ_VERSION) \
--label name=$1 \
--label build-date=$(shell date +%Y-%m-%dT%H:%M:%S%z) \
--label architecture="$(ARCH)" \
--label run="docker run -d -e LICENSE=accept $1:$2" \
--label run="podman run -d -e LICENSE=accept $1:$2" \
--label vcs-ref=$(IMAGE_REVISION) \
--label vcs-type=git \
--label vcs-url=$(IMAGE_SOURCE) \
$(if $(findstring $(arch_go),$(ARCH)),,--platform=linux/$(ARCH)) \
$(EXTRA_LABELS) \
--target $5 \
.
$(if $(findstring docker,$(COMMAND)), @docker kill $(BUILD_SERVER_CONTAINER))
$(if $(findstring docker,$(COMMAND)), @docker network rm build)
endef
DOCKER_SERVER_VERSION=$(shell docker version --format "{{ .Server.Version }}")
DOCKER_CLIENT_VERSION=$(shell docker version --format "{{ .Client.Version }}")
PODMAN_VERSION=$(shell podman version --format "{{ .Version }}")
.PHONY: command-version
command-version:
# If we're using Docker, then check it's recent enough to support multi-stage builds
ifneq (,$(findstring docker,$(COMMAND)))
@test "$(word 1,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker client 17.05 or greater is required" && exit 1)
@test "$(word 1,$(subst ., ,$(DOCKER_SERVER_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(DOCKER_SERVER_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker server 17.05 or greater is required" && exit 1)
endif
ifneq (,$(findstring podman,$(COMMAND)))
@test "$(word 1,$(subst ., ,$(PODMAN_VERSION)))" -ge "1" || (echo "Error: Podman version 1.0 or greater is required" && exit 1)
endif
###############################################################################
# Build targets
###############################################################################
.PHONY: build-advancedserver-host
build-advancedserver-host: build-advancedserver
.PHONY: build-advancedserver
build-advancedserver: registry-login log-build-env downloads/$(MQ_ARCHIVE) command-version
build-advancedserver: log-build-env downloads/$(MQ_ARCHIVE) command-version
$(info $(SPACER)$(shell printf $(TITLE)"Build $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)"$(END)))
$(call build-mq,$(MQ_IMAGE_ADVANCEDSERVER),$(MQ_TAG),Dockerfile-server,$(MQ_ARCHIVE),mq-server)
@@ -349,40 +377,39 @@ build-advancedserver: registry-login log-build-env downloads/$(MQ_ARCHIVE) comma
build-devserver-host: build-devserver
.PHONY: build-devserver
build-devserver: registry-login log-build-env downloads/$(MQ_ARCHIVE_DEV) command-version
build-devserver: log-build-env downloads/$(MQ_ARCHIVE_DEV) command-version
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_DEVSERVER):$(MQ_TAG)"$(END)))
$(call build-mq,$(MQ_IMAGE_DEVSERVER),$(MQ_TAG),Dockerfile-server,$(MQ_ARCHIVE_DEV),mq-dev-server)
.PHONY: build-advancedserver-cover
build-advancedserver-cover: registry-login command-version
build-advancedserver-cover: command-version
$(COMMAND) build --build-arg BASE_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) -t $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)-cover -f Dockerfile-server.cover .
.PHONY: build-explorer
build-explorer: registry-login downloads/$(MQ_ARCHIVE_DEV)
build-explorer: downloads/$(MQ_ARCHIVE_DEV)
$(call build-mq,mq-explorer,latest-$(ARCH),incubating/mq-explorer/Dockerfile,$(MQ_ARCHIVE_DEV),mq-explorer)
.PHONY: build-sdk
build-sdk: registry-login downloads/$(MQ_ARCHIVE_DEV)
build-sdk: downloads/$(MQ_ARCHIVE_DEV)
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_SDK)"$(END)))
$(call build-mq,mq-sdk,$(MQ_TAG),incubating/mq-sdk/Dockerfile,$(MQ_SDK_ARCHIVE),mq-sdk)
.PHONY: registry-login
registry-login:
ifneq ($(REGISTRY_USER),)
$(COMMAND) login -u $(REGISTRY_USER) -p $(REGISTRY_PASS) registry.redhat.io
endif
###############################################################################
# Logging targets
###############################################################################
.PHONY: log-build-env
log-build-vars:
$(info $(SPACER)$(shell printf $(TITLE)"Build environment"$(END)))
@echo ARCH=$(ARCH)
@echo MQ_VERSION=$(MQ_VERSION)
@echo MQ_ARCHIVE=$(MQ_ARCHIVE)
@echo arch_uname=$(arch_uname)
@echo arch_go=$(arch_go)
@echo "ARCH=$(ARCH) (origin:$(origin ARCH))"
@echo MQ_VERSION="$(MQ_VERSION) (origin:$(origin MQ_VERSION))"
@echo MQ_ARCHIVE="$(MQ_ARCHIVE) (origin:$(origin MQ_ARCHIVE))"
@echo MQ_ARCHIVE_DEV_ARCH=$(MQ_ARCHIVE_DEV_ARCH)
@echo MQ_ARCHIVE_DEV=$(MQ_ARCHIVE_DEV)
@echo MQ_IMAGE_DEVSERVER=$(MQ_IMAGE_DEVSERVER)
@echo MQ_IMAGE_ADVANCEDSERVER=$(MQ_IMAGE_ADVANCEDSERVER)
@echo COMMAND=$(COMMAND)
@echo REGISTRY_USER=$(REGISTRY_USER)
.PHONY: log-build-env
log-build-env: log-build-vars
@@ -392,16 +419,22 @@ log-build-env: log-build-vars
include formatting.mk
###############################################################################
# Push/pull targets
###############################################################################
.PHONY: pull-mq-archive
pull-mq-archive:
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY)" -o downloads/$(MQ_ARCHIVE)
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY)" --output downloads/$(MQ_ARCHIVE)
.PHONY: pull-mq-archive-dev
pull-mq-archive-dev:
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" -o downloads/$(MQ_ARCHIVE_DEV)
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" --output downloads/$(MQ_ARCHIVE_DEV)
.PHONY: push-advancedserver
push-advancedserver:
@if [ $(MQ_DELIVERY_REGISTRY_NAMESPACE) = "master-fake" ]; then\
echo "Detected fake master build. Note that the push destination is set to the fake master namespace: $(MQ_DELIVERY_REGISTRY_FULL_PATH)";\
fi
$(info $(SPACER)$(shell printf $(TITLE)"Push production image to $(MQ_DELIVERY_REGISTRY_FULL_PATH)"$(END)))
$(COMMAND) login $(MQ_DELIVERY_REGISTRY_HOSTNAME) -u $(MQ_DELIVERY_REGISTRY_USER) -p $(MQ_DELIVERY_REGISTRY_CREDENTIAL)
$(COMMAND) tag $(MQ_IMAGE_ADVANCEDSERVER)\:$(MQ_TAG) $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_FULL_RELEASE_NAME)
@@ -409,6 +442,9 @@ push-advancedserver:
.PHONY: push-devserver
push-devserver:
@if [ $(MQ_DELIVERY_REGISTRY_NAMESPACE) = "master-fake" ]; then\
echo "Detected fake master build. Note that the push destination is set to the fake master namespace: $(MQ_DELIVERY_REGISTRY_FULL_PATH)";\
fi
$(info $(SPACER)$(shell printf $(TITLE)"Push developer image to $(MQ_DELIVERY_REGISTRY_FULL_PATH)"$(END)))
$(COMMAND) login $(MQ_DELIVERY_REGISTRY_HOSTNAME) -u $(MQ_DELIVERY_REGISTRY_USER) -p $(MQ_DELIVERY_REGISTRY_CREDENTIAL)
$(COMMAND) tag $(MQ_IMAGE_DEVSERVER)\:$(MQ_TAG) $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEV_FULL_RELEASE_NAME)
@@ -432,25 +468,33 @@ pull-devserver:
push-manifest: build-skopeo-container
$(info $(SPACER)$(shell printf $(TITLE)"** Determining the image digests **"$(END)))
ifneq "$(LTS)" "true"
$(eval MQ_IMAGE_DEVSERVER_AMD64_DIGEST=$(shell $(COMMAND) run skopeo:latest --override-os linux --override-arch s390x inspect --creds $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) docker://$(MQ_IMAGE_DEVSERVER_AMD64) | jq -r .Digest))
$(eval MQ_IMAGE_DEVSERVER_AMD64_DIGEST=$(shell $(COMMAND) run skopeo:latest --override-os linux inspect --creds $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) docker://$(MQ_IMAGE_DEVSERVER_AMD64) | jq -r .Digest))
$(eval MQ_IMAGE_DEVSERVER_S390X_DIGEST=$(shell $(COMMAND) run skopeo:latest --override-os linux inspect --creds $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) docker://$(MQ_IMAGE_DEVSERVER_S390X) | jq -r .Digest))
$(eval MQ_IMAGE_DEVSERVER_PPC64LE_DIGEST=$(shell $(COMMAND) run skopeo:latest --override-os linux inspect --creds $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) docker://$(MQ_IMAGE_DEVSERVER_PPC64LE) | jq -r .Digest))
$(info $(shell printf "** Determined the built $(MQ_IMAGE_DEVSERVER_AMD64) has a digest of $(MQ_IMAGE_DEVSERVER_AMD64_DIGEST)**"$(END)))
$(info $(shell printf "** Determined the built $(MQ_IMAGE_DEVSERVER_S390X) has a digest of $(MQ_IMAGE_DEVSERVER_S390X_DIGEST)**"$(END)))
$(info $(shell printf "** Determined the built $(MQ_IMAGE_DEVSERVER_PPC64LE) has a digest of $(MQ_IMAGE_DEVSERVER_PPC64LE_DIGEST)**"$(END)))
endif
$(eval MQ_IMAGE_ADVANCEDSERVER_AMD64_DIGEST=$(shell $(COMMAND) run skopeo:latest --override-os linux inspect --creds $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) docker://$(MQ_IMAGE_ADVANCEDSERVER_AMD64) | jq -r .Digest))
$(eval MQ_IMAGE_ADVANCEDSERVER_S390X_DIGEST=$(shell $(COMMAND) run skopeo:latest --override-os linux inspect --creds $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) docker://$(MQ_IMAGE_ADVANCEDSERVER_S390X) | jq -r .Digest))
$(eval MQ_IMAGE_ADVANCEDSERVER_PPC64LE_DIGEST=$(shell $(COMMAND) run skopeo:latest --override-os linux inspect --creds $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) docker://$(MQ_IMAGE_ADVANCEDSERVER_PPC64LE) | jq -r .Digest))
$(info $(shell printf "** Determined the built $(MQ_IMAGE_ADVANCEDSERVER_AMD64) has a digest of $(MQ_IMAGE_ADVANCEDSERVER_AMD64_DIGEST)**"$(END)))
$(info $(shell printf "** Determined the built $(MQ_IMAGE_ADVANCEDSERVER_S390X) has a digest of $(MQ_IMAGE_ADVANCEDSERVER_S390X_DIGEST)**"$(END)))
$(info $(shell printf "** Determined the built $(MQ_IMAGE_ADVANCEDSERVER_PPC64LE) has a digest of $(MQ_IMAGE_ADVANCEDSERVER_PPC64LE_DIGEST)**"$(END)))
ifneq "$(LTS)" "true"
$(info $(shell printf "** Calling script to create fat-manifest for $(MQ_IMAGE_DEVSERVER_MANIFEST)**"$(END)))
echo $(shell ./travis-build-scripts/create-manifest-list.sh -r $(MQ_DELIVERY_REGISTRY_HOSTNAME) -n $(MQ_DELIVERY_REGISTRY_NAMESPACE) -i $(MQ_IMAGE_DEVSERVER) -t $(MQ_MANIFEST_TAG) -u $(MQ_ARCHIVE_REPOSITORY_USER) -p $(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -d "$(MQ_IMAGE_DEVSERVER_AMD64_DIGEST) $(MQ_IMAGE_DEVSERVER_S390X_DIGEST)" $(END))
echo $(shell ./travis-build-scripts/create-manifest-list.sh -r $(MQ_DELIVERY_REGISTRY_HOSTNAME) -n $(MQ_DELIVERY_REGISTRY_NAMESPACE) -i $(MQ_IMAGE_DEVSERVER) -t $(MQ_MANIFEST_TAG) -u $(MQ_ARCHIVE_REPOSITORY_USER) -p $(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -d "$(MQ_IMAGE_DEVSERVER_AMD64_DIGEST) $(MQ_IMAGE_DEVSERVER_S390X_DIGEST) $(MQ_IMAGE_DEVSERVER_PPC64LE_DIGEST)" $(END))
endif
$(info $(shell printf "** Calling script to create fat-manifest for $(MQ_IMAGE_ADVANCEDSERVER_MANIFEST)**"$(END)))
echo $(shell ./travis-build-scripts/create-manifest-list.sh -r $(MQ_DELIVERY_REGISTRY_HOSTNAME) -n $(MQ_DELIVERY_REGISTRY_NAMESPACE) -i $(MQ_IMAGE_ADVANCEDSERVER) -t $(MQ_MANIFEST_TAG) -u $(MQ_ARCHIVE_REPOSITORY_USER) -p $(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -d "$(MQ_IMAGE_ADVANCEDSERVER_AMD64_DIGEST) $(MQ_IMAGE_ADVANCEDSERVER_S390X_DIGEST)" $(END))
echo $(shell ./travis-build-scripts/create-manifest-list.sh -r $(MQ_DELIVERY_REGISTRY_HOSTNAME) -n $(MQ_DELIVERY_REGISTRY_NAMESPACE) -i $(MQ_IMAGE_ADVANCEDSERVER) -t $(MQ_MANIFEST_TAG) -u $(MQ_ARCHIVE_REPOSITORY_USER) -p $(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -d "$(MQ_IMAGE_ADVANCEDSERVER_AMD64_DIGEST) $(MQ_IMAGE_ADVANCEDSERVER_S390X_DIGEST) $(MQ_IMAGE_ADVANCEDSERVER_PPC64LE_DIGEST)" $(END))
.PHONY: build-skopeo-container
build-skopeo-container:
$(COMMAND) images | grep -q "skopeo"; if [ $$? != 0 ]; then docker build -t skopeo:latest ./docker-builds/skopeo/; fi
$(COMMAND) images | grep -q "skopeo"; if [ $$? != 0 ]; then $(COMMAND) build -t skopeo:latest ./docker-builds/skopeo/; fi
###############################################################################
# Other targets
###############################################################################
.PHONY: clean
clean:
@@ -489,35 +533,20 @@ lint: $(addsuffix /$(wildcard *.go), $(GO_PKG_DIRS))
.PHONY: gosec
gosec:
$(info $(SPACER)$(shell printf "Running gosec test"$(END)))
@gosec -fmt=json -out=gosec_results.json cmd/... internal/... 2> /dev/null ;\
cat "gosec_results.json" ;\
cat gosec_results.json | grep HIGH | grep severity > /dev/null ;\
if [ $$? -eq 0 ]; then \
printf "\nFAILURE: gosec found files containing HIGH severity issues - see results.json\n" ;\
@gosecrc=0; gosec -fmt=json -out=gosec_results.json cmd/... internal/... 2> /dev/null || gosecrc=$$?; \
cat gosec_results.json | jq '{"GolangErrors": (.["Golang errors"]|length>0),"Issues":(.Issues|length>0)}' | grep 'true' >/dev/null ;\
if [ $$? -eq 0 ] || [ $$gosecrc -ne 0 ]; then \
printf "FAILURE: Issues found running gosec - see gosec_results.json\n" ;\
cat "gosec_results.json" ;\
exit 1 ;\
else \
printf "\ngosec found no HIGH severity issues\n" ;\
fi ;\
cat gosec_results.json | grep MEDIUM | grep severity > /dev/null ;\
if [ $$? -eq 0 ]; then \
printf "\nFAILURE: gosec found files containing MEDIUM severity issues - see results.json\n" ;\
exit 1 ;\
else \
printf "\ngosec found no MEDIUM severity issues\n" ;\
fi ;\
cat gosec_results.json | grep LOW | grep severity > /dev/null;\
if [ $$? -eq 0 ]; then \
printf "\nFAILURE: gosec found files containing LOW severity issues - see results.json\n" ;\
exit 1;\
else \
printf "\ngosec found no LOW severity issues\n" ;\
fi ;\
include formatting.mk
printf "gosec found no issues\n" ;\
cat "gosec_results.json" ;\
fi
.PHONY: update-release-information
update-release-information:
sed -i.bak 's/ARG MQ_URL=.*-LinuxX64.tar.gz"/ARG MQ_URL="https:\/\/public.dhe.ibm.com\/ibmdl\/export\/pub\/software\/websphere\/messaging\/mqadv\/$(MQ_VERSION)-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"/g' Dockerfile-server && rm Dockerfile-server.bak
sed -i.bak 's/ARG MQ_ARCHIVE=.*-LinuxX64.tar.gz"/ARG MQ_ARCHIVE="downloads\/$(MQ_VERSION)-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"/g' Dockerfile-server && rm Dockerfile-server.bak
$(eval MQ_VERSION_1=$(shell echo '${MQ_VERSION}' | rev | cut -c 3- | rev))
sed -i.bak 's/IBM_MQ_.*_LINUX_X86-64_NOINST.tar.gz/IBM_MQ_${MQ_VERSION_1}_LINUX_X86-64_NOINST.tar.gz/g' docs/building.md && rm docs/building.md.bak
sed -i.bak 's/ibm-mqadvanced-server:.*-amd64/ibm-mqadvanced-server:$(MQ_VERSION)-amd64/g' docs/security.md
@@ -527,3 +556,17 @@ update-release-information:
sed -i.bak 's/knowledgecenter\/SSFKSJ_.*\/com/knowledgecenter\/SSFKSJ_${MQ_VERSION_2}.0\/com/g' docs/usage.md && rm docs/usage.md.bak
$(eval MQ_VERSION_3=$(shell echo '${MQ_VERSION_1}' | sed "s/\.//g"))
sed -i.bak 's/MQ_..._ARCHIVE_REPOSITORY/MQ_${MQ_VERSION_3}_ARCHIVE_REPOSITORY/g' .travis.yml && rm .travis.yml.bak
COMMAND_SERVER_VERSION=$(shell $(COMMAND) version --format "{{ .Server.Version }}")
COMMAND_CLIENT_VERSION=$(shell $(COMMAND) version --format "{{ .Client.Version }}")
PODMAN_VERSION=$(shell podman version --format "{{ .Version }}")
.PHONY: command-version
command-version:
# If we're using Docker, then check it's recent enough to support multi-stage builds
ifneq (,$(findstring docker,$(COMMAND)))
@test "$(word 1,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker client 17.05 or greater is required" && exit 1)
@test "$(word 1,$(subst ., ,$(COMMAND_SERVER_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(COMMAND_SERVER_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker server 17.05 or greater is required" && exit 1)
endif
ifneq (,$(findstring podman,$(COMMAND)))
@test "$(word 1,$(subst ., ,$(PODMAN_VERSION)))" -ge "1" || (echo "Error: Podman version 1.0 or greater is required" && exit 1)
endif

View File

@@ -27,30 +27,33 @@ Note that in order to use the image, it is necessary to accept the terms of the
- **LICENSE** - Set this to `accept` to agree to the MQ Advanced for Developers license. If you wish to see the license you can set this to `view`.
- **LANG** - Set this to the language you would like the license to be printed in.
- **MQ_QMGR_NAME** - Set this to the name you want your Queue Manager to be created with.
- **LOG_FORMAT** - Set this to change the format of the logs which are printed on the container's stdout. Set to "json" to use JSON format (JSON object per line); set to "basic" to use a simple human-readable format. Defaults to "basic".
- **MQ_QMGR_LOG_FILE_PAGES** - Set this to control the value for LogFilePages passed to the "crtmqm" command. Cannot be changed after queue manager creation.
- **MQ_LOGGING_CONSOLE_SOURCE** - Specifies a comma-separated list of sources for logs which are mirrored to the container's stdout. The valid values are "qmgr" and "web". Defaults to "qmgr".
- **MQ_LOGGING_CONSOLE_FORMAT** - Changes the format of the logs which are printed on the container's stdout. Set to "json" to use JSON format (JSON object per line); set to "basic" to use a simple human-readable format. Defaults to "basic".
- **MQ_LOGGING_CONSOLE_EXCLUDE_ID** - Excludes log messages with the specified ID. The log messages still appear in the log file on disk, but are excluded from the container's stdout. Defaults to "AMQ5041I,AMQ5052I,AMQ5051I,AMQ5037I,AMQ5975I".
- **MQ_ENABLE_METRICS** - Set this to `true` to generate Prometheus metrics for your Queue Manager.
See the [default developer configuration docs](docs/developer-config.md) for the extra environment variables supported by the MQ Advanced for Developers image.
### Kubernetes
If you want to use IBM MQ in [Kubernetes](https://kubernetes.io), you can find an example [Helm](https://helm.sh/) chart here: [IBM charts](https://github.com/IBM/charts). This can be used to run the container on a cluster, such as [IBM Cloud Private](https://www.ibm.com/cloud-computing/products/ibm-cloud-private/) or the [IBM Cloud Kubernetes Service](https://www.ibm.com/cloud/container-service).
If you want to use IBM MQ on [Kubernetes](https://kubernetes.io), you can find an example [Helm](https://helm.sh/) chart here: [IBM MQ Sample Helm Chart](https://github.com/ibm-messaging/mq-helm). This can be used to run the container on a Kubernetes cluster, such as the [IBM Cloud Kubernetes Service](https://www.ibm.com/cloud/container-service).
## Issues and contributions
For issues relating specifically to the container image or Helm chart, please use the [GitHub issue tracker](https://github.com/ibm-messaging/mq-container/issues). If you do submit a Pull Request related to this Docker image, please indicate in the Pull Request that you accept and agree to be bound by the terms of the [IBM Contributor License Agreement](CLA.md).
For issues relating specifically to the container image or Helm chart, please use the [GitHub issue tracker](https://github.com/ibm-messaging/mq-container/issues). Pull requests are not currently accepted.
## License
The Dockerfiles and associated code and scripts are licensed under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
Licenses for the products installed within the images are as follows:
- [IBM MQ Advanced for Developers](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-BYHCL7) (International License Agreement for Non-Warranted Programs). This license may be viewed from an image using the `LICENSE=view` environment variable as described above or by following the link above.
- [IBM MQ Advanced](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-BZDDDY) (International Program License Agreement). This license may be viewed from an image using the `LICENSE=view` environment variable as described above or by following the link above.
- [IBM MQ Advanced for Developers](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-CAUEQC) (International License Agreement for Non-Warranted Programs). This license may be viewed from an image using the `LICENSE=view` environment variable as described above or by following the link above.
- [IBM MQ Advanced](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-UPFX-8MW49T) (International Program License Agreement). This license may be viewed from an image using the `LICENSE=view` environment variable as described above or by following the link above.
Note: The IBM MQ Advanced for Developers license does not permit further distribution and the terms restrict usage to a developer machine.
## Copyright
© Copyright IBM Corporation 2015, 2021
© Copyright IBM Corporation 2015, 2023

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2017, 2020
# © Copyright IBM Corporation 2017, 2022
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -20,19 +20,31 @@
SRC_DIR = src
BUILD_DIR = ./build
ARCH ?= $(if $(findstring x86_64,$(shell uname -m)),amd64,$(if $(findstring aarch64,$(shell uname -m)),aarch64,$(shell uname -m)))
# Flags passed to the C compiler. Need to use gnu11 to get POSIX functions needed for file locking.
CFLAGS += -std=gnu11 -fPIC -Wall -m64
CFLAGS.amd64 := -m64
CFLAGS.ppc64le := -m64
CFLAGS.s390x := -m64
# -m64 is not a valid compiler option on aarch64/arm64 (ARM)
CFLAGS.arm64 :=
CFLAGS += -std=gnu11 -fPIC -Wall ${CFLAGS.${ARCH}}
LIB_APR = -L/usr/lib64 -lapr-1 -laprutil-1
LIB_MQ = -L/opt/mqm/lib64 -lmqm_r
all: $(BUILD_DIR)/mqhtpass.so $(BUILD_DIR)/htpass_test
all: $(BUILD_DIR)/mqhtpass.so $(BUILD_DIR)/htpass_test $(BUILD_DIR)/log_test
$(BUILD_DIR)/log.o : $(SRC_DIR)/log.c $(SRC_DIR)/log.h
mkdir -p ${dir $@}
gcc $(CFLAGS) -c $(SRC_DIR)/log.c -o $@
$(BUILD_DIR)/log_test : $(BUILD_DIR)/log.o
mkdir -p ${dir $@}
gcc $(CFLAGS) $(SRC_DIR)/log_test.c $^ -o $@
# Run Logging tests, and print log if they fail
$@ || (cat log_test*.log && exit 1)
$(BUILD_DIR)/htpass.o : $(SRC_DIR)/htpass.c $(SRC_DIR)/htpass.h
mkdir -p ${dir $@}
gcc $(CFLAGS) -c $(SRC_DIR)/htpass.c -I /usr/include/apr-1 -o $@

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2021
© Copyright IBM Corporation 2021, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -124,7 +124,7 @@ void log_printf(const char *source_file, int source_line, const char *level, con
if (strftime(date_buf, sizeof date_buf, "%FT%T", utc))
{
// Round microseconds down to milliseconds, for consistency
cur += snprintf(cur, end-cur, ", \"ibm_datetime\":\"%s.%03ldZ\"", date_buf, now.tv_usec / 1000);
cur += snprintf(cur, end-cur, ", \"ibm_datetime\":\"%s.%03ldZ\"", date_buf, now.tv_usec / (long)1000);
}
cur += snprintf(cur, end-cur, ", \"ibm_processId\":\"%d\"", pid);
cur += snprintf(cur, end-cur, ", \"host\":\"%s\"", hostname);
@@ -146,7 +146,17 @@ void log_printf(const char *source_file, int source_line, const char *level, con
// Important: Just do one file write, to prevent problems with multi-threading.
// This only works if the log message is not too long for the buffer.
fprintf(fp, buf);
fprintf(fp, "%s", buf);
}
}
int trimmed_len(char *s, int max_len)
{
int i;
for (i = max_len - 1; i >= 0; i--)
{
if (s[i] != ' ')
break;
}
return i+1;
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2021
© Copyright IBM Corporation 2021, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -59,5 +59,12 @@ void log_close();
*/
#define log_debugf(format,...) log_printf(__FILE__, __LINE__, "DEBUG", format, ##__VA_ARGS__)
/**
* Return the length of the string when trimmed of trailing spaces.
* IBM MQ uses fixed length strings, so this function can be used to print
* a trimmed version of a string using the "%.*s" printf format string.
* For example, `log_printf("%.*s", trimmed_len(fw_str, 48), fw_str)`
*/
int trimmed_len(char *s, int);
#endif

View File

@@ -0,0 +1,120 @@
/*
© Copyright IBM Corporation 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"
// Headers for multi-threaded tests
#include <pthread.h>
// Start a test and log the function name
#define test_start() printf("=== RUN: %s\n", __func__)
// Indicate test has passed
#define test_pass() printf("--- PASS: %s\n", __func__)
// The length of strings used in the tests
#define STR_LEN 5
// Indicate test has failed
void test_fail(const char *test_name)
{
printf("--- FAIL: %s\n", test_name);
exit(1);
}
// Print a fixed-width string in hexadecimal
void print_hex(char fw_string[STR_LEN])
{
printf("[");
for (int i=0; i<STR_LEN; i++)
{
printf("%02x", fw_string[i]);
if (i < STR_LEN-1)
printf(",");
}
printf("]");
}
// ----------------------------------------------------------------------------
// Tests for string manipulation
// ----------------------------------------------------------------------------
void test_trimmed_len(const char *test_name, char fw_string[STR_LEN], int expected_len)
{
printf("=== RUN: %s\n", test_name);
int len;
// Create a copy of the fixed-width string
char fw_string2[STR_LEN];
memcpy(fw_string2, fw_string, STR_LEN * sizeof(char));
// Call the function under test
len = trimmed_len(fw_string, STR_LEN);
// Check the result is correct
if (len != expected_len)
{
printf("%s: Expected result to be %d; got %d\n", __func__, expected_len, len);
test_fail(test_name);
}
// Check that the original string has not been changed
for (int i=0; i<STR_LEN; i++)
{
if (fw_string[i] != fw_string2[i])
{
printf("%c-%c\n", fw_string[i], fw_string2[i]);
printf("%s: Expected string to be identical to input hex ", __func__);
print_hex(fw_string2);
printf("; got hex ");
print_hex(fw_string);
printf("\n");
test_fail(test_name);
}
}
printf("--- PASS: %s\n", test_name);
}
void test_trimmed_len_normal()
{
char fw_string[STR_LEN] = {'a','b','c',' ',' '};
test_trimmed_len(__func__, fw_string, 3);
}
void test_trimmed_len_full()
{
char fw_string[STR_LEN] = {'a','b','c','d','e'};
test_trimmed_len(__func__, fw_string, 5);
}
void test_trimmed_len_empty()
{
char fw_string[STR_LEN] = {' ',' ',' ',' ',' '};
test_trimmed_len(__func__, fw_string, 0);
}
// ----------------------------------------------------------------------------
int main()
{
// Turn on debugging for the tests
setenv("DEBUG", "true", true);
log_init("log_test.log");
test_trimmed_len_normal();
test_trimmed_len_full();
test_trimmed_len_empty();
log_close();
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2021
© Copyright IBM Corporation 2021, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,8 +34,6 @@ static MQZ_TERM_AUTHORITY mqhtpass_terminate;
#define HTPASSWD_FILE "/etc/mqm/mq.htpasswd"
#define NAME "MQ Advanced for Developers custom authentication service"
static char *trim(char *s);
/**
* Initialization and entrypoint for the dynamically loaded
* authorization installable service. It registers the addresses of the
@@ -80,7 +78,7 @@ void MQENTRY MQStart(
{
log_infof("Initializing %s", NAME);
}
log_debugf("MQStart options=%s qmgr=%s", ((Options == MQZIO_SECONDARY) ? "Secondary" : "Primary"), trim(QMgrName));
log_debugf("MQStart options=%s qmgr=%.*s", ((Options == MQZIO_SECONDARY) ? "Secondary" : "Primary"), trimmed_len(QMgrName, MQ_Q_MGR_NAME_LENGTH), QMgrName);
if (!htpass_valid_file(HTPASSWD_FILE))
{
@@ -176,11 +174,14 @@ static void MQENTRY mqhtpass_authenticate_user_csp(
// Tell the queue manager to continue trying other authorization services, as they might have the user.
*pContinuation = MQZCI_CONTINUE;
log_debugf(
"User authentication failed due to invalid user. user=%s effuser=%s applname=%s csp_user=%s cc=%d reason=%d",
trim(pIdentityContext->UserIdentifier),
trim(pApplicationContext->EffectiveUserID),
trim(pApplicationContext->ApplName),
trim(csp_user),
"User authentication failed due to invalid user. user=%.*s effuser=%.*s applname=%.*s csp_user=%s cc=%d reason=%d",
trimmed_len(pIdentityContext->UserIdentifier, MQ_USER_ID_LENGTH),
pIdentityContext->UserIdentifier,
trimmed_len(pApplicationContext->EffectiveUserID, MQ_USER_ID_LENGTH),
pApplicationContext->EffectiveUserID,
trimmed_len(pApplicationContext->ApplName, MQ_APPL_NAME_LENGTH),
pApplicationContext->ApplName,
csp_user,
*pCompCode,
*pReason);
}
@@ -192,11 +193,14 @@ static void MQENTRY mqhtpass_authenticate_user_csp(
// Tell the queue manager to stop trying other authorization services.
*pContinuation = MQZCI_STOP;
log_debugf(
"User authentication failed due to invalid password. user=%s effuser=%s applname=%s csp_user=%s cc=%d reason=%d",
trim(pIdentityContext->UserIdentifier),
trim(pApplicationContext->EffectiveUserID),
trim(pApplicationContext->ApplName),
trim(csp_user),
"User authentication failed due to invalid password. user=%.*s effuser=%.*s applname=%.*s csp_user=%s cc=%d reason=%d",
trimmed_len(pIdentityContext->UserIdentifier, MQ_USER_ID_LENGTH),
pIdentityContext->UserIdentifier,
trimmed_len(pApplicationContext->EffectiveUserID, MQ_USER_ID_LENGTH),
pApplicationContext->EffectiveUserID,
trimmed_len(pApplicationContext->ApplName, MQ_APPL_NAME_LENGTH),
pApplicationContext->ApplName,
csp_user,
*pCompCode,
*pReason);
}
@@ -227,7 +231,6 @@ static void MQENTRY mqhtpass_authenticate_user(
PMQLONG pReason)
{
char *spuser = NULL;
char *sppass = NULL;
// By default, return a warning, which indicates to MQ that this
// authorization service hasn't authenticated the user.
*pCompCode = MQCC_WARNING;
@@ -276,11 +279,14 @@ static void MQENTRY mqhtpass_authenticate_user(
else
{
log_debugf(
"User authentication failed user=%s effuser=%s applname=%s cspuser=%s cc=%d reason=%d",
trim(pIdentityContext->UserIdentifier),
trim(pApplicationContext->EffectiveUserID),
trim(pApplicationContext->ApplName),
trim(spuser),
"User authentication failed user=%.*s effuser=%.*s applname=%.*s cspuser=%s cc=%d reason=%d",
trimmed_len(pIdentityContext->UserIdentifier, MQ_USER_ID_LENGTH),
pIdentityContext->UserIdentifier,
trimmed_len(pApplicationContext->EffectiveUserID, MQ_USER_ID_LENGTH),
pApplicationContext->EffectiveUserID,
trimmed_len(pApplicationContext->ApplName, MQ_APPL_NAME_LENGTH),
pApplicationContext->ApplName,
spuser,
*pCompCode,
*pReason);
}
@@ -334,18 +340,3 @@ static void MQENTRY mqhtpass_terminate(
*pReason = MQRC_NONE;
}
/**
* Remove trailing spaces from a string.
*/
static char *trim(char *s)
{
int i;
for (i = strlen(s) - 1; i >= 0; i--)
{
if (s[i] == ' ')
s[i] = 0;
else
break;
}
return s;
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2020
© Copyright IBM Corporation 2017, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,22 +18,24 @@ limitations under the License.
package main
import (
"context"
"fmt"
"os"
"os/exec"
"os/signal"
"strings"
"github.com/ibm-messaging/mq-container/pkg/name"
)
func queueManagerHealthy() (bool, error) {
func queueManagerHealthy(ctx context.Context) (bool, error) {
name, err := name.GetQueueManagerName()
if err != nil {
return false, err
}
// Specify the queue manager name, just in case someone's created a second queue manager
// #nosec G204
cmd := exec.Command("dspmq", "-n", "-m", name)
cmd := exec.CommandContext(ctx, "dspmq", "-n", "-m", name)
// Run the command and wait for completion
out, err := cmd.CombinedOutput()
fmt.Printf("%s", out)
@@ -47,13 +49,20 @@ func queueManagerHealthy() (bool, error) {
return true, nil
}
func main() {
healthy, err := queueManagerHealthy()
func doMain() int {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()
healthy, err := queueManagerHealthy(ctx)
if err != nil {
os.Exit(2)
return 2
}
if !healthy {
os.Exit(1)
return 1
}
os.Exit(0)
return 0
}
func main() {
os.Exit(doMain())
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2019
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,44 +18,59 @@ limitations under the License.
package main
import (
"context"
"fmt"
"net"
"os"
"os/signal"
"github.com/ibm-messaging/mq-container/internal/ready"
"github.com/ibm-messaging/mq-container/pkg/name"
)
func main() {
func doMain() int {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()
// Check if runmqserver has indicated that it's finished configuration
r, err := ready.Check()
if !r || err != nil {
os.Exit(1)
return 1
}
name, err := name.GetQueueManagerName()
if err != nil {
fmt.Println(err)
os.Exit(1)
return 1
}
// Check if the queue manager has a running listener
if active, _ := ready.IsRunningAsActiveQM(name); active {
status, err := ready.Status(ctx, name)
if err != nil {
return 1
}
switch status {
case ready.StatusActiveQM:
conn, err := net.Dial("tcp", "127.0.0.1:1414")
if err != nil {
fmt.Println(err)
os.Exit(1)
return 1
}
err = conn.Close()
if err != nil {
fmt.Println(err)
}
} else if standby, _ := ready.IsRunningAsStandbyQM(name); standby {
return 0
case ready.StatusStandbyQM:
fmt.Printf("Detected queue manager running in standby mode")
os.Exit(10)
} else if replica, _ := ready.IsRunningAsReplicaQM(name); replica {
return 10
case ready.StatusReplicaQM:
fmt.Printf("Detected queue manager running in replica mode")
os.Exit(20)
} else {
os.Exit(1)
return 20
default:
return 1
}
}
func main() {
os.Exit(doMain())
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2021
© Copyright IBM Corporation 2021, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,22 +18,24 @@ limitations under the License.
package main
import (
"context"
"fmt"
"os"
"os/exec"
"os/signal"
"strings"
"github.com/ibm-messaging/mq-container/pkg/name"
)
func queueManagerStarted() (bool, error) {
func queueManagerStarted(ctx context.Context) (bool, error) {
name, err := name.GetQueueManagerName()
if err != nil {
return false, err
}
// Specify the queue manager name, just in case someone's created a second queue manager
// #nosec G204
cmd := exec.Command("dspmq", "-n", "-m", name)
cmd := exec.CommandContext(ctx, "dspmq", "-n", "-m", name)
// Run the command and wait for completion
out, err := cmd.CombinedOutput()
if err != nil {
@@ -46,13 +48,20 @@ func queueManagerStarted() (bool, error) {
return true, nil
}
func main() {
started, err := queueManagerStarted()
func doMain() int {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()
started, err := queueManagerStarted(ctx)
if err != nil {
os.Exit(2)
return 2
}
if !started {
os.Exit(1)
return 1
}
os.Exit(0)
return 0
}
func main() {
os.Exit(doMain())
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2021
© Copyright IBM Corporation 2018, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import (
"fmt"
"io/ioutil"
"os"
"strings"
"syscall"
"github.com/ibm-messaging/mq-container/internal/htpasswd"
@@ -30,7 +31,20 @@ import (
var log *logger.Logger
func getLogFormat() string {
return os.Getenv("LOG_FORMAT")
logFormat := strings.ToLower(strings.TrimSpace(os.Getenv("MQ_LOGGING_CONSOLE_FORMAT")))
//old-style env var is used.
if logFormat == "" {
logFormat = strings.ToLower(strings.TrimSpace(os.Getenv("LOG_FORMAT")))
}
if logFormat != "" && (logFormat == "basic" || logFormat == "json") {
return logFormat
} else {
//this is the case where value is either empty string or set to something other than "basic"/"json"
logFormat = "basic"
}
return logFormat
}
func getDebug() bool {
@@ -77,6 +91,7 @@ func logTermination(args ...interface{}) {
// Write the message to the termination log. This is not the default place
// that Kubernetes will look for termination information.
log.Debugf("Writing termination message: %v", msg)
// #nosec G306 - its a read by owner/s group, and pose no harm.
err := ioutil.WriteFile("/run/termination-log", []byte(msg), 0660)
if err != nil {
log.Debug(err)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2021
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -46,6 +46,7 @@ func logTermination(args ...interface{}) {
// Write the message to the termination log. This is not the default place
// that Kubernetes will look for termination information.
log.Debugf("Writing termination message: %v", msg)
// #nosec G306 - its a read by owner/s group, and pose no harm.
err := ioutil.WriteFile("/run/termination-log", []byte(msg), 0660)
if err != nil {
log.Debug(err)
@@ -58,7 +59,20 @@ func logTermination(args ...interface{}) {
}
func getLogFormat() string {
return os.Getenv("LOG_FORMAT")
logFormat := strings.ToLower(strings.TrimSpace(os.Getenv("MQ_LOGGING_CONSOLE_FORMAT")))
//old-style env var is used.
if logFormat == "" {
logFormat = strings.ToLower(strings.TrimSpace(os.Getenv("LOG_FORMAT")))
}
if logFormat != "" && (logFormat == "basic" || logFormat == "json") {
return logFormat
} else {
//this is the case where value is either empty string or set to something other than "basic"/"json"
logFormat = "basic"
}
return logFormat
}
// formatBasic formats a log message parsed from JSON, as "basic" text
@@ -81,6 +95,94 @@ func formatBasic(obj map[string]interface{}) string {
}
// Convert time zone information from some logs (e.g. Liberty) for consistency
obj["ibm_datetime"] = strings.Replace(obj["ibm_datetime"].(string), "+0000", "Z", 1)
// Escape any new-line characters, so that we don't get multi-line messages messing up the output
obj["message"] = strings.ReplaceAll(obj["message"].(string), "\n", "\\n")
if obj["type"] != nil && (obj["type"] == "liberty_trace") {
timeStamp := obj["ibm_datetime"]
threadID := ""
srtModuleName := ""
logLevel := ""
ibmClassName := ""
srtIbmClassName := ""
ibmMethodName := ""
message := ""
if obj["loglevel"] != nil {
//threadID is captured below
if obj["ibm_threadId"] != nil {
threadID = obj["ibm_threadId"].(string)
}
//logLevel character to be mirrored in console web server logging is decided below
logLevelTmp := obj["loglevel"].(string)
switch logLevelTmp {
case "AUDIT":
logLevel = "A"
case "INFO":
logLevel = "I"
case "EVENT":
logLevel = "1"
case "ENTRY":
logLevel = ">"
case "EXIT":
logLevel = "<"
case "FINE":
logLevel = "1"
case "FINER":
logLevel = "2"
case "FINEST":
logLevel = "3"
default:
logLevel = string(logLevelTmp[0])
}
//This is a 13 characters string present in extracted out of module node
if obj["module"] != nil {
srtModuleNameArr := strings.Split(obj["module"].(string), ".")
arrLen := len(srtModuleNameArr)
srtModuleName = srtModuleNameArr[arrLen-1]
if len(srtModuleName) > 13 {
srtModuleName = srtModuleName[0:13]
}
}
if obj["ibm_className"] != nil {
ibmClassName = obj["ibm_className"].(string)
//A 13 character string is extracted from class name. This is required for FINE, FINER & FINEST log lines
ibmClassNameArr := strings.Split(ibmClassName, ".")
arrLen := len(ibmClassNameArr)
srtIbmClassName = ibmClassNameArr[arrLen-1]
if len(srtModuleName) > 13 {
srtIbmClassName = srtIbmClassName[0:13]
}
}
if obj["ibm_methodName"] != nil {
ibmMethodName = obj["ibm_methodName"].(string)
}
if obj["message"] != nil {
message = obj["message"].(string)
}
//For AUDIT & INFO logging
if logLevel == "A" || logLevel == "I" {
return fmt.Sprintf("%s %s %-13s %s %s %s %s\n", timeStamp, threadID, srtModuleName, logLevel, ibmClassName, ibmMethodName, message)
}
//For EVENT logLevel
if logLevelTmp == "EVENT" {
return fmt.Sprintf("%s %s %-13s %s %s\n", timeStamp, threadID, srtModuleName, logLevel, message)
}
//For ENTRY & EXIT
if logLevel == ">" || logLevel == "<" {
return fmt.Sprintf("%s %s %-13s %s %s %s\n", timeStamp, threadID, srtModuleName, logLevel, ibmMethodName, message)
}
//For deeper log levels
if logLevelTmp == "FINE" || logLevel == "2" || logLevel == "3" {
return fmt.Sprintf("%s %s %-13s %s %s %s %s\n", timeStamp, threadID, srtIbmClassName, logLevel, ibmClassName, ibmMethodName, message)
}
}
}
return fmt.Sprintf("%s %s\n", obj["ibm_datetime"], obj["message"])
}
@@ -131,6 +233,11 @@ func configureLogger(name string) (mirrorFunc, error) {
return nil, err
}
return func(msg string, isQMLog bool) bool {
arrLoggingConsoleExcludeIds := strings.Split(strings.ToUpper(os.Getenv("MQ_LOGGING_CONSOLE_EXCLUDE_ID")), ",")
if isExcludedMsgIdPresent(msg, arrLoggingConsoleExcludeIds) {
//If excluded id is present do not mirror it, return back
return false
}
// Check if the message is JSON
if len(msg) > 0 && msg[0] == '{' {
obj, err := processLogMessage(msg)
@@ -155,6 +262,11 @@ func configureLogger(name string) (mirrorFunc, error) {
return nil, err
}
return func(msg string, isQMLog bool) bool {
arrLoggingConsoleExcludeIds := strings.Split(strings.ToUpper(os.Getenv("MQ_LOGGING_CONSOLE_EXCLUDE_ID")), ",")
if isExcludedMsgIdPresent(msg, arrLoggingConsoleExcludeIds) {
//If excluded id is present do not mirror it, return back
return false
}
// Check if the message is JSON
if len(msg) > 0 && msg[0] == '{' {
// Parse the JSON message, and print a simplified version
@@ -165,7 +277,7 @@ func configureLogger(name string) (mirrorFunc, error) {
if err != nil {
log.Printf("Failed to unmarshall JSON in log message - %v", err)
} else {
fmt.Printf(formatBasic(obj))
fmt.Print(formatBasic(obj))
}
} else {
// The log being mirrored isn't JSON, so just print it.
@@ -197,6 +309,16 @@ func filterQMLogMessage(obj map[string]interface{}) bool {
return false
}
// Function to check if ids provided in MQ_LOGGING_CONSOLE_EXCLUDE_ID are present in given log line or not
func isExcludedMsgIdPresent(msg string, envExcludeIds []string) bool {
for _, id := range envExcludeIds {
if id != "" && strings.Contains(msg, strings.TrimSpace(id)) {
return true
}
}
return false
}
func logDiagnostics() {
if getDebug() {
log.Debug("--- Start Diagnostics ---")
@@ -238,3 +360,73 @@ func logDiagnostics() {
log.Debug("--- End Diagnostics ---")
}
}
// Returns the value of MQ_LOGGING_CONSOLE_SOURCE environment variable
func getMQLogConsoleSource() string {
return strings.ToLower(strings.TrimSpace(os.Getenv("MQ_LOGGING_CONSOLE_SOURCE")))
}
// Function to check if valid values are provided for environment variable MQ_LOGGING_CONSOLE_SOURCE. If not valid, main program throws a warning to console
func isLogConsoleSourceValid() bool {
mqLogSource := getMQLogConsoleSource()
retValue := false
//If nothing is set, we will mirror qmgr, so valid
if mqLogSource == "" {
return true
}
logConsoleSource := strings.Split(mqLogSource, ",")
//This will find out if the environment variable contains permitted values and is comma separated
for _, src := range logConsoleSource {
switch strings.TrimSpace(src) {
//If it is a permitted value, it is valid. Keep it as true, but dont return it. We may encounter something junk soon
case "qmgr", "web", "":
retValue = true
//If invalid entry arrives in-between/anywhere, just return false, there is no turning back
default:
return false
}
}
return retValue
}
// To check which all logs have to be mirrored
func checkLogSourceForMirroring(source string) bool {
logsrcs := getMQLogConsoleSource()
//Nothing set, this is when we mirror qmgr
if logsrcs == "" {
if source == "qmgr" {
return true
} else {
return false
}
}
//Split the csv environment value so that we get an accurate comparison instead of a contains() check
logSrcArr := strings.Split(logsrcs, ",")
//Iterate through the array to decide on mirroring
for _, arr := range logSrcArr {
switch strings.TrimSpace(arr) {
case "qmgr":
//If value of source is qmgr and it exists in environment variable, mirror qmgr logs
if source == "qmgr" {
return true
}
case "web":
//If value of source is web and it exists in environment variable, and mirror web logs
if source == "web" {
//If older environment variable is set make sure to print appropriate message
if os.Getenv("MQ_ENABLE_EMBEDDED_WEB_SERVER_LOG") != "" {
log.Println("Environment variable MQ_ENABLE_EMBEDDED_WEB_SERVER_LOG has now been replaced. Use MQ_LOGGING_CONSOLE_SOURCE instead.")
}
return true
}
}
}
return false
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2020
© Copyright IBM Corporation 2020, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package main
import (
"encoding/json"
"fmt"
"os"
"strings"
"testing"
)
@@ -53,3 +54,86 @@ func TestFormatBasic(t *testing.T) {
})
}
}
// This test covers for functions isLogConsoleSourceValid() & checkLogSourceForMirroring()
var mqLogSourcesTests = []struct {
testNum int
logsrc string
exptValid bool
exptQmgrSrc bool
exptWebSrc bool
}{
{1, "qmgr,web", true, true, true},
{2, "qmgr", true, true, false},
{3, "web,qmgr", true, true, true},
{4, "web", true, false, true},
{5, " ", true, true, false},
{6, "QMGR,WEB", true, true, true},
{7, "qmgr, ", true, true, false},
{8, "qmgr , web", true, true, true},
{9, "qmgr,dummy", false, true, false},
{10, "fake,dummy", false, false, false},
{11, "qmgr,fake,dummy", false, true, false},
{12, "fake,dummy,web", false, false, true},
{13, "true", false, false, false},
{14, "false", false, false, false},
{15, "", true, true, false},
}
func TestLoggingConsoleSourceInputs(t *testing.T) {
for _, mqlogsrctest := range mqLogSourcesTests {
err := os.Setenv("MQ_LOGGING_CONSOLE_SOURCE", mqlogsrctest.logsrc)
if err != nil {
t.Error(err)
}
isValid := isLogConsoleSourceValid()
if isValid != mqlogsrctest.exptValid {
t.Errorf("Expected return value from isLogConsoleSourceValid() is %v for MQ_LOGGING_CONSOLE_SOURCE='%v', got %v\n", mqlogsrctest.exptValid, mqlogsrctest.logsrc, isValid)
}
isLogSrcQmgr := checkLogSourceForMirroring("qmgr")
if isLogSrcQmgr != mqlogsrctest.exptQmgrSrc {
t.Errorf("Expected return value from checkLogSourceForMirroring() is %v for MQ_LOGGING_CONSOLE_SOURCE='%v', got %v\n", mqlogsrctest.exptQmgrSrc, mqlogsrctest.logsrc, isLogSrcQmgr)
}
isLogSrcWeb := checkLogSourceForMirroring("web")
if isLogSrcWeb != mqlogsrctest.exptWebSrc {
t.Errorf("Expected return value from checkLogSourceForMirroring() is %v for MQ_LOGGING_CONSOLE_SOURCE='%v', got %v\n", mqlogsrctest.exptWebSrc, mqlogsrctest.logsrc, isLogSrcWeb)
}
}
}
// This test covers for function isExcludedMsgIdPresent()
var mqExcludeIDTests = []struct {
testNum int
exculdeIDsArr []string
expectedRetVal bool
logEntry string
}{
{
1,
[]string{"AMQ5051I", "AMQ5037I", "AMQ5975I"},
true,
"{\"ibm_messageId\":\"AMQ5051I\",\"ibm_arithInsert1\":0,\"ibm_arithInsert2\":1,\"message\":\"AMQ5051I: The queue manager task 'AUTOCONFIG' has started.\"}",
},
{
2,
[]string{"AMQ5975I", "AMQ5037I"},
false,
"{\"ibm_messageId\":\"AMQ5051I\",\"ibm_arithInsert1\":0,\"ibm_arithInsert2\":1,\"message\":\"AMQ5051I: The queue manager task 'AUTOCONFIG' has started.\"}",
},
{
3,
[]string{""},
false,
"{\"ibm_messageId\":\"AMQ5051I\",\"ibm_arithInsert1\":0,\"ibm_arithInsert2\":1,\"message\":\"AMQ5051I: The queue manager task 'AUTOCONFIG' has started.\"}",
},
}
func TestIsExcludedMsgIDPresent(t *testing.T) {
for _, excludeIDTest := range mqExcludeIDTests {
retVal := isExcludedMsgIdPresent(excludeIDTest.logEntry, excludeIDTest.exculdeIDsArr)
if retVal != excludeIDTest.expectedRetVal {
t.Errorf("%v. Expected return value from isExcludedMsgIdPresent() is %v for MQ_LOGGING_CONSOLE_EXCLUDE_ID='%v', got %v\n",
excludeIDTest.testNum, excludeIDTest.expectedRetVal, excludeIDTest.exculdeIDsArr, retVal)
}
}
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2021
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import (
"os"
"sync"
"github.com/ibm-messaging/mq-container/internal/fips"
"github.com/ibm-messaging/mq-container/internal/ha"
"github.com/ibm-messaging/mq-container/internal/metrics"
"github.com/ibm-messaging/mq-container/internal/ready"
@@ -144,6 +145,9 @@ func doMain() error {
// Print out versioning information
logVersionInfo()
// Determine FIPS compliance level
fips.ProcessFIPSType(log)
keyLabel, defaultCmsKeystore, defaultP12Truststore, err := tls.ConfigureDefaultTLSKeystores()
if err != nil {
logTermination(err)
@@ -156,6 +160,11 @@ func doMain() error {
return err
}
//Validate MQ_LOG_CONSOLE_SOURCE variable
if !isLogConsoleSourceValid() {
log.Println("One or more invalid value is provided for MQ_LOGGING_CONSOLE_SOURCE. Allowed values are 'qmgr' & 'web' in csv format")
}
err = postInit(name, keyLabel, defaultP12Truststore)
if err != nil {
logTermination(err)
@@ -170,6 +179,9 @@ func doMain() error {
}
}
// Post FIPS initialization processing
fips.PostInit(log)
enableTraceCrtmqm := os.Getenv("MQ_ENABLE_TRACE_CRTMQM")
if enableTraceCrtmqm == "true" || enableTraceCrtmqm == "1" {
err = startMQTrace()
@@ -203,17 +215,24 @@ func doMain() error {
log.Debug("Cancel log mirroring")
cancelMirror()
}()
// TODO: Use the error channel
_, err = mirrorSystemErrorLogs(ctx, &wg, mf)
if err != nil {
logTermination(err)
return err
}
_, err = mirrorQueueManagerErrorLogs(ctx, &wg, name, newQM, mf)
if err != nil {
logTermination(err)
return err
//For mirroring mq system logs and qm logs, if environment variable is set
if checkLogSourceForMirroring("qmgr") {
//Mirror MQ system logs
_, err = mirrorSystemErrorLogs(ctx, &wg, mf)
if err != nil {
logTermination(err)
return err
}
//Mirror queue manager logs
_, err = mirrorQueueManagerErrorLogs(ctx, &wg, name, newQM, mf)
if err != nil {
logTermination(err)
return err
}
}
if *devFlag {
_, err = mirrorHTPasswdLogs(ctx, &wg, name, newQM, mf)
if err != nil {
@@ -221,10 +240,12 @@ func doMain() error {
return err
}
}
// Recommended to use this option in conjunction with setting WLP_LOGGING_MESSAGE_FORMAT=JSON
mirrorWebLog := os.Getenv("MQ_ENABLE_EMBEDDED_WEB_SERVER_LOG")
if mirrorWebLog == "true" || mirrorWebLog == "1" {
_, err = mirrorWebServerLogs(ctx, &wg, name, newQM, mf)
//For mirroring web server logs if source variable is set
if checkLogSourceForMirroring("web") {
// Always log from the start of the web server messages.log, as
// Liberty resets it.
_, err = mirrorWebServerLogs(ctx, &wg, name, true, mf)
if err != nil {
logTermination(err)
return err

View File

@@ -95,6 +95,7 @@ func mirrorLog(ctx context.Context, wg *sync.WaitGroup, path string, fromStart b
// the file is open before the queue manager is created or started.
// Otherwise, there would be the potential for a nearly-full file to
// rotate before the goroutine had a chance to open it.
// #nosec G304 - no harm, we open readonly and check error.
f, err = os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
return nil, err
@@ -122,6 +123,7 @@ func mirrorLog(ctx context.Context, wg *sync.WaitGroup, path string, fromStart b
return
}
log.Debugf("File exists: %v, %v", path, fi.Size())
// #nosec G304 - no harm, we open readonly and check error.
f, err = os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
log.Error(err)
@@ -169,6 +171,7 @@ func mirrorLog(ctx context.Context, wg *sync.WaitGroup, path string, fromStart b
}
// Re-open file
log.Debugf("Re-opening error log file %v", path)
// #nosec G304 - no harm, we open readonly and check error.
f, err = os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
log.Error(err)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2019
© Copyright IBM Corporation 2018, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package main
import (
"os"
"github.com/ibm-messaging/mq-container/internal/fips"
"github.com/ibm-messaging/mq-container/internal/tls"
)
@@ -25,6 +26,15 @@ import (
func postInit(name, keyLabel string, p12Truststore tls.KeyStoreData) error {
enableWebServer := os.Getenv("MQ_ENABLE_EMBEDDED_WEB_SERVER")
if enableWebServer == "true" || enableWebServer == "1" {
// Enable FIPS for MQ Web Server if asked for.
if fips.IsFIPSEnabled() {
err := configureFIPSWebServer(p12Truststore)
if err != nil {
return err
}
}
// Configure the web server (if enabled)
webKeystore, err := configureWebServer(keyLabel, p12Truststore)
if err != nil {
@@ -35,6 +45,7 @@ func postInit(name, keyLabel string, p12Truststore tls.KeyStoreData) error {
if len(p12Truststore.TrustedCerts) == 0 {
webTruststoreRef = "MQWebKeyStore"
}
// Start the web server, in the background (if installed)
// WARNING: No error handling or health checking available for the web server
go func() {

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2020
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ limitations under the License.
package main
import (
"context"
"fmt"
"io/ioutil"
"os"
@@ -54,23 +55,36 @@ func createDirStructure() error {
func createQueueManager(name string, devMode bool) (bool, error) {
log.Printf("Creating queue manager %v", name)
// Run 'dspmqinf' to check if 'mqs.ini' configuration file exists
// If command succeeds, the queue manager (or standby queue manager) has already been created
_, _, err := command.Run("dspmqinf", name)
if err == nil {
log.Printf("Detected existing queue manager %v", name)
return false, nil
}
mounts, err := containerruntime.GetMounts()
if err != nil {
log.Printf("Error getting mounts for queue manager")
return false, err
}
dataDir := getQueueManagerDataDir(mounts, name)
// Run 'dspmqinf' to check if 'mqs.ini' configuration file exists
// If command succeeds, the queue manager (or standby queue manager) has already been created
_, _, err = command.Run("dspmqinf", name)
if err == nil {
log.Printf("Detected existing queue manager %v", name)
// Check if MQ_QMGR_LOG_FILE_PAGES matches the value set in qm.ini
lfp := os.Getenv("MQ_QMGR_LOG_FILE_PAGES")
if lfp != "" {
qmIniBytes, err := readQMIni(dataDir)
if err != nil {
log.Printf("Error reading qm.ini : %v", err)
return false, err
}
if !validateLogFilePageSetting(qmIniBytes, lfp) {
log.Println("Warning: the value of MQ_QMGR_LOG_FILE_PAGES does not match the value of 'LogFilePages' in the qm.ini. This setting cannot be altered after Queue Manager creation.")
}
}
return false, nil
}
// Check if 'qm.ini' configuration file exists for the queue manager
// TODO : handle possible race condition - use a file lock?
dataDir := getQueueManagerDataDir(mounts, name)
_, err = os.Stat(filepath.Join(dataDir, "qm.ini"))
if err != nil {
// If 'qm.ini' is not found - run 'crtmqm' to create a new queue manager
@@ -95,6 +109,25 @@ func createQueueManager(name string, devMode bool) (bool, error) {
return true, nil
}
//readQMIni reads the qm.ini file and returns it as a byte array
//This function is specific to comply with the nosec.
func readQMIni(dataDir string) ([]byte, error) {
qmgrDir := filepath.Join(dataDir, "qm.ini")
// #nosec G304 - qmgrDir filepath is derived from dspmqinf
iniFileBytes, err := ioutil.ReadFile(qmgrDir)
if err != nil {
return nil, err
}
return iniFileBytes, err
}
//validateLogFilePageSetting validates if the specified logFilePage number is equal to the existing value in the qm.ini
func validateLogFilePageSetting(iniFileBytes []byte, logFilePages string) bool {
lfpString := "LogFilePages=" + logFilePages
qminiConfigStr := string(iniFileBytes)
return strings.Contains(qminiConfigStr, lfpString)
}
func updateCommandLevel() error {
level, ok := os.LookupEnv("MQ_CMDLEVEL")
if ok && level != "" {
@@ -131,17 +164,18 @@ func startQueueManager(name string) error {
func stopQueueManager(name string) error {
log.Println("Stopping queue manager")
qmGracePeriod := os.Getenv("MQ_GRACE_PERIOD")
isStandby, err := ready.IsRunningAsStandbyQM(name)
status, err := ready.Status(context.Background(), name)
if err != nil {
log.Printf("Error getting status for queue manager %v: %v", name, err.Error())
return err
}
isStandby := status.StandbyQM()
args := []string{"-w", "-r", "-tp", qmGracePeriod, name}
if os.Getenv("MQ_MULTI_INSTANCE") == "true" {
if isStandby {
args = []string{"-x", name}
} else {
args = []string{"-s", "-w", "-r", "-tp", qmGracePeriod, name}
args = []string{"-s", "-w", "-tp", qmGracePeriod, name}
}
}
out, rc, err := command.Run("endmqm", args...)
@@ -237,6 +271,14 @@ func getCreateQueueManagerArgs(mounts map[string]string, name string, devMode bo
if _, ok := mounts["/mnt/mqm-data"]; ok {
args = append(args, "-md", "/mnt/mqm-data/qmgrs")
}
if os.Getenv("MQ_QMGR_LOG_FILE_PAGES") != "" {
_, err = strconv.Atoi(os.Getenv("MQ_QMGR_LOG_FILE_PAGES"))
if err != nil {
log.Printf("Error processing MQ_QMGR_LOG_FILE_PAGES, the default value for LogFilePages will be used. Err: %v", err)
} else {
args = append(args, "-lf", os.Getenv("MQ_QMGR_LOG_FILE_PAGES"))
}
}
args = append(args, name)
return args
}
@@ -286,7 +328,8 @@ func updateQMini(qmname string) error {
if strings.Contains(qminiConfigStr, "ServiceComponent:") {
var re = regexp.MustCompile(`(?m)^.*ServiceComponent.*$\s^.*Service.*$\s^.*Name.*$\s^.*Module.*$\s^.*ComponentDataSize.*$`)
curFile := re.ReplaceAllString(qminiConfigStr, "")
// #nosec G304 - qmgrDir filepath is derived from dspmqinf
// #nosec G304 G306 - qmgrDir filepath is derived from dspmqinf and
// its a read by owner/s group, and pose no harm.
err := ioutil.WriteFile(qmgrDir, []byte(curFile), 0660)
if err != nil {
return err

View File

@@ -0,0 +1,86 @@
/*
© Copyright IBM Corporation 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"io/ioutil"
"testing"
)
func Test_validateLogFilePageSetting(t *testing.T) {
type args struct {
iniFilePath string
isValid bool
logFilePagesValue string
}
tests := []struct {
name string
args args
}{
{
name: "TestLogFilePages1",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_1.ini",
isValid: true,
logFilePagesValue: "1235",
},
},
{
name: "TestLogFilePages2",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_2.ini",
isValid: true,
logFilePagesValue: "2224",
},
},
{
name: "TestLogFilePages3",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_3.ini",
isValid: false,
logFilePagesValue: "1235",
},
},
{
name: "TestLogFilePages4",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_4.ini",
isValid: false,
logFilePagesValue: "1235",
},
},
{
name: "TestLogFilePages5",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_5.ini",
isValid: false,
logFilePagesValue: "1235",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
iniFileBytes, err := ioutil.ReadFile(tt.args.iniFilePath)
if err != nil {
t.Fatal(err)
}
validate := validateLogFilePageSetting(iniFileBytes, tt.args.logFilePagesValue)
if validate != tt.args.isValid {
t.Fatalf("Expected ini file validation output to be %v got %v", tt.args.isValid, validate)
}
})
}
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2018
© Copyright IBM Corporation 2017, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -33,8 +33,8 @@ func signalHandler(qmgr string) chan int {
control := make(chan int)
// Use separate channels for the signals, to avoid SIGCHLD signals swamping
// the buffer, and preventing other signals.
stopSignals := make(chan os.Signal)
reapSignals := make(chan os.Signal)
stopSignals := make(chan os.Signal, 1)
reapSignals := make(chan os.Signal, 1)
signal.Notify(stopSignals, syscall.SIGTERM, syscall.SIGINT)
go func() {
for {

View File

@@ -0,0 +1,9 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogFilePages=1235
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,9 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogFilePages=2224
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,9 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogFilePages=6002
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,8 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,8 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogBufferPages=1235
LogWriteIntegrity=TripleWrite

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2020
© Copyright IBM Corporation 2018, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -197,3 +197,25 @@ func configureWebServer(keyLabel string, p12Truststore tls.KeyStoreData) (string
return webKeystore, err
}
// Configure FIPS mode for MQ Web Server
func configureFIPSWebServer(p12TrustStore tls.KeyStoreData) error {
var errOut error
// Need to update jvm.options file of MQ Web Server. We don't update the jvm.options file
// in /etc/mqm/web/installations/Installation1/servers/mqweb directory. Instead we update
// the one in /etc/mqm/web/installations/Installation1/servers/mqweb/configDropins/defaults.
// During runtime MQ Web Server merges the data from two files.
mqwebJvmOptsDir := "/etc/mqm/web/installations/Installation1/servers/mqweb/configDropins/defaults"
_, errOut = os.Stat(mqwebJvmOptsDir)
if errOut == nil {
// Update the jvm.options file using the data from template file. Tell the MQ Web Server
// use a FIPS provider by setting "-Dcom.ibm.jsse2.usefipsprovider=true" and then tell it
// use a specific FIPS provider by setting "Dcom.ibm.jsse2.usefipsProviderName=IBMJCEPlusFIPS".
errOut = mqtemplate.ProcessTemplateFile(mqwebJvmOptsDir+"/jvm.options.tpl",
mqwebJvmOptsDir+"/jvm.options", map[string]string{
"FipsProvider": "true",
"FipsProviderName": "IBMJCEPlusFIPS",
}, log)
}
return errOut
}

View File

@@ -1,6 +1,6 @@
###########################################################################################################################################################
# MQ_VERSION is the fully qualified MQ version number to build
MQ_VERSION ?= 9.2.4.0
MQ_VERSION ?= 9.3.2.1
###########################################################################################################################################################

36
docs/building.md Normal file → Executable file
View File

@@ -4,58 +4,44 @@
You need to have the following tools installed:
* [Docker](https://www.docker.com/) V17.06.1 or later, or [Podman](https://podman.io) V1.0 or later
* [Docker](https://www.docker.com/) 17.06.1 or later, or [Podman](https://podman.io) 1.0 or later (Podman 4.1 on macOS).
* [GNU make](https://www.gnu.org/software/make/)
If you are working in the Windows Subsystem for Linux, follow [this guide by Microsoft to set up Docker](https://blogs.msdn.microsoft.com/commandline/2017/12/08/cross-post-wsl-interoperability-with-docker/) first.
You will also need a [Red Hat Account](https://access.redhat.com) to be able to access the Red Hat Registry.
## Building a production image
From MQ 9.2.X, the MQ container adds support for MQ Long Term Support (LTS) **production licensed** releases.
### MQ Continuous Delivery (CD)
### Building MQ 9.3 Long Term Support (LTS) and Continuous Delivery (CD)
This procedure works for building the MQ Continuous Delivery release, on `amd64`, `ppc64le` and `s390x` architectures.
**Note**: MQ 9.3 is the latest MQ version with MQ Long Term Support (LTS), as well as being the latest Continuous Delivery (CD) version.
The procedure below is for building the 9.3 release, on `amd64`, `ppc64le` and `s390x` architectures.
1. Create a `downloads` directory in the root of this repository
2. Download MQ from [IBM Passport Advantage](https://www.ibm.com/software/passportadvantage/) or [IBM Fix Central](https://www.ibm.com/support/fixcentral), and place the downloaded file (for example, `IBM_MQ_9.2.4_LINUX_X86-64_NOINST.tar.gz`) in the `downloads` directory
3. Login to the Red Hat Registry: `docker login registry.redhat.io` using your Customer Portal credentials.
2. Download MQ from [IBM Passport Advantage](https://www.ibm.com/software/passportadvantage/). Identify the correct 'Long Term Support Release for Containers' eImage part number for your architecture from the 9.3.0 LTS tab at https://www.ibm.com/support/pages/downloading-ibm-mq-930
3. Ensure the `tar.gz` file is in the `downloads` directory
4. Run `make build-advancedserver`
> **Warning**: Note that from MQ 9.2.X CD, the MQ container build uses a 'No-Install' MQ Package, available under `IBM MQ V9.2.x Continuous Delivery Release components eAssembly, part no. CJ7CNML`
If you have an MQ archive file with a different file name, you can specify a particular file (which must be in the `downloads` directory). You should also specify the MQ version, so that the resulting image is tagged correctly, for example:
```bash
MQ_ARCHIVE=mq-1.2.3.4.tar.gz MQ_VERSION=1.2.3.4 make build-advancedserver
```
### MQ Long Term Support (LTS)
### Building previous MQ Long Term Support (LTS)
This procedure works for building the MQ Long Term Support release, on `amd64`, `ppc64le` and `s390x` architectures.
**Note**: MQ 9.3 is the latest MQ version with MQ Long Term Support (LTS), as well as being the latest Continuous Delivery (CD) version. Therefore, to build build 9.3.0.X, follow the [instructions above for MQ 9.3](#building-mq-93-long-term-support-lts-and-continuous-delivery-cd).
1. Create a `downloads` directory in the root of this repository
2. Download MQ from [IBM Passport Advantage](https://www.ibm.com/software/passportadvantage/) or [IBM Fix Central](https://www.ibm.com/support/fixcentral), and place the downloaded file (for example, `9.2.0.1-IBM-MQ-Advanced-Non-Install-LinuxX86.tar.gz`) in the `downloads` directory
3. Login to the Red Hat Registry: `docker login registry.redhat.io` using your Customer Portal credentials.
4. Run `LTS=true make build-advancedserver`
> **Warning**: Note that from MQ 9.2 LTS, the MQ container build uses a 'No-Install' MQ Package, available under `IBM MQ V9.2 Long Term Support Release components eAssembly, part no. CXXXXXX`
If you have an MQ archive file with a different file name, you can specify a particular file (which must be in the `downloads` directory). You should also specify the MQ version, so that the resulting image is tagged correctly, for example:
```bash
MQ_ARCHIVE=mq-1.2.3.4.tar.gz MQ_VERSION=1.2.3.4 LTS=true make build-advancedserver
```
However, if you wish to build the previous MQ LTS, use the [instructions](https://github.ibm.com/mq-cloudpak/mq-container/blob/v9.2.0.x-eus/docs/building.md#mq-long-term-support-lts) in the `v9.2.0.x-eus` branch.
## Building a developer image
Login to the Red Hat Registry: `docker login registry.redhat.io` using your Customer Portal credentials.
Run `make build-devserver`, which will download the latest version of MQ Advanced for Developers from IBM developerWorks. This is currently only available on the `amd64` architecture.
You can use the environment variable `MQ_ARCHIVE_DEV` to specify an alternative local file to install from (which must be in the `downloads` directory).
## Installed components
This image includes the core MQ server, Java, language packs, GSKit, and web server. This is configured in the `Generate MQ package in INSTALLATION_DIR` section [here](../install-mq.sh), with the configured options being picked up at build time.
This image includes the core MQ server, Java, language packs, GSKit, and web server. This is configured in the `mq-redux` build stage in `Dockerfile-server`.

View File

@@ -34,7 +34,7 @@ Two channels are created, one for administration, the other for normal messaging
## Web Console
By default the MQ Advanced for Developers image will start the IBM MQ Web Console that allows you to administer your Queue Manager running on your container. When the web console has been started, you can access it by opening a web browser and navigating to https://<Container IP>:9443/ibmmq/console. Where <Container IP> is replaced by the IP address of your running container.
By default the MQ Advanced for Developers image will start the IBM MQ Web Console that allows you to administer your Queue Manager running on your container. When the web console has been started, you can access it by opening a web browser and navigating to `https://<Container IP>:9443/ibmmq/console`. Where `<Container IP>` is replaced by the IP address of your running container.
When you navigate to this page you may be presented with a security exception warning. This happens because, by default, the web console creates a self-signed certificate to use for the HTTPS operations. This certificate is not trusted by your browser and has an incorrect distinguished name.

View File

@@ -16,5 +16,5 @@ docker run \
--env LICENSE=accept \
--env MQ_QMGR_NAME=QM1 \
--detach \
ibm-mqadvanced-server:9.2.4.0-amd64
ibm-mqadvanced-server:9.3.2.1-amd64
```

View File

@@ -2,10 +2,9 @@
## Prerequisites
You need to ensure you have the following tools installed:
* [Docker](https://www.docker.com/)
* [Docker](https://www.docker.com/) 19.03 or higher (API version 1.40)
* [GNU make](https://www.gnu.org/software/make/)
* [Go](https://golang.org/) - only needed for running the tests
* [dep](https://github.com/golang/dep) (official Go dependency management tool) - needed to prepare for running the tests
## Running the tests
There are two main sets of tests:
@@ -18,14 +17,14 @@ There are two main sets of tests:
The Docker tests can be run locally on a machine with Docker. For example:
```
make devserver
make advancedserver
make test-devserver
make test-advancedserver
```
You can specify the image to use directly by using the `MQ_IMAGE_ADVANCEDSERVER` or `MQ_IMAGE_DEVSERVER` variables, for example:
```
MQ_IMAGE_ADVANCEDSERVER=ibm-mqadvanced-server:9.2.4.0-amd64 make test-advancedserver
MQ_IMAGE_ADVANCEDSERVER=ibm-mqadvanced-server:9.3.2.1-amd64 make test-advancedserver
```
You can pass parameters to `go test` with an environment variable. For example, to run the "TestGoldenPath" test, run the following command:

View File

@@ -14,7 +14,7 @@ docker run \
--publish 1414:1414 \
--publish 9443:9443 \
--detach \
ibmcom/mq
icr.io/ibm-messaging/mq
```
## Running with the default configuration and a volume
@@ -34,7 +34,7 @@ docker run \
--publish 9443:9443 \
--detach \
--volume qm1data:/mnt/mqm \
ibmcom/mq
icr.io/ibm-messaging/mq
```
The Docker image always uses `/mnt/mqm` for MQ data, which is correctly linked for you under `/var/mqm` at runtime. This is to handle problems with file permissions on some platforms.
@@ -51,7 +51,7 @@ docker run \
--publish 9443:9443 \
--publish 9157:9157 \
--detach \
ibmcom/mq
icr.io/ibm-messaging/mq
```
## Customizing the queue manager configuration
@@ -60,14 +60,14 @@ You can customize the configuration in several ways:
1. For getting started, you can use the [default developer configuration](developer-config.md), which is available out-of-the-box for the MQ Advanced for Developers image
2. By creating your own image and adding your own MQSC file into the `/etc/mqm` directory on the image. This file will be run when your queue manager is created.
3. By using [remote MQ administration](https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.2.0/com.ibm.mq.adm.doc/q021090_.htm), via an MQ command server, the MQ HTTP APIs, or using a tool such as the MQ web console or MQ Explorer.
3. By using [remote MQ administration](https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.3.0/com.ibm.mq.adm.doc/q021090_.htm), via an MQ command server, the MQ HTTP APIs, or using a tool such as the MQ web console or MQ Explorer.
Note that a listener is always created on port 1414 inside the container. This port can be mapped to any port on the Docker host.
The following is an *example* `Dockerfile` for creating your own pre-configured image, which adds a custom MQ configuration file:
```dockerfile
FROM ibmcom/mq
FROM icr.io/ibm-messaging/mq
USER 1001
COPY 20-config.mqsc /etc/mqm/
```
@@ -112,3 +112,5 @@ For example, if you have an identity certificate you wish to add with the label
This can be achieved by either mounting the directories or files into the container when you run it or by baking the files into the correct location in the image.
If you supply multiple identity certificates then the first label alphabetically will be chosen as the certificate to be used by the MQ Console and the default certificate for the queue manager. If you wish to use a different certificate on the queue manager then you can change the certificate to use at runtime by executing the MQSC command `ALTER QMGR CERTLABL('<newlabel>')`
It must be noted that queue manager certificate with a Subject Distinguished Name (DN) same as it's Issuer certificate (CA) is not supported. Certificates must have a unique Subject Distinguished Name.

View File

@@ -1,4 +1,4 @@
* © Copyright IBM Corporation 2019
* © Copyright IBM Corporation 2019, 2022
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,4 +16,5 @@
* Set the keystore location for the queue manager
ALTER QMGR SSLKEYR('{{ .SSLKeyR }}')
ALTER QMGR CERTLABL('{{ .CertificateLabel }}')
ALTER QMGR SSLFIPS({{ .SSLFips }})
REFRESH SECURITY(*) TYPE(SSL)

25
go.mod
View File

@@ -1,17 +1,24 @@
module github.com/ibm-messaging/mq-container
go 1.15
go 1.19
require (
github.com/genuinetools/amicontained v0.4.0
github.com/genuinetools/pkg v0.0.0-20181022210355-2fcf164d37cb // indirect
github.com/genuinetools/amicontained v0.4.3
github.com/ibm-messaging/mq-golang v2.0.0+incompatible
github.com/prometheus/client_golang v1.7.1
github.com/prometheus/client_golang v1.11.1
github.com/prometheus/client_model v0.2.0
github.com/prometheus/common v0.14.0 // indirect
github.com/prometheus/procfs v0.2.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1
software.sslmate.com/src/go-pkcs12 v0.0.0-20200830195227-52f69702a001
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
google.golang.org/protobuf v1.26.0-rc.1 // indirect
)

322
go.sum
View File

@@ -1,84 +1,27 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/genuinetools/amicontained v0.4.0 h1:J70LMWTebQqQJQaQx9uAW82A6QQqe5ux9GMFgo3NAGY=
github.com/genuinetools/amicontained v0.4.0/go.mod h1:PAMZkg9CcUTa6gNyULQ6tOMTMEb2HTKJufvKeFqDw+o=
github.com/genuinetools/amicontained v0.4.3 h1:cqq9XiAHfWWY3dk8VU8bSJFu9yh8Il5coEdeTAPq72o=
github.com/genuinetools/amicontained v0.4.3/go.mod h1:PAMZkg9CcUTa6gNyULQ6tOMTMEb2HTKJufvKeFqDw+o=
github.com/genuinetools/amicontained v0.4.9 h1:/LvLdgD7iO3IPk7neqfcwB7ufoH7tG77u1pERXBIj7w=
github.com/genuinetools/pkg v0.0.0-20181022210355-2fcf164d37cb h1:9MQ4N7zyYTtdjLGqE5McDbgjIjqR5TAPc6lytEOdndc=
github.com/genuinetools/pkg v0.0.0-20181022210355-2fcf164d37cb/go.mod h1:XTcrCYlXPxnxL2UpnwuRn7tcaTn9HAhxFoFJucootk8=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -87,187 +30,63 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/ibm-messaging/mq-golang v1.0.0 h1:NZHBQlJzAuNsVv09sooYgxBWPvRUX4L6wZIuOSumiKE=
github.com/ibm-messaging/mq-golang v2.0.0+incompatible h1:xAufRPYSzoRGaME2+x7LcW5+uvy/G3xL/3Sn3u+G/lY=
github.com/ibm-messaging/mq-golang v2.0.0+incompatible/go.mod h1:qjsZDb7m1oKnbPeDma2JVJTKgyCA91I4bcJ1qHY+gcA=
github.com/ibm-messaging/mq-golang v3.0.0+incompatible h1:Yc3c8emAyveT54uNDRMkgvS+EBAHeLNWHkc3hk5x+IY=
github.com/ibm-messaging/mq-golang v3.0.0+incompatible/go.mod h1:qjsZDb7m1oKnbPeDma2JVJTKgyCA91I4bcJ1qHY+gcA=
github.com/ibm-messaging/mq-golang/v5 v5.0.0-alpha h1:Bw2c+k+o9VTMXpiVBmX6PKOm/vPuihx6dO2knPAhkKc=
github.com/ibm-messaging/mq-golang/v5 v5.0.0-alpha/go.mod h1:ywCwmYbJOU/E0rl+z4GiNoxVMty68O+LVO39a1VMXrE=
github.com/ibm-messaging/mq-golang/v5 v5.1.2 h1:u0e1Vce2TNqJpH088vF77rDMsnMRWnGaOIlxZo4DMZc=
github.com/ibm-messaging/mq-golang/v5 v5.1.2/go.mod h1:ywCwmYbJOU/E0rl+z4GiNoxVMty68O+LVO39a1VMXrE=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4=
github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -275,153 +94,56 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae h1:duLSQW+DZ5MsXKX7kc4rXlq6/mmxz4G6ewJuBPlhRe0=
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
software.sslmate.com/src/go-pkcs12 v0.0.0-20200830195227-52f69702a001 h1:AVd6O+azYjVQYW1l55IqkbL8/JxjrLtO6q4FCmV8N5c=
software.sslmate.com/src/go-pkcs12 v0.0.0-20200830195227-52f69702a001/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

View File

@@ -6,6 +6,9 @@ NativeHALocalInstance:
{{ if .CipherSpec }}
CipherSpec={{ .CipherSpec }}
{{- end }}
{{ if .SSLFipsRequired }}
SSLFipsRequired={{ .SSLFipsRequired }}
{{- end }}
{{- end }}
NativeHAInstance:
Name={{ .NativeHAInstance0_Name }}

View File

@@ -1,4 +1,4 @@
* © Copyright IBM Corporation 2018, 2019
* © Copyright IBM Corporation 2018, 2022
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,5 +14,5 @@
* limitations under the License.
* Set the cipherspec for dev channels
ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12) SSLCAUTH(OPTIONAL)
ALTER CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12) SSLCAUTH(OPTIONAL)
ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12_OR_HIGHER) SSLCAUTH(OPTIONAL)
ALTER CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12_OR_HIGHER) SSLCAUTH(OPTIONAL)

View File

@@ -36,6 +36,7 @@
</basicRegistry>
<variable name="httpHost" value="*"/>
<variable name="managementMode" value="externallyprovisioned"/>
<variable name="mqConsoleRemoteSupportEnabled" value="false"/>
<variable name="mqConsoleEnableUnsafeInline" value="true"/>
<jndiEntry jndiName="mqConsoleDefaultCCDTHostname" value="${env.MQ_CONSOLE_DEFAULT_CCDT_HOSTNAME}"/>
<jndiEntry jndiName="mqConsoleDefaultCCDTPort" value="${env.MQ_CONSOLE_DEFAULT_CCDT_PORT}"/>

View File

@@ -21,6 +21,8 @@ set -ex
sudo curl -Lo /usr/local/bin/dep https://github.com/golang/dep/releases/download/v0.5.1/dep-linux-$ARCH
sudo chmod +x /usr/local/bin/dep
sudo apt-get update || :
sudo apt-get install -y jq
go install golang.org/x/lint/golint@latest
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $GOPATH/bin 2.0.0 || echo "Gosec not installed. Platform may not be supported."
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $GOPATH/bin v2.14.0 || echo "Gosec not installed. Platform may not be supported."

View File

@@ -1,6 +1,6 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2015, 2021
# © Copyright IBM Corporation 2015, 2022
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,6 +22,7 @@ test -f /usr/bin/yum && YUM=true || YUM=false
test -f /usr/bin/microdnf && MICRODNF=true || MICRODNF=false
test -f /usr/bin/rpm && RPM=true || RPM=false
test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false
CPU_ARCH=$(uname -m)
if ($UBUNTU); then
export DEBIAN_FRONTEND=noninteractive
@@ -29,8 +30,7 @@ if ($UBUNTU); then
# This ensures no unsupported code gets installed, and makes the build faster
source /etc/os-release
# Figure out the correct apt URL based on the CPU architecture
CPU_ARCH=$(uname -p)
if [ ${CPU_ARCH} == "x86_64" ]; then
if [ "${CPU_ARCH}" == "x86_64" ]; then
APT_URL="http://archive.ubuntu.com/ubuntu/"
else
APT_URL="http://ports.ubuntu.com/ubuntu-ports/"
@@ -41,29 +41,22 @@ if ($UBUNTU); then
echo "deb ${APT_URL} ${UBUNTU_CODENAME}-updates main restricted" >> /etc/apt/sources.list
echo "deb ${APT_URL} ${UBUNTU_CODENAME}-security main restricted" >> /etc/apt/sources.list
# Install additional packages required by MQ, this install process and the runtime scripts
EXTRA_DEBS="bash bc ca-certificates coreutils curl debianutils file findutils gawk grep libc-bin mount passwd procps sed tar util-linux"
# On ARM CPUs, there is no IBM JRE, so install another one
if [ "${CPU_ARCH}" == "aarch64" ]; then
EXTRA_DEBS="${EXTRA_DEBS} openjdk-8-jre"
fi
apt-get update
apt-get install -y --no-install-recommends \
bash \
bc \
ca-certificates \
coreutils \
curl \
debianutils \
file \
findutils \
gawk \
grep \
libc-bin \
mount \
passwd \
procps \
sed \
tar \
util-linux
apt-get install -y --no-install-recommends ${EXTRA_DEBS}
fi
if ($RPM); then
EXTRA_RPMS="bash bc ca-certificates file findutils gawk glibc-common grep ncurses-compat-libs passwd procps-ng sed shadow-utils tar util-linux which"
# On ARM CPUs, there is no IBM JRE, so install another one
if [ "${CPU_ARCH}" == "aarch64" ]; then
EXTRA_RPMS="${EXTRA_RPMS} java-1.8.0-openjdk-headless"
fi
# Install additional packages required by MQ, this install process and the runtime scripts
$YUM && yum -y install --setopt install_weak_deps=false ${EXTRA_RPMS}
$MICRODNF && microdnf --disableplugin=subscription-manager install ${EXTRA_RPMS}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2020
© Copyright IBM Corporation 2017, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ limitations under the License.
package command
import (
"context"
"fmt"
"os/exec"
)
@@ -27,9 +28,13 @@ import (
// Do not use this function to run shell built-ins (like "cd"), because
// the error handling works differently
func Run(name string, arg ...string) (string, int, error) {
return RunContext(context.Background(), name, arg...)
}
func RunContext(ctx context.Context, name string, arg ...string) (string, int, error) {
// Run the command and wait for completion
// #nosec G204
cmd := exec.Command(name, arg...)
cmd := exec.CommandContext(ctx, name, arg...)
out, err := cmd.CombinedOutput()
rc := cmd.ProcessState.ExitCode()
if err != nil {

View File

@@ -36,12 +36,15 @@ func CopyFileMode(src, dest string, perm os.FileMode) error {
if err != nil {
return fmt.Errorf("failed to open %s for copy: %v", src, err)
}
// #nosec G307 - local to this function, pose no harm.
defer in.Close()
// #nosec G304 - this func creates based on the input filemode.
out, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, perm)
if err != nil {
return fmt.Errorf("failed to open %s for copy: %v", dest, err)
}
// #nosec G307 - local to this function, pose no harm.
defer out.Close()
_, err = io.Copy(out, in)

96
internal/fips/fips.go Normal file
View File

@@ -0,0 +1,96 @@
/*
© Copyright IBM Corporation 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fips
import (
"os"
"strings"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/pkg/logger"
)
var (
FIPSEnabledType int
)
// FIPS has been turned off either because OS is not FIPS enabled or
// MQ_ENABLE_FIPS environment variable is set to "false"
const FIPS_ENABLED_OFF = 0
// FIPS is turned ON
const FIPS_ENABLED_ON = 1
// FIPS enabled at operating system level
const FIPS_ENABLED_PLATFORM = 1
// FIPS enabled via environment variable
const FIPS_ENABLED_ENV_VAR = 2
// Get FIPS enabled type.
func ProcessFIPSType(logs *logger.Logger) {
// Run "sysctl crypto.fips_enabled" command to determine if FIPS has been enabled
// on OS.
FIPSEnabledType = FIPS_ENABLED_OFF
out, _, err := command.Run("sysctl", "crypto.fips_enabled")
if err == nil {
// Check the output of the command for expected output
if strings.Contains(out, "crypto.fips_enabled = 1") {
FIPSEnabledType = FIPS_ENABLED_PLATFORM
}
}
// Check if we have been asked to override FIPS cryptography
fipsOverride, fipsOverrideSet := os.LookupEnv("MQ_ENABLE_FIPS")
if fipsOverrideSet {
if strings.EqualFold(fipsOverride, "false") || strings.EqualFold(fipsOverride, "0") {
FIPSEnabledType = FIPS_ENABLED_OFF
} else if strings.EqualFold(fipsOverride, "true") || strings.EqualFold(fipsOverride, "1") {
// This is the case where OS may or may not be FIPS compliant but we have been asked
// to run MQ queue manager, web server and Native HA in FIPS mode. This case can also
// be used when running docker tests. If FIPS is enabled on host, then don't modify
// the original value.
if FIPSEnabledType != FIPS_ENABLED_PLATFORM {
FIPSEnabledType = FIPS_ENABLED_ENV_VAR
}
} else if strings.EqualFold(fipsOverride, "auto") {
// This is the default case. Leave it to the OS default as determined above.
} else {
// We don't recognise the value specified. Log a warning and carry on.
if logs != nil {
logs.Printf("Invalid value '%s' was specified for MQ_ENABLE_FIPS. The value has been ignored.\n", fipsOverride)
}
}
}
}
func IsFIPSEnabled() bool {
return FIPSEnabledType > FIPS_ENABLED_OFF
}
// Log a message on the console to indicate FIPS certified
// cryptography being used.
func PostInit(log *logger.Logger) {
message := "FIPS cryptography is not enabled."
if FIPSEnabledType == FIPS_ENABLED_PLATFORM {
message = "FIPS cryptography is enabled. FIPS cryptography setting on the host is 'true'."
} else if FIPSEnabledType == FIPS_ENABLED_ENV_VAR {
message = "FIPS cryptography is enabled. FIPS cryptography setting on the host is 'false'."
}
log.Println(message)
}

View File

@@ -0,0 +1,65 @@
/*
© Copyright IBM Corporation 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package keystore contains code to create and update keystores
package fips
import (
"fmt"
"os"
"testing"
)
func TestEnableFIPSAuto(t *testing.T) {
ProcessFIPSType(nil)
// Test default "auto"
fipsType := IsFIPSEnabled()
if fipsType {
t.Errorf("Expected FIPS OFF but got %v\n", fipsType)
}
}
func TestEnableFIPSTrue(t *testing.T) {
// Test MQ_ENABLE_FIPS=true
os.Setenv("MQ_ENABLE_FIPS", "true")
fmt.Println(os.Getenv("MQ_ENABLE_FIPS"))
ProcessFIPSType(nil)
fipsType := IsFIPSEnabled()
if !fipsType {
t.Errorf("Expected FIPS ON but got %v\n", fipsType)
}
}
func TestEnableFIPSFalse(t *testing.T) {
// Test MQ_ENABLE_FIPS=false
os.Setenv("MQ_ENABLE_FIPS", "false")
ProcessFIPSType(nil)
fipsType := IsFIPSEnabled()
if fipsType {
t.Errorf("Expected FIPS OFF but got %v\n", fipsType)
}
}
func TestEnableFIPSInvalid(t *testing.T) {
// Test MQ_ENABLE_FIPS with invalid value
os.Setenv("MQ_ENABLE_FIPS", "falseOff")
ProcessFIPSType(nil)
fipsType := IsFIPSEnabled()
if fipsType {
t.Errorf("Expected FIPS OFF but got %v\n", fipsType)
}
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2020, 2021
© Copyright IBM Corporation 2020, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ package ha
import (
"os"
"github.com/ibm-messaging/mq-container/internal/fips"
"github.com/ibm-messaging/mq-container/internal/mqtemplate"
"github.com/ibm-messaging/mq-container/internal/tls"
"github.com/ibm-messaging/mq-container/pkg/logger"
@@ -57,6 +58,13 @@ func ConfigureNativeHA(log *logger.Logger) error {
if ok {
templateMap["CipherSpec"] = cipherSpec
}
// If FIPS is enabled, then set SSLFipsRequired to Yes
if fips.IsFIPSEnabled() {
templateMap["SSLFipsRequired"] = "Yes"
} else {
templateMap["SSLFipsRequired"] = "No"
}
}
err := mqtemplate.ProcessTemplateFile(templateFile, file, templateMap, log)

View File

@@ -108,5 +108,6 @@ func (htpfile mapHtPasswd) updateHtPasswordFile(isTest bool) error {
if isTest {
file = "my.htpasswd"
}
// #nosec G306 - its a read by owner/s group, and pose no harm.
return ioutil.WriteFile(file, htpfile.GetBytes(), 0660)
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2020
© Copyright IBM Corporation 2018, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import (
"strings"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/fips"
)
// KeyStore describes information about a keystore file
@@ -34,36 +35,46 @@ type KeyStore struct {
Password string
keyStoreType string
command string
fipsEnabled bool
}
// NewJKSKeyStore creates a new Java Key Store, managed by the runmqckm command
func NewJKSKeyStore(filename, password string) *KeyStore {
return &KeyStore{
keyStore := &KeyStore{
Filename: filename,
Password: password,
keyStoreType: "jks",
command: "/opt/mqm/bin/runmqckm",
fipsEnabled: fips.IsFIPSEnabled(),
}
return keyStore
}
// NewCMSKeyStore creates a new MQ CMS Key Store, managed by the runmqakm command
func NewCMSKeyStore(filename, password string) *KeyStore {
return &KeyStore{
keyStore := &KeyStore{
Filename: filename,
Password: password,
keyStoreType: "cms",
command: "/opt/mqm/bin/runmqakm",
fipsEnabled: fips.IsFIPSEnabled(),
}
return keyStore
}
// NewPKCS12KeyStore creates a new PKCS12 Key Store, managed by the runmqakm command
func NewPKCS12KeyStore(filename, password string) *KeyStore {
return &KeyStore{
keyStore := &KeyStore{
Filename: filename,
Password: password,
keyStoreType: "p12",
command: "/opt/mqm/bin/runmqakm",
fipsEnabled: fips.IsFIPSEnabled(),
}
return keyStore
}
// Create a key store, if it doesn't already exist
@@ -100,7 +111,7 @@ func (ks *KeyStore) Create() error {
}
// Create the keystore now we're sure it doesn't exist
out, _, err := command.Run(ks.command, "-keydb", "-create", "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password, "-stash")
out, _, err := command.Run(ks.command, "-keydb", "-create", ks.getFipsEnabledFlag(), "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password, "-stash")
if err != nil {
return fmt.Errorf("error running \"%v -keydb -create\": %v %s", ks.command, err, out)
}
@@ -115,7 +126,7 @@ func (ks *KeyStore) CreateStash() error {
_, err := os.Stat(stashFile)
if err != nil {
if os.IsNotExist(err) {
out, _, err := command.Run(ks.command, "-keydb", "-stashpw", "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password)
out, _, err := command.Run(ks.command, "-keydb", ks.getFipsEnabledFlag(), "-stashpw", "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password)
if err != nil {
return fmt.Errorf("error running \"%v -keydb -stashpw\": %v %s", ks.command, err, out)
}
@@ -127,7 +138,7 @@ func (ks *KeyStore) CreateStash() error {
// Import imports a certificate file in the keystore
func (ks *KeyStore) Import(inputFile, password string) error {
out, _, err := command.Run(ks.command, "-cert", "-import", "-file", inputFile, "-pw", password, "-target", ks.Filename, "-target_pw", ks.Password, "-target_type", ks.keyStoreType)
out, _, err := command.Run(ks.command, "-cert", "-import", ks.getFipsEnabledFlag(), "-file", inputFile, "-pw", password, "-target", ks.Filename, "-target_pw", ks.Password, "-target_type", ks.keyStoreType)
if err != nil {
return fmt.Errorf("error running \"%v -cert -import\": %v %s", ks.command, err, out)
}
@@ -136,7 +147,7 @@ func (ks *KeyStore) Import(inputFile, password string) error {
// CreateSelfSignedCertificate creates a self-signed certificate in the keystore
func (ks *KeyStore) CreateSelfSignedCertificate(label, dn, hostname string) error {
out, _, err := command.Run(ks.command, "-cert", "-create", "-db", ks.Filename, "-pw", ks.Password, "-label", label, "-dn", dn, "-san_dnsname", hostname, "-size 2048 -sig_alg sha256 -eku serverAuth")
out, _, err := command.Run(ks.command, "-cert", "-create", ks.getFipsEnabledFlag(), "-db", ks.Filename, "-pw", ks.Password, "-label", label, "-dn", dn, "-san_dnsname", hostname, "-size 2048 -sig_alg sha256 -eku serverAuth")
if err != nil {
return fmt.Errorf("error running \"%v -cert -create\": %v %s", ks.command, err, out)
}
@@ -145,7 +156,7 @@ func (ks *KeyStore) CreateSelfSignedCertificate(label, dn, hostname string) erro
// Add adds a CA certificate to the keystore
func (ks *KeyStore) Add(inputFile, label string) error {
out, _, err := command.Run(ks.command, "-cert", "-add", "-db", ks.Filename, "-type", ks.keyStoreType, "-pw", ks.Password, "-file", inputFile, "-label", label)
out, _, err := command.Run(ks.command, "-cert", "-add", ks.getFipsEnabledFlag(), "-db", ks.Filename, "-type", ks.keyStoreType, "-pw", ks.Password, "-file", inputFile, "-label", label)
if err != nil {
return fmt.Errorf("error running \"%v -cert -add\": %v %s", ks.command, err, out)
}
@@ -154,7 +165,7 @@ func (ks *KeyStore) Add(inputFile, label string) error {
// Add adds a CA certificate to the keystore
func (ks *KeyStore) AddNoLabel(inputFile string) error {
out, _, err := command.Run(ks.command, "-cert", "-add", "-db", ks.Filename, "-type", ks.keyStoreType, "-pw", ks.Password, "-file", inputFile)
out, _, err := command.Run(ks.command, "-cert", "-add", ks.getFipsEnabledFlag(), "-db", ks.Filename, "-type", ks.keyStoreType, "-pw", ks.Password, "-file", inputFile)
if err != nil {
return fmt.Errorf("error running \"%v -cert -add\": %v %s", ks.command, err, out)
}
@@ -163,7 +174,7 @@ func (ks *KeyStore) AddNoLabel(inputFile string) error {
// GetCertificateLabels returns the labels of all certificates in the key store
func (ks *KeyStore) GetCertificateLabels() ([]string, error) {
out, _, err := command.Run(ks.command, "-cert", "-list", "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password)
out, _, err := command.Run(ks.command, "-cert", "-list", ks.getFipsEnabledFlag(), "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password)
if err != nil {
return nil, fmt.Errorf("error running \"%v -cert -list\": %v %s", ks.command, err, out)
}
@@ -207,7 +218,7 @@ func (ks *KeyStore) RenameCertificate(from, to string) error {
// ListAllCertificates Lists all certificates in the keystore
func (ks *KeyStore) ListAllCertificates() ([]string, error) {
out, _, err := command.Run(ks.command, "-cert", "-list", "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password)
out, _, err := command.Run(ks.command, "-cert", "-list", ks.getFipsEnabledFlag(), "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password)
if err != nil {
return nil, fmt.Errorf("error running \"%v -cert -list\": %v %s", ks.command, err, out)
}
@@ -215,6 +226,8 @@ func (ks *KeyStore) ListAllCertificates() ([]string, error) {
var labels []string
for scanner.Scan() {
s := scanner.Text()
// Check for trusted certficates as well here as this method can
// be called for trusted store as well.
if strings.HasPrefix(s, "-") || strings.HasPrefix(s, "*-") || strings.HasPrefix(s, "!") {
s := strings.TrimLeft(s, "-*!")
labels = append(labels, strings.TrimSpace(s))
@@ -226,3 +239,22 @@ func (ks *KeyStore) ListAllCertificates() ([]string, error) {
}
return labels, nil
}
// Returns the FIPS flag. True if enabled else false
func (ks *KeyStore) IsFIPSEnabled() bool {
return ks.fipsEnabled
}
// Returns -fips option if FIPS is enabled otherwise empty string. Return value is used
// when running runmqakm/runmqckm commands.
func (ks *KeyStore) getFipsEnabledFlag() string {
var fipsEnabled string
if ks.fipsEnabled {
fipsEnabled = "-fips"
} else {
fipsEnabled = ""
}
return fipsEnabled
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2019
© Copyright IBM Corporation 2018, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -35,6 +35,8 @@ const (
var (
metricsEnabled = false
// #nosec G112 - this code is changing soon to use https.
// for now we will ignore the gosec.
metricsServer = &http.Server{Addr: ":" + defaultPort}
)
@@ -43,8 +45,8 @@ func GatherMetrics(qmName string, log *logger.Logger) {
// If running in standby mode - wait until the queue manager becomes active
for {
active, _ := ready.IsRunningAsActiveQM(qmName)
if active {
status, _ := ready.Status(context.Background(), qmName)
if status.ActiveQM() {
break
}
time.Sleep(requestTimeout * time.Second)

View File

@@ -48,8 +48,10 @@ func ProcessTemplateFile(templateFile, destFile string, data interface{}, log *l
return err
}
}
// #nosec G302
// #nosec G302 G304 G306 - its a read by owner/s group, and pose no harm.
f, err := os.OpenFile(destFile, os.O_CREATE|os.O_WRONLY, 0660)
// #nosec G307 - local to this function, pose no harm.
defer f.Close()
err = t.Execute(f, data)
if err != nil {

View File

@@ -18,6 +18,7 @@ package mqversion
import (
"fmt"
"strconv"
"strings"
"github.com/ibm-messaging/mq-container/internal/command"
@@ -38,14 +39,59 @@ func Compare(checkVersion string) (int, error) {
if err != nil {
return 0, err
}
// trim any suffix from MQ version x.x.x.x
currentVersion = currentVersion[0:7]
if currentVersion < checkVersion {
return -1, nil
} else if currentVersion == checkVersion {
return 0, nil
} else if currentVersion > checkVersion {
return 1, nil
currentVRMF, err := parseVRMF(currentVersion)
if err != nil {
return 0, err
}
return 0, fmt.Errorf("Failed to compare MQ versions")
compareVRMF, err := parseVRMF(checkVersion)
if err != nil {
return 0, fmt.Errorf("failed to parse compare version: %w", err)
}
return currentVRMF.compare(*compareVRMF), nil
}
type vrmf [4]int
func (v vrmf) String() string {
return fmt.Sprintf("%d.%d.%d.%d", v[0], v[1], v[2], v[3])
}
func (v vrmf) compare(to vrmf) int {
for idx := 0; idx < 4; idx++ {
if v[idx] < to[idx] {
return -1
}
if v[idx] > to[idx] {
return 1
}
}
return 0
}
func parseVRMF(vrmfString string) (*vrmf, error) {
versionParts := strings.Split(vrmfString, ".")
if len(versionParts) != 4 {
return nil, fmt.Errorf("incorrect number of parts to version string: expected 4, got %d", len(versionParts))
}
vmrfPartNames := []string{"version", "release", "minor", "fix"}
parsed := vrmf{}
for idx, value := range versionParts {
partName := vmrfPartNames[idx]
if value == "" {
return nil, fmt.Errorf("empty %s found in VRMF", partName)
}
val, err := strconv.Atoi(value)
if err != nil {
return nil, fmt.Errorf("non-numeric %s found in VRMF", partName)
}
if val < 0 {
return nil, fmt.Errorf("negative %s found in VRMF", partName)
}
if idx == 0 && val == 0 {
return nil, fmt.Errorf("zero value for version not allowed")
}
parsed[idx] = val
}
return &parsed, nil
}

View File

@@ -16,10 +16,13 @@ limitations under the License.
package mqversion
import "testing"
import (
"fmt"
"testing"
)
func TestCompareLower(t *testing.T) {
checkVersion := "9.9.9.9"
checkVersion := "99.99.99.99"
mqVersionCheck, err := Compare(checkVersion)
if err != nil {
t.Fatalf("Failed to compare MQ versions: %v", err)
@@ -53,3 +56,92 @@ func TestCompareEqual(t *testing.T) {
t.Errorf("MQ version compare result failed. Expected 0, Got %v", mqVersionCheck)
}
}
func TestVersionValid(t *testing.T) {
checkVersion, err := Get()
if err != nil {
t.Fatalf("Failed to get current MQ version: %v", err)
}
_, err = parseVRMF(checkVersion)
if err != nil {
t.Fatalf("Validation of MQ version failed: %v", err)
}
}
func TestValidVRMF(t *testing.T) {
validVRMFs := map[string]vrmf{
"1.0.0.0": {1, 0, 0, 0},
"10.0.0.0": {10, 0, 0, 0},
"1.10.0.0": {1, 10, 0, 0},
"1.0.10.0": {1, 0, 10, 0},
"1.0.0.10": {1, 0, 0, 10},
"999.998.997.996": {999, 998, 997, 996},
}
for test, expect := range validVRMFs {
t.Run(test, func(t *testing.T) {
parsed, err := parseVRMF(test)
if err != nil {
t.Fatalf("Unexpectedly failed to parse VRMF '%s': %s", test, err.Error())
}
if *parsed != expect {
t.Fatalf("VRMF not parsed as expected. Expected '%v', got '%v'", parsed, expect)
}
})
}
}
func TestInvalidVRMF(t *testing.T) {
invalidVRMFs := []string{
"not-a-number",
"9.8.7.string",
"0.1.2.3",
"1.0.0.-10",
}
for _, test := range invalidVRMFs {
t.Run(test, func(t *testing.T) {
parsed, err := parseVRMF(test)
if err == nil {
t.Fatalf("Expected error when parsing VRMF '%s', but got none. VRMF returned: %v", test, parsed)
}
})
}
}
func TestCompare(t *testing.T) {
tests := []struct {
current string
compare string
expect int
}{
{"1.0.0.1", "1.0.0.1", 0},
{"1.0.0.1", "1.0.0.0", 1},
{"1.0.0.1", "1.0.0.2", -1},
{"9.9.9.9", "10.0.0.0", -1},
{"9.9.9.9", "9.10.0.0", -1},
{"9.9.9.9", "9.9.10.0", -1},
{"9.9.9.9", "9.9.9.10", -1},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%s-%s", test.current, test.compare), func(t *testing.T) {
baseVRMF, err := parseVRMF(test.current)
if err != nil {
t.Fatalf("Could not parse base version '%s': %s", test.current, err.Error())
}
compareVRMF, err := parseVRMF(test.compare)
if err != nil {
t.Fatalf("Could not parse current version '%s': %s", test.current, err.Error())
}
result := baseVRMF.compare(*compareVRMF)
if result != test.expect {
t.Fatalf("Expected %d but got %d when comparing '%s' with '%s'", test.expect, result, test.current, test.compare)
}
if test.expect == 0 {
return
}
resultReversed := compareVRMF.compare(*baseVRMF)
if resultReversed != test.expect*-1 {
t.Fatalf("Expected %d but got %d when comparing '%s' with '%s'", test.expect*-1, resultReversed, test.compare, test.current)
}
})
}
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2019
© Copyright IBM Corporation 2018, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ limitations under the License.
package ready
import (
"context"
"io/ioutil"
"os"
"strings"
@@ -53,6 +54,7 @@ func Clear() error {
// Set lets any subsequent calls to `CheckReady` know that the queue
// manager has finished its configuration step
func Set() error {
// #nosec G306 - this gives permissions to owner/s group only.
return ioutil.WriteFile(fileName, []byte("1"), 0770)
}
@@ -66,28 +68,38 @@ func Check() (bool, error) {
return exists, nil
}
// IsRunningAsActiveQM returns true if the queue manager is running in active mode
func IsRunningAsActiveQM(name string) (bool, error) {
return isRunningQM(name, "(RUNNING)")
}
// IsRunningAsStandbyQM returns true if the queue manager is running in standby mode
func IsRunningAsStandbyQM(name string) (bool, error) {
return isRunningQM(name, "(RUNNING AS STANDBY)")
}
// IsRunningAsReplicaQM returns true if the queue manager is running in replica mode
func IsRunningAsReplicaQM(name string) (bool, error) {
return isRunningQM(name, "(REPLICA)")
}
func isRunningQM(name string, status string) (bool, error) {
out, _, err := command.Run("dspmq", "-n", "-m", name)
// Status returns an enum representing the current running status of the queue manager
func Status(ctx context.Context, name string) (QMStatus, error) {
out, _, err := command.RunContext(ctx, "dspmq", "-n", "-m", name)
if err != nil {
return false, err
return StatusUnknown, err
}
if strings.Contains(string(out), status) {
return true, nil
if strings.Contains(string(out), "(RUNNING)") {
return StatusActiveQM, nil
}
return false, nil
if strings.Contains(string(out), "(RUNNING AS STANDBY)") {
return StatusStandbyQM, nil
}
if strings.Contains(string(out), "(REPLICA)") {
return StatusStandbyQM, nil
}
return StatusUnknown, nil
}
type QMStatus int
const (
StatusUnknown QMStatus = iota
StatusActiveQM
StatusStandbyQM
StatusReplicaQM
)
// ActiveQM returns true if the queue manager is running in active mode
func (s QMStatus) ActiveQM() bool { return s == StatusActiveQM }
// StandbyQM returns true if the queue manager is running in standby mode
func (s QMStatus) StandbyQM() bool { return s == StatusStandbyQM }
// ReplicaQM returns true if the queue manager is running in replica mode
func (s QMStatus) ReplicaQM() bool { return s == StatusReplicaQM }

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2019, 2021
© Copyright IBM Corporation 2019, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -76,18 +76,20 @@ type TLSStore struct {
Truststore KeyStoreData
}
func configureTLSKeystores(keystoreDir, keyDir, trustDir string, p12TruststoreRequired bool) (string, KeyStoreData, KeyStoreData, error) {
func configureTLSKeystores(keystoreDir, keyDir, trustDir string, p12TruststoreRequired bool, nativeTLSHA bool) (string, KeyStoreData, KeyStoreData, error) {
var keyLabel string
// Create the CMS Keystore & PKCS#12 Truststore (if required)
tlsStore, err := generateAllKeystores(keystoreDir, p12TruststoreRequired)
tlsStore, err := generateAllKeystores(keystoreDir, p12TruststoreRequired, nativeTLSHA)
if err != nil {
return "", tlsStore.Keystore, tlsStore.Truststore, err
}
// Process all keys - add them to the CMS KeyStore
keyLabel, err := processKeys(&tlsStore, keystoreDir, keyDir)
if err != nil {
return "", tlsStore.Keystore, tlsStore.Truststore, err
if tlsStore.Keystore.Keystore != nil {
// Process all keys - add them to the CMS KeyStore
keyLabel, err = processKeys(&tlsStore, keystoreDir, keyDir)
if err != nil {
return "", tlsStore.Keystore, tlsStore.Truststore, err
}
}
// Process all trust certificates - add them to the CMS KeyStore & PKCS#12 Truststore (if required)
@@ -101,13 +103,13 @@ func configureTLSKeystores(keystoreDir, keyDir, trustDir string, p12TruststoreRe
// ConfigureDefaultTLSKeystores configures the CMS Keystore & PKCS#12 Truststore
func ConfigureDefaultTLSKeystores() (string, KeyStoreData, KeyStoreData, error) {
return configureTLSKeystores(keystoreDirDefault, keyDirDefault, trustDirDefault, true)
return configureTLSKeystores(keystoreDirDefault, keyDirDefault, trustDirDefault, true, false)
}
// ConfigureHATLSKeystore configures the CMS Keystore & PKCS#12 Truststore
func ConfigureHATLSKeystore() (string, KeyStoreData, KeyStoreData, error) {
// *.crt files mounted to the HA TLS dir keyDirHA will be processed as trusted in the CMS keystore
return configureTLSKeystores(keystoreDirHA, keyDirHA, keyDirHA, false)
return configureTLSKeystores(keystoreDirHA, keyDirHA, keyDirHA, false, true)
}
// ConfigureTLS configures TLS for the queue manager
@@ -115,10 +117,26 @@ func ConfigureTLS(keyLabel string, cmsKeystore KeyStoreData, devMode bool, log *
const mqsc string = "/etc/mqm/15-tls.mqsc"
const mqscTemplate string = mqsc + ".tpl"
sslKeyRing := ""
var fipsEnabled = "NO"
// Don't set SSLKEYR if no keys or crts are not supplied
// Key label will be blank if no private keys were added during processing keys and certs.
if cmsKeystore.Keystore != nil && len(keyLabel) > 0 {
certList, _ := cmsKeystore.Keystore.ListAllCertificates()
if len(certList) > 0 {
sslKeyRing = strings.TrimSuffix(cmsKeystore.Keystore.Filename, ".kdb")
}
if cmsKeystore.Keystore.IsFIPSEnabled() {
fipsEnabled = "YES"
}
}
err := mqtemplate.ProcessTemplateFile(mqscTemplate, mqsc, map[string]string{
"SSLKeyR": strings.TrimSuffix(cmsKeystore.Keystore.Filename, ".kdb"),
"SSLKeyR": sslKeyRing,
"CertificateLabel": keyLabel,
"SSLFips": fipsEnabled,
}, log)
if err != nil {
return err
@@ -159,7 +177,7 @@ func configureTLSDev(log *logger.Logger) error {
}
// generateAllKeystores creates the CMS Keystore & PKCS#12 Truststore (if required)
func generateAllKeystores(keystoreDir string, p12TruststoreRequired bool) (TLSStore, error) {
func generateAllKeystores(keystoreDir string, p12TruststoreRequired bool, nativeTLSHA bool) (TLSStore, error) {
var cmsKeystore, p12Truststore KeyStoreData
@@ -175,11 +193,19 @@ func generateAllKeystores(keystoreDir string, p12TruststoreRequired bool) (TLSSt
return TLSStore{cmsKeystore, p12Truststore}, fmt.Errorf("Failed to create Keystore directory: %v", err)
}
// Create the CMS Keystore
cmsKeystore.Keystore = keystore.NewCMSKeyStore(filepath.Join(keystoreDir, cmsKeystoreName), cmsKeystore.Password)
err = cmsKeystore.Keystore.Create()
if err != nil {
return TLSStore{cmsKeystore, p12Truststore}, fmt.Errorf("Failed to create CMS Keystore: %v", err)
// Search the default keys directory for any keys/certs.
keysDirectory := keyDirDefault
// Change to default native HA TLS directory if we are configuring nativeHA
if nativeTLSHA {
keysDirectory = keyDirHA
}
// Create the CMS Keystore if we have been provided keys and certificates
if haveKeysAndCerts(keysDirectory) || haveKeysAndCerts(trustDirDefault) {
cmsKeystore.Keystore = keystore.NewCMSKeyStore(filepath.Join(keystoreDir, cmsKeystoreName), cmsKeystore.Password)
err = cmsKeystore.Keystore.Create()
if err != nil {
return TLSStore{cmsKeystore, p12Truststore}, fmt.Errorf("Failed to create CMS Keystore: %v", err)
}
}
// Create the PKCS#12 Truststore (if required)
@@ -203,7 +229,6 @@ func processKeys(tlsStore *TLSStore, keystoreDir string, keyDir string) (string,
// Process all keys
keyList, err := ioutil.ReadDir(keyDir)
if err == nil && len(keyList) > 0 {
// Process each set of keys - each set should contain files: *.key & *.crt
for _, keySet := range keyList {
keys, _ := ioutil.ReadDir(filepath.Join(keyDir, keySet.Name()))
@@ -230,11 +255,19 @@ func processKeys(tlsStore *TLSStore, keystoreDir string, keyDir string) (string,
return "", err
}
// Validate certificates for duplicate Subject DNs
if len(caCertificate) > 0 {
errCertValid := validateCertificates(publicCertificate, caCertificate)
if errCertValid != nil {
return "", errCertValid
}
}
// Create a new PKCS#12 Keystore - containing private key, public certificate & optional CA certificate
file, err := pkcs.Encode(rand.Reader, privateKey, publicCertificate, caCertificate, tlsStore.Keystore.Password)
if err != nil {
return "", fmt.Errorf("Failed to encode PKCS#12 Keystore %s: %v", keySet.Name()+".p12", err)
}
// #nosec G306 - this gives permissions to owner/s group only.
err = ioutil.WriteFile(filepath.Join(keystoreDir, keySet.Name()+".p12"), file, 0644)
if err != nil {
return "", fmt.Errorf("Failed to write PKCS#12 Keystore %s: %v", filepath.Join(keystoreDir, keySet.Name()+".p12"), err)
@@ -538,6 +571,7 @@ func generateRandomPassword() string {
validcharArray := []byte(validChars)
password := ""
for i := 0; i < 12; i++ {
// #nosec G404 - this is only for internal keystore and using math/rand pose no harm.
password = password + string(validcharArray[pwr.Intn(len(validcharArray))])
}
@@ -582,10 +616,13 @@ func getCertificateFingerprint(block *pem.Block) (string, error) {
// writeCertificatesToFile writes a list of certificates to a file
func writeCertificatesToFile(file string, certificates []*pem.Block) error {
// #nosec G304 - this is a temporary pem file to write certs.
f, err := os.Create(file)
if err != nil {
return fmt.Errorf("Failed to create file %s: %v", file, err)
}
// #nosec G307 - local to this function, pose no harm.
defer f.Close()
w := bufio.NewWriter(f)
@@ -602,3 +639,39 @@ func writeCertificatesToFile(file string, certificates []*pem.Block) error {
}
return nil
}
// Search the specified directory for .key and .crt files.
// Return true if at least one .key or .crt file is found else false
func haveKeysAndCerts(keyDir string) bool {
fileList, err := os.ReadDir(keyDir)
if err == nil && len(fileList) > 0 {
for _, fileInfo := range fileList {
// Keys and certs will be supplied in an user defined subdirectory.
// Do a listing of the subdirectory and then search for .key and .cert files
keys, _ := ioutil.ReadDir(filepath.Join(keyDir, fileInfo.Name()))
for _, key := range keys {
if strings.HasSuffix(key.Name(), ".key") || strings.HasSuffix(key.Name(), ".crt") {
// We found at least one key/crt file.
return true
}
}
}
}
return false
}
// Iterate through the certificates to ensure there are no two certificates with same Subject DN.
// GSKit does not allow two certificates with same Subject DN/Friendly Names
func validateCertificates(personalCert *x509.Certificate, caCertificates []*x509.Certificate) error {
// Check if we have been asked to override certificate validation by setting
// MQ_ENABLE_CERT_VALIDATION to false
enableValidation, enableValidationSet := os.LookupEnv("MQ_ENABLE_CERT_VALIDATION")
if !enableValidationSet || (enableValidationSet && !strings.EqualFold(strings.Trim(enableValidation, ""), "false")) {
for _, caCert := range caCertificates {
if strings.EqualFold(personalCert.Subject.String(), caCert.Subject.String()) {
return fmt.Errorf("Error: The Subject DN of the Issuer Certificate and the Queue Manager are same")
}
}
}
return nil
}

View File

@@ -65,7 +65,6 @@ func ConfigureWebKeystore(p12Truststore KeyStoreData, webKeystore string) (strin
// Check if a new self-signed certificate should be generated
genHostName := os.Getenv("MQ_GENERATE_CERTIFICATE_HOSTNAME")
if genHostName != "" {
// Create the Web Keystore
newWebKeystore := keystore.NewPKCS12KeyStore(webKeystoreFile, p12Truststore.Password)
err := newWebKeystore.Create()
@@ -78,7 +77,6 @@ func ConfigureWebKeystore(p12Truststore KeyStoreData, webKeystore string) (strin
if err != nil {
return "", fmt.Errorf("Failed to generate certificate in Web Keystore %s with DN of 'CN=%s': %v", webKeystoreFile, genHostName, err)
}
} else {
// Check Web Keystore already exists
_, err := os.Stat(webKeystoreFile)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2020
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -102,5 +102,10 @@ func LogContainerDetails(log *logger.Logger) error {
}
}
}
if os.Getenv("MQ_LOGGING_CONSOLE_FORMAT") == "" && os.Getenv("LOG_FORMAT") != "" {
log.Println("Environment variable LOG_FORMAT is deprecated. Use MQ_LOGGING_CONSOLE_FORMAT instead.")
}
return nil
}

View File

@@ -1,6 +1,6 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2015, 2020
# © Copyright IBM Corporation 2015, 2023
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,49 +21,8 @@ set -ex
test -f /usr/bin/rpm && RPM=true || RPM=false
test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false
# Only install the SDK package as part of the build stage
INSTALL_SDK=${INSTALL_SDK:-0}
# Download and extract the MQ unzippable server
DIR_TMP=/tmp/mq
mkdir -p ${DIR_TMP}
cd ${DIR_TMP}
curl -LO $MQ_URL
tar -xzf ./*.tar.gz
rm -f ./*.tar.gz
ls -la ${DIR_TMP}
# Generate MQ package in INSTALLATION_DIR
export genmqpkg_inc32=0
export genmqpkg_incadm=1
export genmqpkg_incamqp=0
export genmqpkg_incams=1
export genmqpkg_inccbl=0
export genmqpkg_inccics=0
export genmqpkg_inccpp=0
export genmqpkg_incdnet=0
export genmqpkg_incjava=1
export genmqpkg_incjre=1
export genmqpkg_incman=0
export genmqpkg_incmqbc=0
export genmqpkg_incmqft=0
export genmqpkg_incmqsf=0
export genmqpkg_incmqxr=0
export genmqpkg_incnls=1
export genmqpkg_incras=1
export genmqpkg_incsamp=1
export genmqpkg_incsdk=$INSTALL_SDK
export genmqpkg_inctls=1
export genmqpkg_incunthrd=0
export genmqpkg_incweb=1
export INSTALLATION_DIR=/opt/mqm
${DIR_TMP}/bin/genmqpkg.sh -b ${INSTALLATION_DIR}
ls -la ${INSTALLATION_DIR}
rm -rf ${DIR_TMP}
# Accept the MQ license
${INSTALLATION_DIR}/bin/mqlicense -accept
/opt/mqm/bin/mqlicense -accept
# Optional: Update the command prompt with the MQ version
$UBUNTU && echo "mq:$(dspmqver -b -f 2)" > /etc/debian_chroot
@@ -97,8 +56,8 @@ $RPM && PAM_FILE=/etc/pam.d/password-auth
sed -i 's/password\t\[success=1 default=ignore\]\tpam_unix\.so obscure sha512/password\t[success=1 default=ignore]\tpam_unix.so obscure sha512 minlen=8/' $PAM_FILE
# List all the installed packages, for the build log
$RPM && rpm -q --all || true
$UBUNTU && dpkg --list || true
$RPM && (rpm -q --all | sort) || true
$UBUNTU && (dpkg --list | sort) || true
#Update the license file to include UBI 8 instead of UBI 7
sed -i 's/v7.0/v8.0/g' /opt/mqm/licenses/non_ibm_license.txt

7
source-branch.env Normal file
View File

@@ -0,0 +1,7 @@
###########################################################################################################################################################
# SOURCE_BRANCH is the repository branch name for this release stream.
# It should be updated when a new release fork is created but not for testing of personal builds or pre-fork updates.
SOURCE_BRANCH ?= v9.3.2
###########################################################################################################################################################

View File

@@ -1,7 +1,8 @@
//go:build mqdev
// +build mqdev
/*
© Copyright IBM Corporation 2018, 2021
© Copyright IBM Corporation 2018, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,6 +23,8 @@ import (
"path/filepath"
"strings"
"testing"
"time"
"crypto/tls"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
@@ -34,7 +37,7 @@ import (
func TestDevGoldenPath(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -51,14 +54,16 @@ func TestDevGoldenPath(t *testing.T) {
waitForReady(t, cli, id)
waitForWebReady(t, cli, id, insecureTLSConfig)
t.Run("JMS", func(t *testing.T) {
// Run the JMS tests, with no password specified
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS)
// Run the JMS tests, with no password specified.
// Use OpenJDK JRE for running testing, pass false for 7th parameter.
// Last parameter is blank as the test doesn't use TLS.
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS, "false", "")
})
t.Run("REST admin", func(t *testing.T) {
testRESTAdmin(t, cli, id, insecureTLSConfig)
testRESTAdmin(t, cli, id, insecureTLSConfig, "")
})
t.Run("REST messaging", func(t *testing.T) {
testRESTMessaging(t, cli, id, insecureTLSConfig, qm, "app", defaultAppPasswordWeb)
testRESTMessaging(t, cli, id, insecureTLSConfig, qm, "app", defaultAppPasswordWeb, "")
})
// Stop the container cleanly
stopContainer(t, cli, id)
@@ -69,7 +74,7 @@ func TestDevGoldenPath(t *testing.T) {
func TestDevSecure(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -115,13 +120,15 @@ func TestDevSecure(t *testing.T) {
waitForWebReady(t, cli, ctr.ID, createTLSConfig(t, cert, tlsPassPhrase))
t.Run("JMS", func(t *testing.T) {
runJMSTests(t, cli, ctr.ID, true, "app", appPassword)
// OpenJDK is used for running tests, hence pass "false" for 7th parameter.
// Cipher name specified is compliant with non-IBM JRE naming.
runJMSTests(t, cli, ctr.ID, true, "app", appPassword, "false", "TLS_RSA_WITH_AES_256_CBC_SHA256")
})
t.Run("REST admin", func(t *testing.T) {
testRESTAdmin(t, cli, ctr.ID, insecureTLSConfig)
testRESTAdmin(t, cli, ctr.ID, insecureTLSConfig, "")
})
t.Run("REST messaging", func(t *testing.T) {
testRESTMessaging(t, cli, ctr.ID, insecureTLSConfig, qm, "app", appPassword)
testRESTMessaging(t, cli, ctr.ID, insecureTLSConfig, qm, "app", appPassword, "")
})
// Stop the container cleanly
@@ -131,7 +138,7 @@ func TestDevSecure(t *testing.T) {
func TestDevWebDisabled(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -153,7 +160,9 @@ func TestDevWebDisabled(t *testing.T) {
})
t.Run("JMS", func(t *testing.T) {
// Run the JMS tests, with no password specified
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS)
// OpenJDK is used for running tests, hence pass "false" for 7th parameter.
// Last parameter is blank as the test doesn't use TLS.
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS, "false", "")
})
// Stop the container cleanly
stopContainer(t, cli, id)
@@ -162,7 +171,7 @@ func TestDevWebDisabled(t *testing.T) {
func TestDevConfigDisabled(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -184,3 +193,592 @@ func TestDevConfigDisabled(t *testing.T) {
// Stop the container cleanly
stopContainer(t, cli, id)
}
// Test if SSLKEYR and CERTLABL attributes are not set when key and certificate
// are not supplied.
func TestSSLKEYRBlank(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
},
}
id := runContainerWithPorts(t, cli, &containerConfig, []int{9443})
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
// execute runmqsc to display qmgr SSLKEYR and CERTLABL attibutes.
// Search the console output for exepcted values
_, sslkeyROutput := execContainer(t, cli, id, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
if !strings.Contains(sslkeyROutput, "SSLKEYR( )") || !strings.Contains(sslkeyROutput, "CERTLABL( )") {
// Although queue manager is ready, it may be that MQSC scripts have not been applied yet.
// Hence wait for a second and retry few times before giving up.
waitCount := 30
var i int
for i = 0; i < waitCount; i++ {
time.Sleep(1 * time.Second)
_, sslkeyROutput = execContainer(t, cli, id, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
if strings.Contains(sslkeyROutput, "SSLKEYR( )") && strings.Contains(sslkeyROutput, "CERTLABL( )") {
break
}
}
// Failed to get expected output? dump the contents of mqsc files.
if i == waitCount {
_, tls15mqsc := execContainer(t, cli, id, "", []string{"cat", "/etc/mqm/15-tls.mqsc"})
_, autoMQSC := execContainer(t, cli, id, "", []string{"cat", "/mnt/mqm/data/qmgrs/QM1/autocfg/cached.mqsc"})
t.Errorf("Expected SSLKEYR to be blank but it is not; got \"%v\"\n AutoConfig MQSC file contents %v\n 15-tls: %v", sslkeyROutput, autoMQSC, tls15mqsc)
}
}
// Stop the container cleanly
stopContainer(t, cli, id)
}
// Test if SSLKEYR and CERTLABL attributes are set when key and certificate
// are supplied.
func TestSSLKEYRWithSuppliedKeyAndCert(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDir(t, false) + ":/etc/mqm/pki/keys/default",
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
// execute runmqsc to display qmgr SSLKEYR and CERTLABL attibutes.
// Search the console output for exepcted values
_, sslkeyROutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
if !strings.Contains(sslkeyROutput, "SSLKEYR(/run/runmqserver/tls/key)") || !strings.Contains(sslkeyROutput, "CERTLABL(default)") {
// Although queue manager is ready, it may be that MQSC scripts have not been applied yet.
// Hence wait for a second and retry few times before giving up.
waitCount := 30
var i int
for i = 0; i < waitCount; i++ {
time.Sleep(1 * time.Second)
_, sslkeyROutput = execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
if strings.Contains(sslkeyROutput, "SSLKEYR(/run/runmqserver/tls/key)") && strings.Contains(sslkeyROutput, "CERTLABL(default)") {
break
}
}
// Failed to get expected output? dump the contents of mqsc files.
if i == waitCount {
_, tls15mqsc := execContainer(t, cli, ctr.ID, "", []string{"cat", "/etc/mqm/15-tls.mqsc"})
_, autoMQSC := execContainer(t, cli, ctr.ID, "", []string{"cat", "/mnt/mqm/data/qmgrs/QM1/autocfg/cached.mqsc"})
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\" \n AutoConfig MQSC file contents %v\n 15-tls: %v", sslkeyROutput, autoMQSC, tls15mqsc)
}
}
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// Test with CA cert
func TestSSLKEYRWithCACert(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDirWithCA(t, false) + ":/etc/mqm/pki/keys/QM1CA",
},
// Assign a random port for the web server on the host
PortBindings: nat.PortMap{
"9443/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
},
},
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
// execute runmqsc to display qmgr SSLKEYR and CERTLABL attibutes.
// Search the console output for exepcted values
_, sslkeyROutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
if !strings.Contains(sslkeyROutput, "SSLKEYR(/run/runmqserver/tls/key)") {
// Although queue manager is ready, it may be that MQSC scripts have not been applied yet.
// Hence wait for a second and retry few times before giving up.
waitCount := 30
var i int
for i = 0; i < waitCount; i++ {
time.Sleep(1 * time.Second)
_, sslkeyROutput = execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
if strings.Contains(sslkeyROutput, "SSLKEYR(/run/runmqserver/tls/key)") {
break
}
}
// Failed to get expected output? dump the contents of mqsc files.
if i == waitCount {
_, tls15mqsc := execContainer(t, cli, ctr.ID, "", []string{"cat", "/etc/mqm/15-tls.mqsc"})
_, autoMQSC := execContainer(t, cli, ctr.ID, "", []string{"cat", "/mnt/mqm/data/qmgrs/QM1/autocfg/cached.mqsc"})
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\"\n AutoConfig MQSC file contents %v\n 15-tls: %v", sslkeyROutput, autoMQSC, tls15mqsc)
}
}
if !strings.Contains(sslkeyROutput, "CERTLABL(QM1CA)") {
_, autoMQSC := execContainer(t, cli, ctr.ID, "", []string{"cat", "/etc/mqm/15-tls.mqsc"})
t.Errorf("Expected CERTLABL to be 'QM1CA' but it is not; got \"%v\" \n MQSC File contents %v", sslkeyROutput, autoMQSC)
}
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// Verifies SSLFIPS is set to NO if MQ_ENABLE_FIPS=false
func TestSSLFIPSNO(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
"MQ_ENABLE_FIPS=false",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDir(t, false) + ":/etc/mqm/pki/keys/default",
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
// execute runmqsc to display qmgr SSLKEYR, SSLFIPS and CERTLABL attibutes.
// Search the console output for exepcted values
_, sslFIPSOutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL SSLFIPS' | runmqsc"})
if !strings.Contains(sslFIPSOutput, "SSLKEYR(/run/runmqserver/tls/key)") {
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "CERTLABL(default)") {
t.Errorf("Expected CERTLABL to be 'default' but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "SSLFIPS(NO)") {
t.Errorf("Expected SSLFIPS to be 'NO' but it is not; got \"%v\"", sslFIPSOutput)
}
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// Verifies SSLFIPS is set to YES if certificates for queue manager
// are supplied and MQ_ENABLE_FIPS=true
func TestSSLFIPSYES(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
appPassword := "differentPassw0rd"
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_APP_PASSWORD=" + appPassword,
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
"MQ_ENABLE_FIPS=true",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDir(t, false) + ":/etc/mqm/pki/keys/default",
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
// Check for expected message on container log
logs := inspectLogs(t, cli, ctr.ID)
if !strings.Contains(logs, "FIPS cryptography is enabled.") {
t.Errorf("Expected 'FIPS cryptography is enabled.' but got %v\n", logs)
}
// execute runmqsc to display qmgr SSLKEYR, SSLFIPS and CERTLABL attibutes.
// Search the console output for exepcted values
_, sslFIPSOutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL SSLFIPS' | runmqsc"})
if !strings.Contains(sslFIPSOutput, "SSLKEYR(/run/runmqserver/tls/key)") {
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "CERTLABL(default)") {
t.Errorf("Expected CERTLABL to be 'default' but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "SSLFIPS(YES)") {
t.Errorf("Expected SSLFIPS to be 'YES' but it is not; got \"%v\"", sslFIPSOutput)
}
t.Run("JMS", func(t *testing.T) {
// Run the JMS tests, with no password specified
runJMSTests(t, cli, ctr.ID, true, "app", appPassword, "false", "TLS_RSA_WITH_AES_256_CBC_SHA256")
})
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// TestDevSecureFIPSYESWeb verifies if the MQ Web Server is running in FIPS mode
func TestDevSecureFIPSTrueWeb(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
const tlsPassPhrase string = "passw0rd"
qm := "qm1"
appPassword := "differentPassw0rd"
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=" + qm,
"MQ_APP_PASSWORD=" + appPassword,
"DEBUG=1",
"WLP_LOGGING_MESSAGE_FORMAT=JSON",
"MQ_ENABLE_EMBEDDED_WEB_SERVER_LOG=true",
"MQ_ENABLE_FIPS=true",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDir(t, false) + ":/etc/mqm/pki/keys/default",
tlsDir(t, false) + ":/etc/mqm/pki/trust/default",
},
// Assign a random port for the web server on the host
// TODO: Don't do this for all tests
PortBindings: nat.PortMap{
"9443/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
},
},
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
cert := filepath.Join(tlsDir(t, true), "server.crt")
waitForWebReady(t, cli, ctr.ID, createTLSConfig(t, cert, tlsPassPhrase))
// Create a TLS Config with a cipher to use when connecting over HTTPS
var secureTLSConfig *tls.Config = createTLSConfigWithCipher(t, cert, tlsPassPhrase, []uint16{tls.TLS_RSA_WITH_AES_256_GCM_SHA384})
// Put a message to queue
t.Run("REST messaging", func(t *testing.T) {
testRESTMessaging(t, cli, ctr.ID, secureTLSConfig, qm, "app", appPassword, "")
})
// Create a TLS Config with a non-FIPS cipher to use when connecting over HTTPS
var secureNonFIPSCipherConfig *tls.Config = createTLSConfigWithCipher(t, cert, tlsPassPhrase, []uint16{tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA})
// Put a message to queue - the attempt to put message will fail with a EOF return message.
t.Run("REST messaging", func(t *testing.T) {
testRESTMessaging(t, cli, ctr.ID, secureNonFIPSCipherConfig, qm, "app", appPassword, "EOF")
})
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// TestDevSecureNOFIPSWeb verifies if the MQ Web Server is not running in FIPS mode
func TestDevSecureFalseFIPSWeb(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
const tlsPassPhrase string = "passw0rd"
qm := "qm1"
appPassword := "differentPassw0rd"
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=" + qm,
"MQ_APP_PASSWORD=" + appPassword,
"DEBUG=1",
"WLP_LOGGING_MESSAGE_FORMAT=JSON",
"MQ_ENABLE_EMBEDDED_WEB_SERVER_LOG=true",
"MQ_ENABLE_FIPS=false",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDir(t, false) + ":/etc/mqm/pki/keys/default",
tlsDir(t, false) + ":/etc/mqm/pki/trust/default",
},
// Assign a random port for the web server on the host
PortBindings: nat.PortMap{
"9443/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
},
},
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
cert := filepath.Join(tlsDir(t, true), "server.crt")
waitForWebReady(t, cli, ctr.ID, createTLSConfig(t, cert, tlsPassPhrase))
// As FIPS is not enabled, the MQ WebServer (actually Java) will choose a JSSE provider from the list
// specified in java.security file. We will need to enable java.net.debug and then parse the web server
// logs to check what JJSE provider is being used. Hence just check the jvm.options file does not contain
// -Dcom.ibm.jsse2.usefipsprovider line.
_, jvmOptionsOutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "cat /var/mqm/web/installations/Installation1/servers/mqweb/configDropins/defaults/jvm.options"})
if strings.Contains(jvmOptionsOutput, "-Dcom.ibm.jsse2.usefipsprovider") {
t.Errorf("Did not expect -Dcom.ibm.jsse2.usefipsprovider but it is not; got \"%v\"", jvmOptionsOutput)
}
// Just do a HTTPS GET as well to query installation details.
var secureTLSConfig *tls.Config = createTLSConfigWithCipher(t, cert, tlsPassPhrase, []uint16{tls.TLS_RSA_WITH_AES_256_GCM_SHA384})
t.Run("REST admin", func(t *testing.T) {
testRESTAdmin(t, cli, ctr.ID, secureTLSConfig, "")
})
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// Verify SSLFIPS is set to NO if no certificates were supplied
func TestSSLFIPSTrueNoCerts(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
appPassword := "differentPassw0rd"
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_APP_PASSWORD=" + appPassword,
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
"MQ_ENABLE_FIPS=true",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
// execute runmqsc to display qmgr SSLKEYR, SSLFIPS and CERTLABL attibutes.
// Search the console output for exepcted values
_, sslFIPSOutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL SSLFIPS' | runmqsc"})
if !strings.Contains(sslFIPSOutput, "SSLKEYR( )") {
t.Errorf("Expected SSLKEYR to be ' ' but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "CERTLABL( )") {
t.Errorf("Expected CERTLABL to be blank but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "SSLFIPS(NO)") {
t.Errorf("Expected SSLFIPS to be 'NO' but it is not; got \"%v\"", sslFIPSOutput)
}
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// Verifies SSLFIPS is set to NO if MQ_ENABLE_FIPS=tru (invalid value)
func TestSSLFIPSInvalidValue(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
"MQ_ENABLE_FIPS=tru",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDir(t, false) + ":/etc/mqm/pki/keys/default",
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
waitForReady(t, cli, ctr.ID)
// execute runmqsc to display qmgr SSLKEYR, SSLFIPS and CERTLABL attibutes.
// Search the console output for exepcted values
_, sslFIPSOutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL SSLFIPS' | runmqsc"})
if !strings.Contains(sslFIPSOutput, "SSLKEYR(/run/runmqserver/tls/key)") {
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "CERTLABL(default)") {
t.Errorf("Expected CERTLABL to be 'default' but it is not; got \"%v\"", sslFIPSOutput)
}
if !strings.Contains(sslFIPSOutput, "SSLFIPS(NO)") {
t.Errorf("Expected SSLFIPS to be 'NO' but it is not; got \"%v\"", sslFIPSOutput)
}
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}
// Container creation fails when invalid certs are passed and MQ_ENABLE_FIPS set true
func TestSSLFIPSBadCerts(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
"MQ_ENABLE_FIPS=true",
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDirInvalid(t, false) + ":/etc/mqm/pki/keys/default",
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
rc := waitForContainer(t, cli, ctr.ID, 20*time.Second)
// Expect return code 1 if container failed to create.
if rc == 1 {
// Get container logs and search for specific message.
logs := inspectLogs(t, cli, ctr.ID)
if strings.Contains(logs, "Failed to parse private key") {
t.Logf("Container creating failed because of invalid certifates")
}
} else {
// Some other error occurred.
t.Errorf("Expected rc=0, got rc=%v", rc)
}
// Stop the container cleanly
stopContainer(t, cli, ctr.ID)
}

View File

@@ -1,7 +1,8 @@
//go:build mqdev
// +build mqdev
/*
© Copyright IBM Corporation 2018, 2021
© Copyright IBM Corporation 2018, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,6 +19,7 @@ limitations under the License.
package main
import (
"bufio"
"bytes"
"context"
"crypto/tls"
@@ -26,8 +28,8 @@ import (
"io/ioutil"
"net/http"
"net/http/httputil"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"time"
@@ -80,15 +82,23 @@ func tlsDir(t *testing.T, unixPath bool) string {
return filepath.Join(getCwd(t, unixPath), "../tls")
}
func tlsDirWithCA(t *testing.T, unixPath bool) string {
return filepath.Join(getCwd(t, unixPath), "../tlscacert")
}
func tlsDirInvalid(t *testing.T, unixPath bool) string {
return filepath.Join(getCwd(t, unixPath), "../tlsinvalidcert")
}
// runJMSTests runs a container with a JMS client, which connects to the queue manager container with the specified ID
func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, password string) {
func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, password string, ibmjre string, cipherName string) {
containerConfig := container.Config{
// -e MQ_PORT_1414_TCP_ADDR=9.145.14.173 -e MQ_USERNAME=app -e MQ_PASSWORD=passw0rd -e MQ_CHANNEL=DEV.APP.SVRCONN -e MQ_TLS_TRUSTSTORE=/tls/test.p12 -e MQ_TLS_PASSPHRASE=passw0rd -v /Users/arthurbarr/go/src/github.com/ibm-messaging/mq-container/test/tls:/tls msgtest
Env: []string{
"MQ_PORT_1414_TCP_ADDR=" + getIPAddress(t, cli, ID),
"MQ_USERNAME=" + user,
"MQ_CHANNEL=DEV.APP.SVRCONN",
"IBMJRE=" + os.Getenv("IBMJRE"),
"IBMJRE=" + ibmjre,
},
Image: imageNameDevJMS(),
}
@@ -101,6 +111,7 @@ func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, pa
containerConfig.Env = append(containerConfig.Env, []string{
"MQ_TLS_TRUSTSTORE=/var/tls/client-trust.jks",
"MQ_TLS_PASSPHRASE=passw0rd",
"MQ_TLS_CIPHER=" + cipherName,
}...)
}
hostConfig := container.HostConfig{
@@ -119,9 +130,57 @@ func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, pa
if rc != 0 {
t.Errorf("JUnit container failed with rc=%v", rc)
}
// Get console output of the container and process the lines
// to see if we have any failures
scanner := bufio.NewScanner(strings.NewReader(inspectLogs(t, cli, ctr.ID)))
for scanner.Scan() {
s := scanner.Text()
if processJunitLogLine(s) {
t.Errorf("JUnit container tests failed. Reason: %s", s)
}
}
defer cleanContainer(t, cli, ctr.ID)
}
// Parse JUnit log line and return true if line contains failed or aborted tests
func processJunitLogLine(outputLine string) bool {
var failedLine bool
// Sample JUnit test run output
//[ 2 containers found ]
//[ 0 containers skipped ]
//[ 2 containers started ]
//[ 0 containers aborted ]
//[ 2 containers successful ]
//[ 0 containers failed ]
//[ 0 tests found ]
//[ 0 tests skipped ]
//[ 0 tests started ]
//[ 0 tests aborted ]
//[ 0 tests successful ]
//[ 0 tests failed ]
// Consider only those lines that begin with '[' and with ']'
if strings.HasPrefix(outputLine, "[") && strings.HasSuffix(outputLine, "]") {
// Strip off [] and whitespaces
trimmed := strings.Trim(outputLine, "[] ")
if strings.Contains(trimmed, "aborted") || strings.Contains(trimmed, "failed") {
// Tokenize on whitespace
tokens := strings.Split(trimmed, " ")
// Determine the count of aborted or failed tests
count, err := strconv.Atoi(tokens[0])
if err == nil {
if count > 0 {
failedLine = true
}
}
}
}
return failedLine
}
// createTLSConfig creates a tls.Config which trusts the specified certificate
func createTLSConfig(t *testing.T, certFile, password string) *tls.Config {
// Get the SystemCertPool, continue with an empty pool on error
@@ -146,7 +205,7 @@ func createTLSConfig(t *testing.T, certFile, password string) *tls.Config {
}
}
func testRESTAdmin(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config) {
func testRESTAdmin(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config, errorExpected string) {
httpClient := http.Client{
Timeout: time.Duration(30 * time.Second),
Transport: &http.Transport{
@@ -158,9 +217,15 @@ func testRESTAdmin(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.C
req.SetBasicAuth("admin", defaultAdminPassword)
resp, err := httpClient.Do(req)
if err != nil {
t.Fatal(err)
if len(errorExpected) > 0 {
if !strings.Contains(err.Error(), errorExpected) {
t.Fatal(err)
}
} else {
t.Fatal(err)
}
}
if resp.StatusCode != http.StatusOK {
if resp != nil && resp.StatusCode != http.StatusOK {
t.Errorf("Expected HTTP status code %v from 'GET installation'; got %v", http.StatusOK, resp.StatusCode)
}
}
@@ -183,7 +248,7 @@ func logHTTPResponse(t *testing.T, resp *http.Response) {
t.Logf("HTTP response: %v", string(d))
}
func testRESTMessaging(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config, qmName string, user string, password string) {
func testRESTMessaging(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config, qmName string, user string, password string, errorExpected string) {
httpClient := http.Client{
Timeout: time.Duration(30 * time.Second),
Transport: &http.Transport{
@@ -200,10 +265,19 @@ func testRESTMessaging(t *testing.T, cli *client.Client, ID string, tlsConfig *t
logHTTPRequest(t, req)
resp, err := httpClient.Do(req)
if err != nil {
t.Fatal(err)
if len(errorExpected) > 0 {
if strings.Contains(err.Error(), errorExpected) {
t.Logf("Error contains expected '%s' value", errorExpected)
return
} else {
t.Fatal(err)
}
} else {
t.Fatal(err)
}
}
logHTTPResponse(t, resp)
if resp.StatusCode != http.StatusCreated {
if resp != nil && resp.StatusCode != http.StatusCreated {
t.Errorf("Expected HTTP status code %v from 'POST to queue'; got %v", http.StatusOK, resp.StatusCode)
t.Logf("HTTP response: %+v", resp)
t.Fail()
@@ -231,3 +305,28 @@ func testRESTMessaging(t *testing.T, cli *client.Client, ID string, tlsConfig *t
t.Errorf("Expected payload to be \"%s\"; got \"%s\"", putMessage, gotMessage)
}
}
// createTLSConfig creates a tls.Config which trusts the specified certificate
func createTLSConfigWithCipher(t *testing.T, certFile, password string, ciphers []uint16) *tls.Config {
// Get the SystemCertPool, continue with an empty pool on error
certs, err := x509.SystemCertPool()
if err != nil {
t.Fatal(err)
}
// Read in the cert file
cert, err := ioutil.ReadFile(certFile)
if err != nil {
t.Fatal(err)
}
// Append our cert to the system pool
ok := certs.AppendCertsFromPEM(cert)
if !ok {
t.Fatal("No certs appended")
}
// Trust the augmented cert pool in our client
return &tls.Config{
InsecureSkipVerify: false,
RootCAs: certs,
CipherSuites: ciphers,
}
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2020
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ import (
func TestLicenseNotSet(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -52,10 +52,12 @@ func TestLicenseNotSet(t *testing.T) {
expectTerminationMessage(t, cli, id)
}
// Start container with LICENSE environment variable set to view.
// Check that container starts and display license text
func TestLicenseView(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -75,103 +77,58 @@ func TestLicenseView(t *testing.T) {
}
}
//Start a container with qm grace set to x seconds
//Check that when the container is stopped that the command endmqm has option -tp and x
func TestEndMQMOpts(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{"LICENSE=accept", "MQ_GRACE_PERIOD=27"},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
killContainer(t, cli, id, "SIGTERM")
_, out := execContainer(t, cli, id, "", []string{"bash", "-c", "ps -ef | grep 'endmqm -w -r -tp 27'"})
t.Log(out)
if !strings.Contains(out, "endmqm -w -r -tp 27") {
t.Errorf("Expected endmqm options endmqm -w -r -tp 27; got \"%v\"", out)
}
}
// TestGoldenPath starts a queue manager successfully when metrics are enabled
func TestGoldenPathWithMetrics(t *testing.T) {
t.Parallel()
goldenPath(t, true)
}
// TestGoldenPath starts a queue manager successfully when metrics are disabled
func TestGoldenPathNoMetrics(t *testing.T) {
t.Parallel()
goldenPath(t, false)
}
// Actual test function for TestGoldenPathNoMetrics & TestGoldenPathWithMetrics
func goldenPath(t *testing.T, metric bool) {
cli, err := client.NewEnvClient()
func goldenPath(t *testing.T, metrics bool) {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{"LICENSE=accept", "MQ_QMGR_NAME=qm1"},
}
if metric {
if metrics {
containerConfig.Env = append(containerConfig.Env, "MQ_ENABLE_METRICS=true")
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
//By default AMQ5041I,AMQ5052I,AMQ5051I,AMQ5037I,AMQ5975I are excluded
jsonLogs := inspectLogs(t, cli, id)
isMessageFound := scanForExcludedEntries(jsonLogs)
if isMessageFound == true {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
if strings.Contains(jsonLogs, "CWWKF0011I") {
t.Errorf("Web Server is off....CWWKF0011I message id is not expected")
}
t.Run("Validate Default LogFilePages", func(t *testing.T) {
testLogFilePages(t, cli, id, "qm1", "4096")
})
// Stop the container cleanly
stopContainer(t, cli, id)
}
// TestSecurityVulnerabilities checks for any vulnerabilities in the image, as reported
// by Red Hat
func TestSecurityVulnerabilities(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
if err != nil {
t.Fatal(err)
}
rc, _ := runContainerOneShot(t, cli, "bash", "-c", "command -v microdnf && test -e /etc/yum.repos.d/ubi.repo")
if rc != 0 {
t.Skip("Skipping test because container is based on ubi-minimal, which doesn't include yum")
}
// id, _, err := command.Run("sudo", "buildah", "from", imageName())
// if err != nil {
// t.Log(id)
// t.Fatal(err)
// }
// id = strings.TrimSpace(id)
// defer command.Run("buildah", "rm", id)
// mnt, _, err := command.Run("sudo", "buildah", "mount", id)
// if err != nil {
// t.Log(mnt)
// t.Fatal(err)
// }
// mnt = strings.TrimSpace(mnt)
// out, _, err := command.Run("bash", "-c", "sudo cp /etc/yum.repos.d/* "+filepath.Join(mnt, "/etc/yum.repos.d/"))
// if err != nil {
// t.Log(out)
// t.Fatal(err)
// }
// out, ret, _ := command.Run("bash", "-c", "yum --installroot="+mnt+" updateinfo list sec | grep /Sec")
// if ret != 1 {
// t.Errorf("Expected no vulnerabilities, found the following:\n%v", out)
// }
}
func utilTestNoQueueManagerName(t *testing.T, hostName string, expectedName string) {
search := "QMNAME(" + expectedName + ")"
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -187,6 +144,7 @@ func utilTestNoQueueManagerName(t *testing.T, hostName string, expectedName stri
t.Errorf("Expected result of running dspmq to contain name=%v, got name=%v", search, out)
}
}
func TestNoQueueManagerName(t *testing.T) {
t.Parallel()
@@ -217,7 +175,7 @@ func TestWithVolumeNoMetrics(t *testing.T) {
// Actual test function for TestWithVolumeNoMetrics & TestWithVolumeAndMetrics
func withVolume(t *testing.T, metric bool) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -261,7 +219,7 @@ func withVolume(t *testing.T, metric bool) {
// TestWithSplitVolumesLogsData starts a queue manager with separate log/data mounts
func TestWithSplitVolumesLogsData(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -281,7 +239,7 @@ func TestWithSplitVolumesLogsData(t *testing.T) {
// TestWithSplitVolumesLogsOnly starts a queue manager with a separate log mount
func TestWithSplitVolumesLogsOnly(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -299,7 +257,7 @@ func TestWithSplitVolumesLogsOnly(t *testing.T) {
// TestWithSplitVolumesDataOnly starts a queue manager with a separate data mount
func TestWithSplitVolumesDataOnly(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -320,7 +278,7 @@ func TestWithSplitVolumesDataOnly(t *testing.T) {
func TestNoVolumeWithRestart(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -340,7 +298,7 @@ func TestNoVolumeWithRestart(t *testing.T) {
// where `runmqserver -i` is run to initialize the storage. Then the
// container can be run as normal.
func TestVolumeRequiresRoot(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -403,7 +361,7 @@ func TestVolumeRequiresRoot(t *testing.T) {
func TestCreateQueueManagerFail(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -436,7 +394,7 @@ func TestCreateQueueManagerFail(t *testing.T) {
func TestStartQueueManagerFail(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -472,7 +430,7 @@ func TestStartQueueManagerFail(t *testing.T) {
func TestVolumeUnmount(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -521,7 +479,7 @@ func TestVolumeUnmount(t *testing.T) {
func TestZombies(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -558,7 +516,7 @@ func TestZombies(t *testing.T) {
func TestMQSC(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -605,7 +563,7 @@ func TestMQSC(t *testing.T) {
func TestLargeMQSC(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -657,7 +615,7 @@ func TestLargeMQSC(t *testing.T) {
func TestRedactValidMQSC(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -735,7 +693,7 @@ func TestRedactValidMQSC(t *testing.T) {
func TestRedactInvalidMQSC(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -808,7 +766,7 @@ func TestRedactInvalidMQSC(t *testing.T) {
// tries to start a container based on that image, and checks that container terminates
func TestInvalidMQSC(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -842,7 +800,7 @@ func TestInvalidMQSC(t *testing.T) {
func TestSimpleMQIniMerge(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -880,7 +838,7 @@ func TestSimpleMQIniMerge(t *testing.T) {
}
func TestMultipleIniMerge(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -929,7 +887,7 @@ func TestMultipleIniMerge(t *testing.T) {
}
func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1027,7 +985,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
func TestReadiness(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1090,7 +1048,7 @@ func TestErrorLogRotation(t *testing.T) {
t.Skipf("Skipping %v until test defect fixed", t.Name())
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1180,7 +1138,7 @@ func TestJSONLogFormatNoMetrics(t *testing.T) {
// Actual test function for TestJSONLogFormatWithMetrics & TestJSONLogFormatNoMetrics
func jsonLogFormat(t *testing.T, metric bool) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1213,34 +1171,12 @@ func jsonLogFormat(t *testing.T, metric bool) {
}
}
func TestBadLogFormat(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"LOG_FORMAT=fake",
},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
rc := waitForContainer(t, cli, id, 20*time.Second)
if rc != 1 {
t.Errorf("Expected rc=1, got rc=%v", rc)
}
expectTerminationMessage(t, cli, id)
}
// TestMQJSONDisabled tests the case where MQ's JSON logging feature is
// specifically disabled (which will disable log mirroring)
func TestMQJSONDisabled(t *testing.T) {
t.SkipNow()
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1268,7 +1204,7 @@ func TestCorrectLicense(t *testing.T) {
t.Fatal("Required test environment variable 'EXPECTED_LICENSE' was not set.")
}
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1293,7 +1229,7 @@ func TestCorrectLicense(t *testing.T) {
func TestVersioning(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1414,7 +1350,7 @@ func TestVersioning(t *testing.T) {
func TestTraceStrmqm(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1439,7 +1375,7 @@ func TestTraceStrmqm(t *testing.T) {
// privileges enabled or disabled. Otherwise the same as the golden path tests.
func utilTestHealthCheck(t *testing.T, nonewpriv bool) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1480,7 +1416,7 @@ func TestHealthCheckWithNewPrivileges(t *testing.T) {
// privileges enabled or disabled. Otherwise the same as the golden path tests.
func utilTestStartedCheck(t *testing.T, nonewpriv bool) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -1516,3 +1452,450 @@ func TestStartedCheckWithNoNewPrivileges(t *testing.T) {
func TestStartedCheckWithNewPrivileges(t *testing.T) {
utilTestStartedCheck(t, false)
}
// Start a container with qm grace set to x seconds
// Check that when the container is stopped that the command endmqm has option -tp and x
func TestEndMQMOpts(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{"LICENSE=accept", "MQ_GRACE_PERIOD=27"},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
killContainer(t, cli, id, "SIGTERM")
_, out := execContainer(t, cli, id, "", []string{"bash", "-c", "ps -ef | grep 'endmqm -w -r -tp 27'"})
t.Log(out)
if !strings.Contains(out, "endmqm -w -r -tp 27") {
t.Errorf("Expected endmqm options endmqm -w -r -tp 27; got \"%v\"", out)
}
}
// TestCustomLogFilePages starts a qmgr with a custom number of logfilepages set.
// Check that the number of logfilepages matches.
func TestCustomLogFilePages(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{"LICENSE=accept", "MQ_QMGR_LOG_FILE_PAGES=8192", "MQ_QMGR_NAME=qmlfp"},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
testLogFilePages(t, cli, id, "qmlfp", "8192")
}
// TestLoggingConsoleSource tests default behavior which is
// MQ_LOGGING_CONSOLE_SOURCE set to qmgr,web
func TestLoggingConsoleSource(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=qm1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=true",
},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
jsonLogs, errJson := waitForMessageInLog(t, cli, id, "AMQ6206I")
if errJson != nil {
t.Errorf("%v", errJson)
}
isMessageFound := scanForExcludedEntries(jsonLogs)
if isMessageFound == true {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
// Stop the container cleanly
stopContainer(t, cli, id)
}
// TestOldBehaviorWebConsole sets LOG_FORMAT to json and verify logs are indeed in json format
func TestOldBehaviorWebConsole(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=qm1",
"LOG_FORMAT=json",
},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
jsonLogs := inspectLogs(t, cli, id)
isMessageFound := scanForExcludedEntries(jsonLogs)
if isMessageFound == true {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
if strings.Contains(jsonLogs, "Environment variable LOG_FORMAT is deprecated. Use MQ_LOGGING_CONSOLE_FORMAT instead.") {
t.Logf("Expected Message stating LOG_FORMAT is deprecated is present in the log")
} else {
t.Errorf("Expected Message stating LOG_FORMAT is deprecated is not in the log")
}
isValidJSON := checkLogForValidJSON(jsonLogs)
if !isValidJSON {
t.Fatalf("Expected all log lines to be valid JSON. But got error %v ", err)
}
// Stop the container cleanly
stopContainer(t, cli, id)
}
// TestLoggingConsoleWithContRestart restarts the container and checks
// that setting of env variable persists
func TestLoggingConsoleWithContRestart(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=qm1",
"MQ_LOGGING_CONSOLE_SOURCE=qmgr",
},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
jsonLogs, errJson := waitForMessageInLog(t, cli, id, "AMQ6206I")
if errJson != nil {
t.Errorf("%v", errJson)
}
isMessageFound := scanForExcludedEntries(jsonLogs)
if isMessageFound == true {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
stopContainer(t, cli, id)
startContainer(t, cli, id)
waitForReady(t, cli, id)
jsonLogs = inspectLogs(t, cli, id)
if !strings.Contains(jsonLogs, "Stopped queue manager") || strings.Contains(jsonLogs, "CWWKF0011I") {
t.Errorf("CWWKF0011I which is not expected is present!!!!!")
}
isMessageFoundAfterRestart := scanForExcludedEntries(jsonLogs)
if isMessageFoundAfterRestart == true {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
// Stop the container cleanly
stopContainer(t, cli, id)
}
// TestLoggingWithQmgrAndExcludeId tests MQ_LOGGING_CONSOLE_SOURCE set to qmgr
// and exclude ID set to amq7230I.
func TestLoggingWithQmgrAndExcludeId(t *testing.T) {
qmgrName := "qm1"
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=qm1",
"MQ_LOGGING_CONSOLE_SOURCE=qmgr",
"MQ_LOGGING_CONSOLE_FORMAT=json",
"MQ_LOGGING_CONSOLE_EXCLUDE_ID=amq7230I",
},
}
dir := "/var/mqm/qmgrs/" + qmgrName + "/errors"
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
jsonLogs, errJson := waitForMessageInLog(t, cli, id, "AMQ6206I")
if errJson != nil {
t.Errorf("%v", errJson)
}
isValidJSON := checkLogForValidJSON(jsonLogs)
if !isValidJSON {
t.Fatalf("Expected all log lines to be valid JSON. But got error %v ", err)
}
if strings.Contains(jsonLogs, "AMQ7230I") || strings.Contains(jsonLogs, "CWWKF0011I") {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
stopContainer(t, cli, id)
//checking that message is only excluded from the console log, but not from the MQ error log
b := copyFromContainer(t, cli, id, filepath.Join(dir, "AMQERR01.json"))
foundInLog := 0
r := bytes.NewReader(b)
scannernew := bufio.NewScanner(r)
for scannernew.Scan() {
textData := scannernew.Text()
if strings.Contains(textData, "AMQ7230I") {
foundInLog = 1
}
}
if foundInLog == 0 {
t.Errorf("mesageID AMQ7230I is not present in MQ LOG!!!!")
}
}
// TestLoggingConsoleSetToWeb tests MQ_LOGGING_CONSOLE_SOURCE set to web
func TestLoggingConsoleSetToWeb(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=qm1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=true",
"MQ_LOGGING_CONSOLE_SOURCE=web",
"MQ_LOGGING_CONSOLE_EXCLUDE_ID=CWWKG0028A,CWWKS4105I",
"MQ_LOGGING_CONSOLE_FORMAT=json",
},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
jsonLogs, errJson := waitForMessageInLog(t, cli, id, "CWWKF0011I")
if errJson != nil {
t.Errorf("%v", errJson)
}
if strings.Contains(jsonLogs, "AMQ6206I") {
t.Errorf("Logging source is set to web, Qmgr message \"%v\" should be excluded!!!", jsonLogs)
}
if strings.Contains(jsonLogs, "AMQ5041I") || strings.Contains(jsonLogs, "AMQ5052I") ||
strings.Contains(jsonLogs, "AMQ5051I") || strings.Contains(jsonLogs, "AMQ5037I") ||
strings.Contains(jsonLogs, "AMQ5975I") || strings.Contains(jsonLogs, "CWWKG0028A") ||
strings.Contains(jsonLogs, "CWWKS4105I") {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
// Stop the container cleanly
stopContainer(t, cli, id)
}
// TestLoggingConsoleSetToQmgr test sets LOG_FORMAT to BASIC and MQ_LOGGING_CONSOLE_FORMAT to
// json and check that log is in json format
func TestLoggingConsoleSetToQmgr(t *testing.T) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=qm1",
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
"MQ_LOGGING_CONSOLE_SOURCE=qmgr",
"LOG_FORMAT=BASIC",
"MQ_LOGGING_CONSOLE_FORMAT=json",
},
}
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
jsonLogs, errJson := waitForMessageInLog(t, cli, id, "AMQ6206I")
if errJson != nil {
t.Errorf("%v", errJson)
}
isMessageFound := scanForExcludedEntries(jsonLogs)
if isMessageFound == true {
t.Errorf("Expected to exclude messageId by default; but messageId \"%v\" is present", jsonLogs)
}
isValidJSON := checkLogForValidJSON(jsonLogs)
if !isValidJSON {
t.Fatalf("Expected all log lines to be valid JSON. But got error %v ", err)
}
// Stop the container cleanly
stopContainer(t, cli, id)
}
// Test queue manager with both personal and CA certificate having the same DN
func TestSameSubDNError(t *testing.T) {
expectedOutput := "Error: The Subject DN of the Issuer Certificate and the Queue Manager are same"
utilSubDNTest(t, "../tlssamesubdn", "true", expectedOutput, false)
}
// Test queue manager with both personal and CA certificate having the same DN
// but override the changed behavior via environment variable
func TestSameSubDNErrorOverride(t *testing.T) {
expectedOutput := "Failed to relabel certificate for"
utilSubDNTest(t, "../tlssamesubdn", "false", expectedOutput, false)
}
// Test queue manager with root CA certificate
func TestWithCASignedCerts(t *testing.T) {
expectedOutput := "Creating queue manager MQQM"
utilSubDNTest(t, "../tlsdifferentsubdn", "true", expectedOutput, true)
}
// Test queue manager with intermediate CA certificate
func TestWithIntermediateCASignedCerts(t *testing.T) {
expectedOutput := "Creating queue manager MQQM"
utilSubDNTest(t, "../tlsintermediateca", "true", expectedOutput, true)
}
// Scan the console output for required content.
func scanForText(output string, prefix string, findText string) (int, bool) {
var count int
var found bool
scanner := bufio.NewScanner(strings.NewReader(output))
for scanner.Scan() {
s := scanner.Text()
if strings.HasPrefix(s, prefix) {
count++
}
if strings.Contains(s, findText) {
found = true
}
}
return count, found
}
// Utility function to test Certificate relabel issues.
func utilSubDNTest(t *testing.T, certPath string, overrideFlag string, expecteOutPut string, waitLong bool) {
t.Parallel()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
containerConfig := container.Config{
Env: []string{
"LICENSE=accept",
"MQ_QMGR_NAME=QM1",
"MQ_ENABLE_CERT_VALIDATION=" + overrideFlag,
},
Image: imageName(),
}
hostConfig := container.HostConfig{
Binds: []string{
coverageBind(t),
tlsDirDN(t, false, certPath) + ":/etc/mqm/pki/keys/QM1",
},
}
networkingConfig := network.NetworkingConfig{}
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
if err != nil {
t.Fatal(err)
}
defer cleanContainer(t, cli, ctr.ID)
startContainer(t, cli, ctr.ID)
if waitLong {
waitForReady(t, cli, ctr.ID)
_, output := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL SSLFIPS' | runmqsc"})
if !strings.Contains(output, "SSLKEYR(/run/runmqserver/tls/key)") {
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\"", output)
}
if !strings.Contains(output, "CERTLABL(QM1)") {
t.Errorf("Expected CERTLABL to be 'default' but it is not; got \"%v\"", output)
}
_, output = execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "runmqakm -cert -list -type cms -db /run/runmqserver/tls/key.kdb -stashed"})
if strings.EqualFold(t.Name(), "TestWithCASignedCerts") {
// There should be one personal certificate and one trusted certificate.
count, found := scanForText(output, "!", "CN=MQMFTQM,OU=ISL,O=IBM,L=BLR,ST=KA,C=IN")
if count != 1 && !found {
t.Errorf("Expected 1 trusted certificate with name containing CN=MQMFTQM. But found %v", output)
}
// One personal certificate that relabeld as QM1
count, found = scanForText(output, "-", "QM1")
if count != 1 && !found {
t.Errorf("Expected 1 personal certificate with name containing QM1. But found %v", output)
}
} else if strings.EqualFold(t.Name(), "TestWithIntermediateCASignedCerts") {
// There should be one personal certificate and two trusted certificates
// an intermediate CA and the root CA.
count, found := scanForText(output, "!", "ST=HANTS,C=GB")
if count != 2 && !found {
t.Errorf("Expected 2 trusted certificate with name containing 'ST=HANTS,C=GB'. But found %v", output)
}
// One personal certificate that is correctly relabeld as QM1
count, found = scanForText(output, "-", "QM1")
if count != 1 && !found {
t.Errorf("Expected 1 personal certificate with name containing QM1. But found %v", output)
}
}
} else {
rc := waitForContainer(t, cli, ctr.ID, 20*time.Second)
// Expect return code 1 if container failed to create.
if rc == 1 {
// Get container logs and search for specific message.
logs := inspectLogs(t, cli, ctr.ID)
if !strings.Contains(logs, expecteOutPut) {
t.Errorf("Container creating failed because of invalid certifates")
}
} else {
// Some other error occurred
t.Errorf("Some other error occurred %v", rc)
}
}
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2021
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -548,9 +548,14 @@ func getCoverageExitCode(t *testing.T, orig int64) int64 {
func waitForContainer(t *testing.T, cli *client.Client, ID string, timeout time.Duration) int64 {
c, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
rc, err := cli.ContainerWait(c, ID)
if err != nil {
t.Logf("Waiting for container for %s", timeout)
okC, errC := cli.ContainerWait(c, ID, container.WaitConditionNotRunning)
var rc int64
select {
case err := <-errC:
t.Fatal(err)
case ok := <-okC:
rc = ok.StatusCode
}
if coverage() {
// COVERAGE: When running coverage, the exit code is written to a file,
@@ -579,7 +584,7 @@ func execContainer(t *testing.T, cli *client.Client, ID string, user string, cmd
if err != nil {
t.Fatal(err)
}
hijack, err := cli.ContainerExecAttach(context.Background(), resp.ID, config)
hijack, err := cli.ContainerExecAttach(context.Background(), resp.ID, types.ExecStartCheck{})
if err != nil {
t.Fatal(err)
}
@@ -686,7 +691,7 @@ func removeNetwork(t *testing.T, cli *client.Client, ID string) {
}
func createVolume(t *testing.T, cli *client.Client, name string) types.Volume {
v, err := cli.VolumeCreate(context.Background(), volume.VolumesCreateBody{
v, err := cli.VolumeCreate(context.Background(), volume.VolumeCreateBody{
Driver: "local",
DriverOpts: map[string]string{},
Labels: map[string]string{},
@@ -740,6 +745,7 @@ func inspectLogs(t *testing.T, cli *client.Client, ID string) string {
t.Fatal(err)
}
buf := new(bytes.Buffer)
// Each output line has a header, which needs to be removed
_, err = stdcopy.StdCopy(buf, buf, reader)
if err != nil {
@@ -884,3 +890,99 @@ func getMQVersion(t *testing.T, cli *client.Client) (string, error) {
version := inspect.ContainerConfig.Labels["version"]
return version, nil
}
// scanForExcludedEntries scans for default excluded messages
func scanForExcludedEntries(msg string) bool {
if strings.Contains(msg, "AMQ5041I") || strings.Contains(msg, "AMQ5052I") ||
strings.Contains(msg, "AMQ5051I") || strings.Contains(msg, "AMQ5037I") ||
strings.Contains(msg, "AMQ5975I") {
return true
}
return false
}
// checkLogForValidJSON checks if the message is in Json format
func checkLogForValidJSON(jsonLogs string) bool {
scanner := bufio.NewScanner(strings.NewReader(jsonLogs))
for scanner.Scan() {
var obj map[string]interface{}
s := scanner.Text()
err := json.Unmarshal([]byte(s), &obj)
if err != nil {
return false
}
}
return true
}
// runContainerWithAllConfig creates and starts a container, using the supplied ContainerConfig, HostConfig,
// NetworkingConfig, and container name (or the value of t.Name if containerName="").
func runContainerWithAllConfigError(t *testing.T, cli *client.Client, containerConfig *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (string, error) {
if containerName == "" {
containerName = t.Name()
}
if containerConfig.Image == "" {
containerConfig.Image = imageName()
}
// Always run as a random user, unless the test has specified otherwise
if containerConfig.User == "" {
containerConfig.User = generateRandomUID()
}
// if coverage
containerConfig.Env = append(containerConfig.Env, "COVERAGE_FILE="+t.Name()+".cov")
containerConfig.Env = append(containerConfig.Env, "EXIT_CODE_FILE="+getExitCodeFilename(t))
t.Logf("Running container (%s)", containerConfig.Image)
ctr, err := cli.ContainerCreate(context.Background(), containerConfig, hostConfig, networkingConfig, containerName)
if err != nil {
return "", err
}
err = startContainerError(t, cli, ctr.ID)
if err != nil {
return "", err
}
return ctr.ID, nil
}
func startContainerError(t *testing.T, cli *client.Client, ID string) error {
t.Logf("Starting container: %v", ID)
startOptions := types.ContainerStartOptions{}
err := cli.ContainerStart(context.Background(), ID, startOptions)
if err != nil {
return err
}
return nil
}
// testLogFilePages validates that the specified number of logFilePages is present in the qm.ini file.
func testLogFilePages(t *testing.T, cli *client.Client, id string, qmName string, expectedLogFilePages string) {
catIniFileCommand := fmt.Sprintf("cat /var/mqm/qmgrs/" + qmName + "/qm.ini")
_, iniContent := execContainer(t, cli, id, "", []string{"bash", "-c", catIniFileCommand})
if !strings.Contains(iniContent, "LogFilePages="+expectedLogFilePages) {
t.Errorf("Expected qm.ini to contain LogFilePages="+expectedLogFilePages+"; got qm.ini \"%v\"", iniContent)
}
}
//waitForMessageInLog will check for a particular message with wait
func waitForMessageInLog(t *testing.T, cli *client.Client, id string, expecteMessageId string) (string, error) {
var jsonLogs string
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
for {
select {
case <-time.After(1 * time.Second):
jsonLogs = inspectLogs(t, cli, id)
if strings.Contains(jsonLogs, expecteMessageId) {
return jsonLogs, nil
}
case <-ctx.Done():
return "", fmt.Errorf("Expected message Id %s was not logged.", expecteMessageId)
}
}
}
// Returns fully qualified path
func tlsDirDN(t *testing.T, unixPath bool, certPath string) string {
return filepath.Join(getCwd(t, unixPath), certPath)
}

View File

@@ -1,20 +1,40 @@
module github.com/ibm-messaging/mq-container/test/docker
go 1.15
go 1.19
require (
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/Microsoft/go-winio v0.4.14 // indirect
github.com/Sirupsen/logrus v1.0.5 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v1.13.2-0.20170601211448-f5ec1e2936dc
// Note: This is not actually Docker v17.12!
// Go modules require the use of semver, but Docker does not use semver and has not
// [opted-in to use Go modules](https://github.com/golang/go/wiki/Modules#can-a-module-consume-a-package-that-has-not-opted-in-to-modules)
// This means that when you `go get` Docker, you need to do so based on a commit,
// e.g. `go get -v github.com/docker/docker@420b1d36250f9cfdc561f086f25a213ecb669b6f`,
// which uses the commit for [Docker v19.03.15](https://github.com/moby/moby/releases/tag/v19.03.15)
// Go will then find the latest tag with a semver-compatible tag. In Docker's case,
// v17.12.0 is valid semver, but v18.09 and v19.03 are not.
// Also note: Docker v20.10 is valid semver, but the v20.10 client API requires use of Docker API
// version 1.41 on the server, which is currently too new for the version of Docker in Travis (Ubuntu Bionic)
github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompatible
github.com/docker/go-connections v0.4.0
github.com/docker/go-units v0.4.0 // indirect
github.com/onsi/ginkgo v1.14.1 // indirect
github.com/onsi/gomega v1.10.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/spf13/cobra v1.1.1 // indirect
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
)
require (
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/containerd/containerd v1.6.6 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
google.golang.org/grpc v1.46.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gotest.tools v2.2.0+incompatible // indirect
)

View File

@@ -1,366 +1,199 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Sirupsen/logrus v1.0.5 h1:447dy9LxSj+Iaa2uN3yoFHOzU9yJcJYiQPtNz8OXtv0=
github.com/Sirupsen/logrus v1.0.5/go.mod h1:rmk17hk6i8ZSAJkSDa7nOxamrG+SP4P0mm+DAvExv4U=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0=
github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v1.13.2-0.20170601211448-f5ec1e2936dc h1:y4nIGNQUH6JtUV3pd6HjnzdnHq+96wMDVXhkfZ6jc4E=
github.com/docker/docker v1.13.2-0.20170601211448-f5ec1e2936dc/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.2+incompatible h1:vFgEHPqWBTp4pTjdLwjAA4bSo3gvIGOYwuJTlEjVBCw=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompatible h1:nhVo1udYfMj0Jsw0lnqrTjjf33aLpdgW9Wve9fHVzhQ=
github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2019, 2020
© Copyright IBM Corporation 2019, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ limitations under the License.
package main
import (
"context"
"strings"
"testing"
"time"
@@ -33,7 +34,7 @@ var miEnv = []string{
// and starts/stop them checking we always have an active and standby
func TestMultiInstanceStartStop(t *testing.T) {
t.Skipf("Skipping %v until test defect fixed", t.Name())
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -75,7 +76,7 @@ func TestMultiInstanceStartStop(t *testing.T) {
// TestMultiInstanceContainerStop starts 2 containers in a multi instance queue manager configuration,
// stops the active queue manager, then checks to ensure the backup queue manager becomes active
func TestMultiInstanceContainerStop(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -92,15 +93,28 @@ func TestMultiInstanceContainerStop(t *testing.T) {
waitForReady(t, cli, qm1aId)
waitForReady(t, cli, qm1bId)
err, active, standby := getActiveStandbyQueueManager(t, cli, qm1aId, qm1bId)
err, originalActive, originalStandby := getActiveStandbyQueueManager(t, cli, qm1aId, qm1bId)
if err != nil {
t.Fatal(err)
}
stopContainer(t, cli, active)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
stopContainer(t, cli, originalActive)
if status := getQueueManagerStatus(t, cli, standby, "QM1"); strings.Compare(status, "Running") != 0 {
t.Fatalf("Expected QM1 to be running as active queue manager, dspmq returned status of %v", status)
for {
status := getQueueManagerStatus(t, cli, originalStandby, "QM1")
select {
case <-time.After(1 * time.Second):
if status == "Running" {
t.Logf("Original standby is now the active")
return
} else if status == "Starting" {
t.Logf("Original standby is starting")
}
case <-ctx.Done():
t.Fatalf("%s Timed out waiting for standby to become the active. Status=%v", time.Now().Format(time.RFC3339), status)
}
}
}
@@ -109,7 +123,7 @@ func TestMultiInstanceContainerStop(t *testing.T) {
func TestMultiInstanceRace(t *testing.T) {
t.Skipf("Skipping %v until file lock is implemented", t.Name())
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -155,7 +169,7 @@ func TestMultiInstanceRace(t *testing.T) {
// mounts, then checks to ensure that the container terminates with the expected message
func TestMultiInstanceNoSharedMounts(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -174,7 +188,7 @@ func TestMultiInstanceNoSharedMounts(t *testing.T) {
// TestMultiInstanceNoSharedLogs starts 2 multi instance queue managers without providing a shared log
// mount, then checks to ensure that the container terminates with the expected message
func TestMultiInstanceNoSharedLogs(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -196,7 +210,7 @@ func TestMultiInstanceNoSharedLogs(t *testing.T) {
// TestMultiInstanceNoSharedData starts 2 multi instance queue managers without providing a shared data
// mount, then checks to ensure that the container terminates with the expected message
func TestMultiInstanceNoSharedData(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -218,7 +232,7 @@ func TestMultiInstanceNoSharedData(t *testing.T) {
// TestMultiInstanceNoMounts starts 2 multi instance queue managers without providing a shared data
// mount, then checks to ensure that the container terminates with the expected message
func TestMultiInstanceNoMounts(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2019
© Copyright IBM Corporation 2019, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -77,6 +77,7 @@ func getActiveStandbyQueueManager(t *testing.T, cli *client.Client, qm1aId strin
func getQueueManagerStatus(t *testing.T, cli *client.Client, containerID string, queueManagerName string) string {
_, dspmqOut := execContainer(t, cli, containerID, "", []string{"bash", "-c", "dspmq", "-m", queueManagerName})
t.Logf("dspmq for %v (%v) returned: %v", containerID, queueManagerName, dspmqOut)
regex := regexp.MustCompile(`STATUS\(.*\)`)
status := regex.FindString(dspmqOut)
status = strings.TrimSuffix(strings.TrimPrefix(status, "STATUS("), ")")

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2021
© Copyright IBM Corporation 2021, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,15 +16,15 @@ limitations under the License.
package main
import (
"testing"
"github.com/docker/docker/client"
"strings"
"testing"
)
// TestNativeHABasic creates 3 containers in a Native HA queue manager configuration
// and ensures the queue manger and replicas start as expected
func TestNativeHABasic(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -74,7 +74,7 @@ func TestNativeHABasic(t *testing.T) {
// queue manager comes back as a replica
func TestNativeHAFailover(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -132,7 +132,7 @@ func TestNativeHAFailover(t *testing.T) {
// TestNativeHASecure creates 3 containers in a Native HA queue manager configuration
// with HA TLS enabled, and ensures the queue manger and replicas start as expected
func TestNativeHASecure(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -177,7 +177,7 @@ func TestNativeHASecure(t *testing.T) {
// with HA TLS enabled, overrides the default CipherSpec, and ensures the queue manger
// and replicas start as expected
func TestNativeHASecureCipherSpec(t *testing.T) {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -217,3 +217,96 @@ func TestNativeHASecureCipherSpec(t *testing.T) {
}
}
// TestNativeHASecure creates 3 containers in a Native HA queue manager configuration
// with HA TLS FIPS enabled, overrides the default CipherSpec, and ensures the queue manger
// and replicas start as expected. This test uses FIPS compliant cipher.
func TestNativeHASecureCipherSpecFIPS(t *testing.T) {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
version, err := getMQVersion(t, cli)
if err != nil {
t.Fatal(err)
}
if version < "9.2.2.0" {
t.Skipf("Skipping %s as test requires at least MQ 9.2.2.0, but image is version %s", t.Name(), version)
}
containerNames := [3]string{"QM1_1", "QM1_2", "QM1_3"}
qmReplicaIDs := [3]string{}
qmNetwork, err := createBridgeNetwork(cli, t)
if err != nil {
t.Fatal(err)
}
defer removeBridgeNetwork(cli, qmNetwork.ID)
for i := 0; i <= 2; i++ {
containerConfig := getNativeHAContainerConfig(containerNames[i], containerNames, defaultHAPort)
// MQ_NATIVE_HA_CIPHERSPEC is set a FIPS compliant cipherspec.
containerConfig.Env = append(containerConfig.Env, "MQ_NATIVE_HA_TLS=true", "MQ_NATIVE_HA_CIPHERSPEC=TLS_RSA_WITH_AES_128_GCM_SHA256", "MQ_ENABLE_FIPS=true")
hostConfig := getNativeHASecureHostConfig(t)
networkingConfig := getNativeHANetworkConfig(qmNetwork.ID)
ctr := runContainerWithAllConfig(t, cli, &containerConfig, &hostConfig, &networkingConfig, containerNames[i])
defer cleanContainer(t, cli, ctr)
qmReplicaIDs[i] = ctr
}
waitForReadyHA(t, cli, qmReplicaIDs)
// Display the contents of qm.ini
_, qmini := execContainer(t, cli, qmReplicaIDs[0], "", []string{"cat", "/var/mqm/qmgrs/QM1/qm.ini"})
if !strings.Contains(qmini, "SSLFipsRequired=Yes") {
t.Errorf("Expected SSLFipsRequired=Yes but it is not; got \"%v\"", qmini)
}
_, err = getActiveReplicaInstances(t, cli, qmReplicaIDs)
if err != nil {
t.Fatal(err)
}
}
// TestNativeHASecure creates 3 containers in a Native HA queue manager configuration
// with HA TLS FIPS enabled with non-FIPS cipher, overrides the default CipherSpec, and
// ensures the queue manger and replicas don't start as expected
func TestNativeHASecureCipherSpecNonFIPSCipher(t *testing.T) {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
version, err := getMQVersion(t, cli)
if err != nil {
t.Fatal(err)
}
if version < "9.2.2.0" {
t.Skipf("Skipping %s as test requires at least MQ 9.2.2.0, but image is version %s", t.Name(), version)
}
containerNames := [3]string{"QM1_1", "QM1_2", "QM1_3"}
qmReplicaIDs := [3]string{}
qmNetwork, err := createBridgeNetwork(cli, t)
if err != nil {
t.Fatal(err)
}
defer removeBridgeNetwork(cli, qmNetwork.ID)
for i := 0; i <= 2; i++ {
containerConfig := getNativeHAContainerConfig(containerNames[i], containerNames, defaultHAPort)
// MQ_NATIVE_HA_CIPHERSPEC is set a FIPS non-compliant cipherspec - SSL_ECDHE_ECDSA_WITH_RC4_128_SHA
containerConfig.Env = append(containerConfig.Env, "MQ_NATIVE_HA_TLS=true", "MQ_NATIVE_HA_CIPHERSPEC=TLS_RSA_WITH_AES_128_GCM_SHA256", "MQ_ENABLE_FIPS=true")
hostConfig := getNativeHASecureHostConfig(t)
networkingConfig := getNativeHANetworkConfig(qmNetwork.ID)
ctr, err := runContainerWithAllConfigError(t, cli, &containerConfig, &hostConfig, &networkingConfig, containerNames[i])
defer cleanContainer(t, cli, ctr)
// We expect container to fail in this case because the cipher is non-FIPS and we have asked for FIPS compliance
// by setting MQ_ENABLE_FIPS=true
if err == nil {
t.Logf("Container start expected to fail but did not. %v", err)
}
qmReplicaIDs[i] = ctr
}
}

View File

@@ -106,7 +106,7 @@ func getActiveReplicaInstances(t *testing.T, cli *client.Client, qmReplicaIDs [3
func waitForReadyHA(t *testing.T, cli *client.Client, qmReplicaIDs [3]string) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Minute)
defer cancel()
for {

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2019
© Copyright IBM Corporation 2018, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import (
func TestGoldenPathMetric(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -55,7 +55,7 @@ func TestGoldenPathMetric(t *testing.T) {
func TestMetricNames(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -100,7 +100,7 @@ func TestMetricLabels(t *testing.T) {
t.Parallel()
requiredLabels := []string{"qmgr"}
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -148,7 +148,7 @@ func TestMetricLabels(t *testing.T) {
func TestRapidFirePrometheus(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -182,7 +182,7 @@ func TestRapidFirePrometheus(t *testing.T) {
func TestSlowPrometheus(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -213,7 +213,7 @@ func TestSlowPrometheus(t *testing.T) {
func TestContainerRestart(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -261,7 +261,7 @@ func TestContainerRestart(t *testing.T) {
func TestQMRestart(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -319,7 +319,7 @@ func TestQMRestart(t *testing.T) {
func TestValidValues(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}
@@ -355,7 +355,7 @@ func TestValidValues(t *testing.T) {
func TestChangingValues(t *testing.T) {
t.Parallel()
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
t.Fatal(err)
}

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2018, 2021
# © Copyright IBM Corporation 2018, 2022
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,24 +15,24 @@
###############################################################################
# Application build environment (Maven)
###############################################################################
FROM registry.redhat.io/ubi8/openjdk-8 as builder
COPY pom.xml .
FROM registry.access.redhat.com/ubi8/openjdk-8 as builder
COPY pom.xml ./
#WORKDIR /usr/src/mymaven
# Download dependencies separately, so Docker caches them
RUN mvn dependency:go-offline install
# Copy source
COPY src .
COPY src ./src
# Run the main build
RUN mvn --offline install
# Print a list of all the files (useful for debugging)
RUN find .
RUN find ./
###############################################################################
# Application runtime (JRE only, no build environment)
###############################################################################
# OpenJDK is not technically supported with the MQ client, but is good enough for these tests
FROM registry.redhat.io/ubi8/openjdk-8-runtime
FROM registry.access.redhat.com/ubi8/openjdk-8-runtime
COPY --from=builder /home/jboss/target/*.jar /opt/app/
COPY --from=builder /home/jboss/target/lib/*.jar /opt/app/
USER 1001
ENTRYPOINT ["java", "-classpath", "/opt/app/*", "org.junit.platform.console.ConsoleLauncher", "-p", "com.ibm.mqcontainer.test", "--details", "verbose"]
ENTRYPOINT ["java", "-classpath", "/opt/app/*", "org.junit.platform.console.ConsoleLauncher", "--fail-if-no-tests", "-p", "com.ibm.mqcontainer.test", "--details", "verbose"]

View File

@@ -1,5 +1,5 @@
<!--
© Copyright IBM Corporation 2018, 2021
© Copyright IBM Corporation 2018, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -26,25 +26,25 @@ limitations under the License.
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.2.0.0</version>
<version>9.3.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.2</version>
<version>5.8.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.2</version>
<version>5.8.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-console-standalone</artifactId>
<version>1.5.2</version>
<version>1.8.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018, 2021
© Copyright IBM Corporation 2018, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -82,11 +82,10 @@ class JMSTests {
boolean ibmjre = System.getenv("IBMJRE").equals("true");
if (ibmjre){
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "true");
factory.setSSLCipherSuite("SSL_RSA_WITH_AES_128_CBC_SHA256");
} else {
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");
factory.setSSLCipherSuite("TLS_RSA_WITH_AES_128_CBC_SHA256");
}
factory.setSSLCipherSuite(System.getenv("MQ_TLS_CIPHER"));
}
return factory;
}

23
test/tlscacert/cacert.crt Normal file
View File

@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIUc5EKoPi8cg2M2n+SqCPn44LFjoAwDQYJKoZIhvcNAQEL
BQAwcjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9y
azEMMAoGA1UECgwDSUJNMQwwCgYDVQQLDANJQk0xDDAKBgNVBAMMA0lCTTEZMBcG
CSqGSIb3DQEJARYKbXFAaWJtLmNvbTAeFw0yMjEwMDYxMzA2NTVaFw0zMjEwMDMx
MzA2NTVaMHIxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTERMA8GA1UEBwwITmV3
IFlvcmsxDDAKBgNVBAoMA0lCTTEMMAoGA1UECwwDSUJNMQwwCgYDVQQDDANJQk0x
GTAXBgkqhkiG9w0BCQEWCm1xQGlibS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQCls3oNIDxzKct0NXVsoz1Hng3BcaDPcBRYCNgAEwDOVe3rEEbZ
d2KFliDgCG3hCHMM1Yaabx3iTVsKklubBxr1JFmyDtgb4z9mJpMVYXS+gsKsZOs/
vNSmzpt5VlbEadHKJ/aFf/EWxvoOP80UiEeUJt36aWFUTyjjyArd2xS8fD1DATFB
U2bteaWfkpuLeFiTtwftZhsLv1s5T35+Ex087eX1tkm/TArxZsNl/9RrSWsbJh/t
bjiRKn+fCZdirFsurP3Si5Jd9laCW0RBKAKYEh40XYDgjLhvcazDPTBueTHXQPG5
S0hCOhCJiCWpPCsh8rIOCz0D9YIByZADR1WvAgMBAAGjUzBRMB0GA1UdDgQWBBS5
OsiPqZXlMwpMqGKczUg3qVvy0zAfBgNVHSMEGDAWgBS5OsiPqZXlMwpMqGKczUg3
qVvy0zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBfwYRcckke
/NzDHlFb8TBlUDqERmlT/qTWamVZO2Zuo4Y0BFOYFEA23F5sQU2s2MFSEZcAKe5v
mJroFE2rr4aY4bJ4Z0UXlOAYyqNxVOTI4MIxwbg3GVr8c8oWBnAmgqI9W9OpgZ52
/bN24XL9s6I3TeOTtYI9z5O70Kl/E3nG8GcfMw0EtNIy0UPUWvJH8FgEsotsRO9v
tPtlZklEK/D+Keozbs2shdNhKgVnDatpdTBqvwLztb1+te5AckuOnJsnG+iIrG2D
Ehoq2O3gktIVdAk4sv2BoONzegLWB+GSxGVZsemfYF4PkN9/w+znz0LK/ATAtabK
rikk0yC+Xg8z
-----END CERTIFICATE-----

View File

@@ -0,0 +1,34 @@
#!/bin/bash -ex
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2022
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
KEY=server.key
CERT=server.crt
CACERT=cacert.crt
CAPEM=rootcakey.pem
# Create a private key and certificate in PEM format, for the server to use
openssl req \
-newkey rsa:2048 -nodes -keyout ${KEY} \
-subj "/CN=localhost" \
-addext "subjectAltName = DNS:localhost" \
-x509 -days 3650 -out ${CERT}
# Generate the private key of the root CA
openssl genrsa -out ${CAPEM} 2048
#Generate the self-signed root CA certificate. Manual input is required when prompted
openssl req -x509 -sha256 -new -nodes -key ${CAPEM} -days 3650 -out ${CACERT}

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEApbN6DSA8cynLdDV1bKM9R54NwXGgz3AUWAjYABMAzlXt6xBG
2XdihZYg4Aht4QhzDNWGmm8d4k1bCpJbmwca9SRZsg7YG+M/ZiaTFWF0voLCrGTr
P7zUps6beVZWxGnRyif2hX/xFsb6Dj/NFIhHlCbd+mlhVE8o48gK3dsUvHw9QwEx
QVNm7Xmln5Kbi3hYk7cH7WYbC79bOU9+fhMdPO3l9bZJv0wK8WbDZf/Ua0lrGyYf
7W44kSp/nwmXYqxbLqz90ouSXfZWgltEQSgCmBIeNF2A4Iy4b3Gswz0wbnkx10Dx
uUtIQjoQiYglqTwrIfKyDgs9A/WCAcmQA0dVrwIDAQABAoIBAQCcL9ZltPMF4mlh
+lnasuu6K+LvafmYTh7+9CcVutPRqfF+1nLR3NRC8sW+JnPb36kCeepMe1yByUR9
bINoV4QzebYKPi+56bQCx21wg9IVGRACi4WrKISRTsIB1z4mGVCj6pNWNsi7HYbq
E31tUx+VKCWoOdiCLbNvMUn84Npk5npK9P9F86qypSJqJv3HORgOa58x7qZiD2fk
TroLuGHKFWGtSiK1vvgax8gBwMi9JvWoPhwHagINh0WwT820+3/4KbqcsvRNSIu8
qA+ltk/Vt0ftwPMpxPYnvRFrSvzYIRE04fbWqA3mxhPr/oP3xXrwyd1hnX6GzPIR
KXeX1i7BAoGBANGV6XtL8cq8tu/4emOYDn4tncMRICQ8uMWZqnIQAvX8PBx1w9E2
Wbkl0oBHJ/gDtU+feDvbHI0JBvXerce2cxj4+793TGLUl980dgq776x2fcxHjvYZ
uZjJd4M95Lh+IhtWGZQ1FviiylDg62w+mrNydX8WiFjLGYPydQqCIAAxAoGBAMpl
m/MDqpgPxiDU1O9DAq8C/0MQUOc/p+67aGsYxmPDdCouBLA/zckQh6Cp9Wo3n7MF
X5UHOqn72q/4ahNEx+3YQoaLqRKTjUHl3r3zj+MsM0hIDp1uOxVzbANxazuLuqqA
C+yJTmRU7uvNPH1AMFJBKRSmhd3MJwoHF/KZAhvfAoGAFaGPU3ZnIjGP//x5RUYw
WL2EhtmBo7vQpjRR7yvP4muCGL3e0/z0DbPloe+2JFbdo7Ylxqe6rqO74Cx3ayFd
h7pK4VwCukCO3C6h8EGtXvNr0GWiT6wgB7DjcNw2ewQpqQCd6zn/gPHsR6SvJ6De
fp7VmaRNtjxgCcpAYjFD9EECgYAhEPaofjnZvAH/jSX4rPb8Rr4TY9AD58d03lNR
4+tNkzogRgJoFRR2u+ecnQfGQa4qnj8eZt7ztHzm8OvLmBodxo4f0yNdMJQMZxS7
7dXdJHSAY51XpRGsEH5eFaKSSOLHRkIsc8ZF6AZcqdwvDlSWq6SdhhMqyFa8cao8
7TiF+wKBgADNZ4HoZDfnuH5jUvf7y+YlxDX3jxWR+BUTLCJmt082uT+8Xg5SALec
B8GP5s6VKglD5Wzj8IhxvpQ5yzH9DRHwEeu3vFLBinIUlWdBiXwtnbmY0E9r3PSb
pZQH5RZ5PyrJicIVBJSqdFu2HDl4heeLJE0LGh7SQnFaexxXn397
-----END RSA PRIVATE KEY-----

19
test/tlscacert/server.crt Normal file
View File

@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDHzCCAgegAwIBAgIUUFCo8fUglrbfDY8ZUDnzAfWeq54wDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIyMTAwNjEzMDYwMloXDTMyMTAw
MzEzMDYwMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAxcja4TbshPj4tWgbRP73eDs2382j6Km5TNej6To13PJq
Wyezg081ctmgFEMlgbRiowZmecpYOKjDKuVDtfLE6nZMmN+PjXXuOMGIPu67fx/4
tnaMDYw96WIBEFNVZ7dC/pceaTIRbnjma89o1/mTudTAYPLAvKpeBqpJJFWPMDhz
nK3NKeydTdUYc9jmEJWiFCI4bUdyvyUjp+7QrDbdODXo27/nVAV0Ih+OuU4ZnxT5
cf1fzVV1ZqHd8jbLm25ZoAmkk+9DSXFNA2hbSepf70mRVD/Qyn8U6b5A2v+mWIfs
B1+iAlPl7IX88W1Q9q1yu0uT8YWGWpeTbeOnJ4WJ8wIDAQABo2kwZzAdBgNVHQ4E
FgQUEjp6AtPmpuLQyBPeiW4pW+VGb2wwHwYDVR0jBBgwFoAUEjp6AtPmpuLQyBPe
iW4pW+VGb2wwDwYDVR0TAQH/BAUwAwEB/zAUBgNVHREEDTALgglsb2NhbGhvc3Qw
DQYJKoZIhvcNAQELBQADggEBAL2bTWfTqxfN0YbBPjG05sR4nO8mhbNSGHDuGeiO
OP0wPxkgAueScTpyhHWEAJmMQOMUM9KhByZj7LnqW8XY9BBS3zPAyzAdia8/o6Vl
7El+M2JCfqz7hSupRK8M+r+XUq3hyEFjPLt+KO6D5VNzXiTM+36UueeQD3aaxxyo
LpHSPeXFBkOrT/wt6FHi4NHvWls95PllncWZVYjxPMUUF/o30tOxSmgXwjUknrI8
29ADKM1IbFuXd4vKYG9V+ukI6n5F86PYrN2ajPBKIidvTqU8tPzMHuJZ3YiIiv8p
TARE2b5YLWuu+aF2z/V71MmIWr0uyOk6pZVGOCw7fwHx/wg=
-----END CERTIFICATE-----

28
test/tlscacert/server.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFyNrhNuyE+Pi1
aBtE/vd4OzbfzaPoqblM16PpOjXc8mpbJ7ODTzVy2aAUQyWBtGKjBmZ5ylg4qMMq
5UO18sTqdkyY34+Nde44wYg+7rt/H/i2dowNjD3pYgEQU1Vnt0L+lx5pMhFueOZr
z2jX+ZO51MBg8sC8ql4GqkkkVY8wOHOcrc0p7J1N1Rhz2OYQlaIUIjhtR3K/JSOn
7tCsNt04Nejbv+dUBXQiH465ThmfFPlx/V/NVXVmod3yNsubblmgCaST70NJcU0D
aFtJ6l/vSZFUP9DKfxTpvkDa/6ZYh+wHX6ICU+XshfzxbVD2rXK7S5PxhYZal5Nt
46cnhYnzAgMBAAECggEBAKLRsZZbf6QLzbqRBHntJ04b+RWOlVOQfRHMJ4x1Nig4
i+OUsEv1pftxOj3T9QlstRKdzziNociq7VffurkLLJ4TWwUybVu37K9easncABAs
ArQ6rRruC32YB2YoJBOoowcw4oEZDY6TCqVP7nB1be46PVDSJmZqHdOA1YuKv8Ci
FbzLZEKYy6QGmHp9xMzc3usQ+KRNIFcR3NJb0eCbfAXb0tP3F12i4ygnxifkOVQS
hukTJlZVbAO3W9uUEzLh5bkLoPfob6Vrwv1tGQ48uFgzgPXc4bWOUDFXHW5+vQLD
1MKFboozrNhRR+Q5xvbRnaWEv4hMHlUNggc5ErRj6CkCgYEA5m5f1VfhfqSvEF2c
XcIfUDiCzREpllY2ZdBSfUlz/GA6f0QUyFJBCdd4ypipQcggn60de9DoKDcNcq32
rfVfANpsciJq9s4+xLL8MGtUuoi4HK8LHP3tc8aJaAcCVjBFbz0orKXDUOcue6A5
Z5riDjiXOE56XSLSSNSRjWh4psUCgYEA27sfaM4J0YkdFuth/Qu+X9PeroUZyC0T
3glMN/7PU4jZg+2v4Psfe61gj8qOt0catuWvsD0wQTy3jt+svY/KfkbspK6/7CEG
fKx1AB1xeMr4JuQp9POFVhKRn4sBUMbHOkbjzlNpGmUI2arlLRTwT8YpuMDjCK4l
ZuUYB/IHOVcCgYAqexqryCHIKTAlAjz7g/gl3+UtTQavsoEg0AEFG++IDW17XN+/
9noLCHA6WV6KxAxPo6iV1POXxl5yT+P0OhIjpCDuAa5ahbdIp/6aJo9ePCpFD3gr
Bh0qhOV8Ch7CKPAEC/Bds8mINrZ5EBbFJOab3I70UHN6jBrcVmPm/+WOSQKBgQCW
AbBWt1qCnu2qCPWzcAH+n8DFOf645vVKPuS20ZEuwR1l8K2ClU4P+/QRFkLKIpO9
Sx7e3VcFInNZ6Z+fJfwiqz7AysAhbwZjtMSHWJJv2XkB7AAsxtc/RJv/5ED4qUu3
oE/DOrRlHZamKwIb/dB1VZ6ED8Ku2VyVW09FlViTLwKBgEU21xqvP1+TXzsrZNGm
/Hj/RAaA8B6tyo5Dj9glV80oakMSaxBsLP9xHkoZjkHaJnoFosKBQSnCcPnEY4gP
22WEyGshu8sujLibLKWhARqjeubatXv+XBxiDdMbgcd/XTwbI4HTjXy5LF0o47UI
W6itMOg9uCfBJM/i2jrAkmQR
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDiTCCAnECFClOtyvBoQXVAGMcX0ObUawZJuYAMA0GCSqGSIb3DQEBCwUAMH0x
CzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEMMAoGA1UEBwwDQkxSMQwwCgYDVQQK
DANJQk0xDDAKBgNVBAsMA0lTTDEQMA4GA1UEAwwHTVFNRlRRTTElMCMGCSqGSIb3
DQEJARYWc2hhc2hpa2FudGhAaW4uaWJtLmNvbTAeFw0yMzAxMjUwNjQzMTBaFw0y
NTA0MjkwNjQzMTBaMIGEMQswCQYDVQQGEwJVUzELMAkGA1UECAwCSUwxEDAOBgNV
BAcMB0NISUNBR08xEDAOBgNVBAoMB0J1cnJhZ28xCzAJBgNVBAsMAkJHMRAwDgYD
VQQDDAdNUVFNQ05UMSUwIwYJKoZIhvcNAQkBFhZzaGFzaGlrYW50aEBpbi5pYm0u
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAys3CaU4vXdZuKyw5
AMkM4onEiJk3/TulWZIrXvFMgYLzAPX5eVUzs+eKfSBVIRiDGtsbmhcztT1GiAU6
l8G9jHSegItJpKjiBEfFEuMmV6Fhx7ZjQdpyGdV+0bcE2IJHmeiaNxouvsV5gBJT
vEamVsw9zU7GGOhhMyBQUUQDNy7yoHn8CBhDdoBskwJtpqPcxzohUDDt5wqSqOUl
jo8yS375k4Q18hWzWIxJIAHoAFk+YyJqLq3mqq438Z9WSgjv9V+eLpNtKlge2IzW
d1uH/siXE8Pp6p3WleG7cw2dzQZap+ekbx+3rRVLs8WYBHeTx08980sv6bBUKwHw
aXXXSQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAMrE0nDBw8wfPR8w7hrUPyG1Ib
/k72yAv9wqaso1pL4IpXE3DFbuoIOQLjNCr+C7h2IzegRZ1z4kZbWh7LeES7M0io
yDgM16Vikr9ek+NCLmF5QAtn/smhfhSEOjJoGkTPUTdWR4VdLeMFGQ9D8LHc0DFP
EyPZy0JZQpRiXAs0ZEDhlFOCxI1aZzJhwGBJd9wOlG/SZKI8izC74mNPU1eE7Js6
1sdU+4zs2wm/QtZ1MLlkKspSQqdNis/wpSSyjTEr9TkfzxVr4f3bALjQydkrcAyv
BkATBYqvJYSHA3PS8VxNTDVef5EgKEWXlCmP/jfMcYNsUxBjaUcqiJJcmI9e
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAys3CaU4vXdZuKyw5AMkM4onEiJk3/TulWZIrXvFMgYLzAPX5
eVUzs+eKfSBVIRiDGtsbmhcztT1GiAU6l8G9jHSegItJpKjiBEfFEuMmV6Fhx7Zj
QdpyGdV+0bcE2IJHmeiaNxouvsV5gBJTvEamVsw9zU7GGOhhMyBQUUQDNy7yoHn8
CBhDdoBskwJtpqPcxzohUDDt5wqSqOUljo8yS375k4Q18hWzWIxJIAHoAFk+YyJq
Lq3mqq438Z9WSgjv9V+eLpNtKlge2IzWd1uH/siXE8Pp6p3WleG7cw2dzQZap+ek
bx+3rRVLs8WYBHeTx08980sv6bBUKwHwaXXXSQIDAQABAoIBAQCdbqs7yij1BG/T
ben2VRx+g4ogrCiNmY7bgJ/QfSrx4vC3TztR2DVhtB2K0t2i6n9kCrFbpiVKzX2C
O+TnR8vYS/N7QCV0AHIr9nbjGZh7MFlSiqB0z5oBuf1P2W6WkFP7A1kr61RcXbnb
FN8R6hpYiQZ06XDYhxRldvFClLSWUaZOhM6DoEcfNV5djDWPv4tSlw0ILvgIDfeu
DfW5d6ih51CT+NqtXUZNgWB4WCFrqxLz2H197QtFNbeEnT2kqU81LiSR6ZLU2LAc
SEhWD9xpldPvm6CsYDy9LQazG+F4KA45OGgiHUfB43EvGnDHJEeX4HFMFWYKmefa
VQRD5GKBAoGBAPEQXruYnfYk3B+arl4GWCZd37TQd4ik2HybkhxPK/LXLJhuImun
6gYu0Y5dSpBv0B6LjhTencAjgfZRSiCplxbnnPMg2Tuu1FAjG7W5UlKsT8IlmHR3
3LqublsCQDaww/pBlXMsT7TUe89uH05v5Fn4pwp5Hy6IArhJLecDoYk5AoGBANde
hrLVn0XhFwQWe11vbhclF9KtJHqspXhKX6mRcQ4VSzoGuaji+ISyfoCaU6kVQrq8
WCZIOcTJTDScrk3BYQbY0+I6hBIug3SXhR8pGshQHvGOC/pAUInzWO3xc3lbJAwR
aK70zN8wXFJjc1rOivMY/mRvdJSYlPmr2e5fJg6RAoGAEj97/FVsN7LImvfZlTKD
v7vBcG2LbuOTo7MfF1eC6yoQrSVBI8cdNwSaRl2XhGGCbp1/zuKfLGlDsEKtCtXr
owc7YUguSY9NcReHRHVX3vw+OWMhLEfahKMppWgBNmKhIzONvZ8wFW80RBqA8i4U
Kh9hfbB3hM0074BSojcrJjkCgYEApavzVjJ6WRjzyZM5xwBm4asJDmlefHe+ujAM
MrbNDxZWTgbKXx5qKjnckjUlUhYmxNsJvDknJzfqRTaZ5vpxFwFIzOhSnGHngZLl
Nrk5/wmTJCIvGIzM57GooTFxsNLpgdcKfjuWNcJP4pjaLepgfOynFL+gIIbXYtBN
zs6myeECgYBp2shsVXAo0G2Iw5qSrPmsC0WurVYv5jZSAcnbV468vgGKP+L65nou
c7iuLWFJdsvgZUXWyijsQNmkOpNDkfYxcimFtNWMzt2IcoAEQzk5VO0Ok6EfrVCr
S1Kj0bo7oOyy0eZfQKVs39gE+ZKc8Fn2s4w4l6ZayhTKcfW6lwrJJA==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID2zCCAsOgAwIBAgIUdbPSj6WWhFu2amL9voKbyCMKiB4wDQYJKoZIhvcNAQEL
BQAwfTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQwwCgYDVQQHDANCTFIxDDAK
BgNVBAoMA0lCTTEMMAoGA1UECwwDSVNMMRAwDgYDVQQDDAdNUU1GVFFNMSUwIwYJ
KoZIhvcNAQkBFhZzaGFzaGlrYW50aEBpbi5pYm0uY29tMB4XDTIzMDEyNTA1MjEz
NloXDTI4MDEyNDA1MjEzNlowfTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQww
CgYDVQQHDANCTFIxDDAKBgNVBAoMA0lCTTEMMAoGA1UECwwDSVNMMRAwDgYDVQQD
DAdNUU1GVFFNMSUwIwYJKoZIhvcNAQkBFhZzaGFzaGlrYW50aEBpbi5pYm0uY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwl9MlmCNG7kzk7qKGuBX
jTONcn2OcifKfwgJlvzTqHcf8X/BIiyOOiwoeznke///LLtt9ygF0iyBMQYM/CG/
rzOR6tbzI4y4Bmx6VqY02CkXi/p66ywQ7B5N2Fdp9Bop3SnthTcT4NoXBSEUhI1O
ob8lDFv1KMRkCULD2sA0FUYCrHtw0M/vEOqsA9VVjyzOXsIlbbR1BSXtlWNneGeL
OAdmQWO3QYCku/YrCyJlscvIisjp4s7guGnQh0Ws8h50R5sqag8RvdHUwExVLUfZ
L1Od0+hCiO5mNfKekT0cs9owplcwgNHw88b8q4/aHDBtQRgsukkMxTpo00ftPJxI
nwIDAQABo1MwUTAdBgNVHQ4EFgQUOyw89AeB0jXb5WCZv/5oDY8oWxkwHwYDVR0j
BBgwFoAUOyw89AeB0jXb5WCZv/5oDY8oWxkwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAQEAtbybQQ9GpY5gH7xz4EWOUZ7XMmBYtuGXVrqUd+76hvCA
H/SB0nl2bGp7tAKBttmXhfKVac6wFCbXvYe49B+Q9+iL7H9st9VZUPKLQ6K3Uet6
L1ggMm2BhecpuYbwkG7ZidVFo/SuUCbCTnXBgHjvq4IkVCaJe7aKZmejSCh7gsIR
BQkZvz/22Vx/WPTEYp0x/riIvSViBjLCuD25Y+nCtS8c2xGVBjs9Q4GWCOAvEfAr
Tqs42brH1Vs92xS143p2h/wv52tmhfJI6X9QVQBBUoIjPR/VDFqZU5EYhAvuQPBi
UADz9hNYGQ9wBzZGvzbrorpoT+7aW9nGtmUsvvupBA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,3 @@
This directory contains private key and a certificate that signed by CA.
The directory also contains the CA certificate. The certificate and it's
CA certificate have different Subject DNs.

View File

@@ -0,0 +1,68 @@
-----BEGIN CERTIFICATE-----
MIIF5DCCA8ygAwIBAgICEAAwDQYJKoZIhvcNAQENBQAwgYsxCzAJBgNVBAYTAkdC
MQ4wDAYDVQQIDAVIQU5UUzETMBEGA1UEBwwKV2luY2hlc3RlcjEMMAoGA1UECgwD
SUJNMQ8wDQYDVQQLDAZIVVJJQk0xETAPBgNVBAMMCEhVUklCTUdCMSUwIwYJKoZI
hvcNAQkBFhZzaGFzaGlrYW50aEBpbi5pYm0uY29tMB4XDTIzMDEyODAyMjEyNFoX
DTMzMDEyNTAyMjEyNFowdjELMAkGA1UEBhMCR0IxDjAMBgNVBAgMBUhBTlRTMQww
CgYDVQQKDANJQk0xDzANBgNVBAsMBkhVUklCTTERMA8GA1UEAwwISFVSSUJNR0Ix
JTAjBgkqhkiG9w0BCQEWFnNoYXNoaWthbnRoQGluLmlibS5jb20wggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQDyTaomebXQXMGAs3ux3SSJnJseozpUIWS2
eUMG8U3YK81raVpFsGPcjDi4RdCo72SqwD3LKKJmyfz4NOlKpZJq5rhqaHkECRj/
GUKihl6Fr4OWlcJui/x4xeJmgFHvgnQEH/r8mvVVE8GqKHX9mRVOMaJtG14hm1qI
DoK+x9IwOut/H5FMeici/C11xIDK65/54vztb4wEfyRNK5e8dFwuD9yJo2gYM0GB
csQTq5WbKr0/uMF9rfFEx0lybHEASqgLCUA5lAGFtexefCFNxOxLnP4U2c5J+bcR
rGQ/hpfw02m0UU+fuNba8GPJbXJ6zT+FP0kme0180OKmH1zcNDRJuGY6OQ1nICHc
hf9QF95XQcwkf4MIltxZiNHbhSLuHrNFImv/AxiFchQJ+KPMLHV23x1uVKvRK3Mg
ZOEZmtCZVTRbOF6AWSTMGblu1tuxjSohO9ycqk8yQk/YkHW3zuEiIV+AAZW6qMKI
UZK64AoFb+E79gRpamz3ZOFfzNn/nKT4eMovDUUa8W4sVOVjBP2lT87xt7WBsE2f
mK4vE19hQGMzI3jZcMjIwNp4HjKIAeZb8o21ywogGF0qHctoINnEu7nG2trH02ug
0d+hwCfPRQHB7dicwTZm8ute4cHrwXed5tt1Bwv4Rq45GbwaOCAeZWa9S9GUaY/t
9xeS66HLPQIDAQABo2YwZDAdBgNVHQ4EFgQUMIuRPon0lwjMxi5tLwJYRcagTN0w
HwYDVR0jBBgwFoAUMjCCvlMnTcsiRvpiGPgBUGAA0EwwEgYDVR0TAQH/BAgwBgEB
/wIBADAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQENBQADggIBACPpl2Im9El6
m7T8cmtgXEW+rcQH/AA3px3+J/RnSWyRUi5fb0lc1RkfxQvuG7/sH3ywOc+uuB2b
3lg6zkNaP4tZYTEjrrkj5qFycoQcvem/5nBKuQ18+ZGulHqE+YzcPTmbNO2VzD5e
RJJpboiJa5TtM4wBeIuWbicWN+2wPeOkiQHxHEWtXOEVmbKzuREI6JHg2CDYMpWb
GWqS3hn9hfQoNhtSdtDFGChlsTpgKB/gRpYEfrlLKYKekJafD+xhEl/ZC2JDOtUr
/dZW4JicC++rUrMt89aFzEAOtcaR4dbL4NQhMRAlF9MdjZvHdcJqYEd3wqOymEnV
4ce1VpraZIh3qywqoOqf54vjd5DugpFoxjye+5ynzfMGX6RjwWnVRiY36kjFiMFR
iGhFT74lbRmw86RUQFjiXWAG9R0cR5s0EyOM3Egp/qRkWxbG6z7JeCdUd7Z/aaR3
iT081PUcQsl+jzCw2J6SDkemzZn/spkViodfzGJ5xEXB0fldIDarbDqOeWjSoKaz
LA7qIfPJptJkwybK/hBqvfR5fXx1VuubJdMfbo5jmP4OVCkNV5I6D5EMkYCxPrOl
9eVjYbndAVAXRF8vopJRqe067c+IwKPTnG4iIoXcR28efCBQ0Tv8DXYmHjSlVLdt
UCqYhFBxgGOUJLmqe7O9TWVk/aIM3Q3M
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIF9jCCA96gAwIBAgIBADANBgkqhkiG9w0BAQ0FADCBizELMAkGA1UEBhMCR0Ix
DjAMBgNVBAgMBUhBTlRTMRMwEQYDVQQHDApXaW5jaGVzdGVyMQwwCgYDVQQKDANJ
Qk0xDzANBgNVBAsMBkhVUklCTTERMA8GA1UEAwwISFVSSUJNR0IxJTAjBgkqhkiG
9w0BCQEWFnNoYXNoaWthbnRoQGluLmlibS5jb20wHhcNMjMwMTI4MDIxNjIzWhcN
MzMwMTI1MDIxNjIzWjCBizELMAkGA1UEBhMCR0IxDjAMBgNVBAgMBUhBTlRTMRMw
EQYDVQQHDApXaW5jaGVzdGVyMQwwCgYDVQQKDANJQk0xDzANBgNVBAsMBkhVUklC
TTERMA8GA1UEAwwISFVSSUJNR0IxJTAjBgkqhkiG9w0BCQEWFnNoYXNoaWthbnRo
QGluLmlibS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDjTlg8
0bZ3vzeYLJ1Z4zp/HplJSDzAn22EROJtHNb1pyfWfaO7UyUy5jNt1UJ6hTXy1xOS
r9eGaSu3kAm/R/METYgsMM56ALQ458VlLpZUEJBMgu63W6/FTckl5iUno7n9y3qL
2CKkHuEXG9jd/jPhBX+GLc+h1iwe1URaJSe1CLdSc8SMsGZUC3wMO3EAAqEOHh9j
BQy2qeWpR6oAF8HST5JX6lW+k/4NeNthdse8/Oqv1otPzseXE9jz09tz+4Qd5fdt
J8UcCWPcpAFb/TM6S2Hpr8xSqZr5+Em4JimdNDtEbJZKjzSwvmZ4S3qsUP0xb9ad
NgDjxYjBqNStgjrSzKGebazD6U4EDa8dXS6UxqgnxmtcSQLXIPcwfH9FniKnR7Tu
/cmSDOdWCedyxeDjrLlGuFUtJiSXCqRHU8c5KxTVkyDV1YZPjISktVJQS1/n39Lf
2TtHNTH3qTDfPzcgBqqczF+vlIKspE4YcTFBynOlL4biWZEsddOjpoqzamycMBqj
sEMlvydggS+Z8oZqDFVTU9/BCC2mth9HZr7hjO950IQcgVKexXOqxgPP4rmzEl2k
jEp9PKdDqBv7lOYjYO4taegfCZs5FPwaKtCStmzQLERMwSifqXe0TGV5obA8asRY
pOiZf6d9nVBvIYKotB1mNJTMqBke5hom8uarPQIDAQABo2MwYTAdBgNVHQ4EFgQU
MjCCvlMnTcsiRvpiGPgBUGAA0EwwHwYDVR0jBBgwFoAUMjCCvlMnTcsiRvpiGPgB
UGAA0EwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcN
AQENBQADggIBADYAHeWqQEg+oIC5qy8obEul4Zuk5J9HignrP8ef0+wdJf+Zx9/j
3nZKBrUrgZiBP+RJgNYLRByO9QT/q+P5dLfuLikyP377oLlVUcXQIXbJU60Yxdl5
wrpS9O8nfbwMUdi+1foGmA17zYNiTfBZ0/vem6yrhKdP6pS4h1+291tF3+mac0Q1
sx7RhssZT22YclH9u3U4q7Ef3q5ilqV5fb/Rm2z/iGtOLF2swm/jS1CEpJbyb0EE
yF8hoX8oliJdunmUqGV8bK5D7GFx47tyS5lU4B/Q14xBYUUc4hs83xAs667h0fym
0fbyQGh92bASPEDw6ep8eI6Iv+DSniwEFPG0ayDtnSEM/HkRVML497Rhqks/cP/9
rMJe9hUoetKO+p390R22EQLqGT6nvWV1jsGMHIMjJB7kfBLbgvFz8pQQdo7IxK4N
IirFdEn/atri2Z6baT6eqKt2tnjodQs1F+14rK1cj0QbH/tkHF8S411MclmufthB
U+VlEcjr4pnpVzvE4B78kXtlRH1N7Pj+vIgwpiC+hnWcQdqVF58E+7ERz9U1JqaQ
tX9c6aZW4m1pMcxR3c76NnYJi6rmhoL8xUNDq7HXrkK3DM0/rUvxl5HwfgGC0FGS
QmFgXgNddo2pj/TjnssE9XxFjsU+gEbGudGe0p5HR5qlKzTLc44WxcmW
-----END CERTIFICATE-----

View File

@@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIF7jCCA9agAwIBAgICEjQwDQYJKoZIhvcNAQENBQAwdjELMAkGA1UEBhMCR0Ix
DjAMBgNVBAgMBUhBTlRTMQwwCgYDVQQKDANJQk0xDzANBgNVBAsMBkhVUklCTTER
MA8GA1UEAwwISFVSSUJNR0IxJTAjBgkqhkiG9w0BCQEWFnNoYXNoaWthbnRoQGlu
LmlibS5jb20wHhcNMjMwMTI4MDM1NTAxWhcNMzMwNTA1MDM1NTAxWjBHMQswCQYD
VQQGEwJJTjELMAkGA1UECAwCS0ExDDAKBgNVBAcMA0JMUjEMMAoGA1UECgwDSUJN
MQ8wDQYDVQQDDAZJQk1JU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCvn7rGrAzGr1BI688hirHC+P1xcI2dUAc1EZx9bQ1mzSAP+9F5hBzT0Ty6ay0Q
zs8qKOs9YpHy1qCrETlrFJxWmd8IYVhT2QoKPxF6jhfYMf6anabtYSRZe1c3v/zi
DyuLuS2XuDeHnfuJl732YTtteYcG4nAx2Y2GcKLnEfNyrB49+ZGbjnNTqIBsR1tD
U96C1h1z4PGtZDxDGbdjGlaB1AJXH9r2tocaS2WyBKo8w9ogTI5d63NYdVvsPKm8
AKwnVLu1kE/xk8/5fraW3tyX4JmCFk4Tt/rf+Oy0dbFfoC9m6JmHPeEopqE9f/qy
m0WpqM3PHuz2Kke7RQ3GNYFDAgMBAAGjggGzMIIBrzAJBgNVHRMEAjAAMBEGCWCG
SAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQg
U2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBTaihsw+XFiyTZXn27Y7qpTFQSD
2DCBuQYDVR0jBIGxMIGugBQwi5E+ifSXCMzGLm0vAlhFxqBM3aGBkaSBjjCBizEL
MAkGA1UEBhMCR0IxDjAMBgNVBAgMBUhBTlRTMRMwEQYDVQQHDApXaW5jaGVzdGVy
MQwwCgYDVQQKDANJQk0xDzANBgNVBAsMBkhVUklCTTERMA8GA1UEAwwISFVSSUJN
R0IxJTAjBgkqhkiG9w0BCQEWFnNoYXNoaWthbnRoQGluLmlibS5jb22CAhAAMA4G
A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBaBgNVHREEUzBRgh1b
RnVsbHkgUXVhbGlmaWVkIERvbWFpbiBOYW1lXYIXW0FueSB2YXJpYXRpb24gb2Yg
RlFETl2CF1tBbnkgdmFyaWF0aW9uIG9mIEZRRE5dMA0GCSqGSIb3DQEBDQUAA4IC
AQCD3iROwkBiSfJ1jCzUdblYawclZE3kX7remHR77sAuGYHEsHhU4PmXUs+A70JJ
jF8gzc1cqMqy4Kwd1BGbNLp9cdtre4TigQ9UqbqxCENyoq0aTIhHmJ5GP3RKMwC1
jaNmH/MUlFhOKZsTLKymkBGCA9GLhD+quU4AIQHMLGoxMIbRZwZzyuGpa7/Gl2Om
f6taMfBsnmFFC+O+saGvu8TG+Q28bGA7wJQM5WMxyVbVY2Lkbb4u2/gDEY1/6T7g
ZkGuCxVlyQ2+dy5teKe7I2AGkgTbwl39i4YMGdj9ZC7ydRIANnNgCuygUTZ3c+w3
PvA33cX7ICWrmrk0y8Ulox7uj1jNi/npdwPkfjyuh9fJpdV4J/BcsQyZ/j4F5Z4B
5MrQeJ7wEELYDv1OOTntyQoqH1HH3TrZ3PFS0whA6gTT76ci2ra85vLVW4SJrbKj
VvDr5VcHE+IsJBedscbP2fO6imkAB74xdkBx9uy7x4aXJi399DHvw6b7mMsbR0om
6CpI0akjprfhdyv4Ri3vvWpWrzHMUMjzLuj6HYopBlFLErMe6WTY1BAh4ljUFKZ0
141/BCkGzNpH/5g1O1QwdQXzEIgUjG16Dm7gM2WKAeJFBttogX2ygTRnVRCZs/fY
JE3CwtxKczC0XteonH/ylGTQQR/0J8Y/ozLAWQxDyzi2Og==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCvn7rGrAzGr1BI
688hirHC+P1xcI2dUAc1EZx9bQ1mzSAP+9F5hBzT0Ty6ay0Qzs8qKOs9YpHy1qCr
ETlrFJxWmd8IYVhT2QoKPxF6jhfYMf6anabtYSRZe1c3v/ziDyuLuS2XuDeHnfuJ
l732YTtteYcG4nAx2Y2GcKLnEfNyrB49+ZGbjnNTqIBsR1tDU96C1h1z4PGtZDxD
GbdjGlaB1AJXH9r2tocaS2WyBKo8w9ogTI5d63NYdVvsPKm8AKwnVLu1kE/xk8/5
fraW3tyX4JmCFk4Tt/rf+Oy0dbFfoC9m6JmHPeEopqE9f/qym0WpqM3PHuz2Kke7
RQ3GNYFDAgMBAAECggEAPeL1eEjsf58LlYazCMjM9z2yYaUd4g9vWr4H/RLOpCko
YTmFiWKKngGfermFueSGj/63VnxDneUP3PhG2Xr71HCIbXWQIIvcw9uRlzQ3JtIH
PAjN59xRaM7T3ytiO27JE4V/kXUy7DE5kDTOleGRhXRLpptomchl3LgYT4C93uw+
Pul/KS4PZrGvTD+QnKNd4aOmlEaVLDRcwMqvg96bofE4Qk8LniQB1xEuYUpJFtPm
dBaGmtkTg8M6ghqOYMMqx8qNjqcv/HxIUFbV6F6fmhDOAAvt0gRzhHsmJieYiWFv
Igj/pmJbo/sfcgiiV4g3lEfqP4i9WpMmpVtEbOrvUQKBgQDio+YfKOwO4Pv0soi6
4qPpAZyYvDeQNFYfm0GP/FBuFHUR7dMA88snPZUY8mSgtfG/zoQdcyI3G7HEsugD
redwGoVvp0s9435xW7KCB3tMP3PhmeMjXihQw5cXyJx+LrHjorme5zQ4OkcB23lF
cjN/Yv0ZxRp2wWpOp3F08CvntQKBgQDGX/h3DTx4IHRjfL6jnL8vKJIsxNFhy/Rz
SMMnwAXLmYv29O+rupqsx/MNbM/VA99HqGQt8p2fVEGafYlolaFjICZM6DH5j30B
t1M4LsPZf+fI5vWI9KHwHT1JxCqfqM5GwwHMrEw8pdicr/+FS6O16Kymln/aAILb
sjvpFyLwFwKBgQCO1m06RjhASFuDJOI3po9XUsS3HiiGofWFhfwUGxk1x37hBdpu
RzhKSu2lA1+YShNKp4VsahuuT64CIh9H8lpitNRUQkORhccy+m/Os5hpvbPzA2G7
8KPIAv0+6Bh5DkTfCreiBmVK6q/F4+TSd98s8d5CV48OOWgemjlPUe7Z4QKBgQCu
MiYP/NqFrhImLquFJqantZuunmIy25NcDJ/6bt9n6vyCLpGrniAm6yneNxfFuTG/
TfoycuLAv48gJ26bHRHr5pZbYGZJ/BtMf3wfUMmAW5Xg0Bb6Xb86B6MC/LRlISmJ
78HLxdzoQMYWyWG63jHzEk9RtcStXVeLrlZ3l26BnwKBgHxMtBHvcaXWzRdm1PZ0
2DVFOP5lm/5t5WC8re8L9oeVLt0+yMBEKXUwX66Z1s5iO24CWsHFN8zDjQhVKfZM
/YOxbfjQWYO1LsgJweAEeEauYI+ncMnQEZf1Ei1P8g2X1GTS+n0r4YANawWczp71
tZURwKJSJwKpGMChxucQDJc9
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,3 @@
This directory contains private key and a certificate that signed by intermediate CA.
The directory also contains the intermediate CA certificate and it's root certificate.
The certificate and it's CA certificate have different Subject DNs.

View File

@@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIxuHuzG+WcZACAggA
MBQGCCqGSIb3DQMHBAgMKyhajZd/ewSCBMiCL57/BUvVwtxmhaIqQBSjHLnx+AvG
f+frFkwM52KuAg0Q+vF/1iQXMbZRrHpxNz/1t3cIdwzlc9S3FB+L42q0CEH0c1FW
6gB6csmb1AyhGYffwkeT8bPkELJhpO2taIFTynwDhHaeKeDce3EwQ5xQd4ydq1Ku
t4oJZun51J5qvNs91BiHHVB3/q1Lnh4VK4TTDgXTGfu8qcuOexHQcOgko4oemorv
E1Woy6Lf99bePxedSuMIxPAXysSCBqcrZDbY9K3yaxV6Gr7S9FBVvOx9r8PTaFEY
sXxdtB22qM1PqZIIjK6nzwXb5iu8wcaZFatD6y7RQaS0kz5EcS5kExrEocFV7D1T
dtTf6tt31PbtKfEauRjz3fBXMw+r3Pu/hWRXd3og9hfzFQz49v9RdvgkHy57uCY+
F/fN3BKyTcTqJWKpBDMx/xtD1kXWHf81SFmckuShbgKjDvZraR4RmzO/9upIDCFF
rJ85takmPvZyAdfvZp6RqVja+cphI4nmxVvmOmUiFMmUJ0lv9MhqpxdVFfleWz0w
9XxeL4l+cd/Kbl2ihHwF4oOzWlamyRZjoWiq5s/ika9I1iQ40rGTThqnphonlhUz
HX4NvA+fbugwqyOjqEkg5AqyP5ucUN3Hl0qd7wqAJprDkB938unKo/1sr82PfdO/
5UvzsKz2ieVavEzi/NxYyR+Xjm3YHG1akcftvElcpYepvemt/PtXJH8fX29b1X6C
TYxV03MeA1sJXeM9iqIf/wGQJ657U5ciXUyUtU8s0dDY+jqpZVjxekgCove9FNXz
Mja15yiAy/F8xKX20ZRisg+Ly60UQYbX6Wu6Uy6NMjWkxZOYebCVYLMag6UjS0CS
8n3/DNvuVooGWbgBFs0tyabtlz/Fz5jGktkMBQeEK4PZKZdMt9aXnDfPFGJWrsme
bUzEZLZSWD2Zwr/ujzfBgVeg56AyHJzHuOOLaofZ90ecv69Udl7sYZBelFXxgN8R
JVXyV0kNZYj9LaqRTi54H8YToAIV7GXIcasH3jP54dOba3px2NXbaiMf7Oe8apyW
E7/vKQNoIbWaglRHXVPGoATTUzYNdBO4jca1rTOXjmzsiZl1JGPwQsS03PuTfa8C
F7Uqxj8P9m71G1KuLYA1es55aNXzXSx6uqrRYeu0iug/jE+voGfjbRW3BUY/qxtl
OjR8pCDPLN6/rt//ejvBdA4gPDgjRNH4fO9DULQDqIVHmYlysZqhbPbhzmiBXZVP
zw1/z9amWR00OeN7xUvm9n+65dosoIn2v1dOz8JBh6Uooj63D2cOghBwEXoPg53B
3vLgqy3NKyNZQ/gGfBjXTTeoWzAy8U8hKecNKcsTBquBeBUfS55WwkbD7Mz0Deho
EcMZPZUwAPyJ2kHL74etpoBXuH7Jzo8SVedhE+C5J6F+oUP/JcoXdehdGLI89CHU
cUARt91OiF3WQo51xT21GlGL8RMHVpjTnYZinnQ/fE1y7JfWtYshBya+YLlAk5vb
9jt0tZ9I/KhJ579ZwWBH8V179kBr5Vn+uWlEBBaJu0abdbRSDjt6fAaxi3Q8XK+c
isuVuzN/8JAeRgRpm7hRfIoG6XOsrY72ktz0JiHflZ+90xaPRvpCA9/mFC5qp1zh
yBs=
-----END ENCRYPTED PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEaTCCAlECAQEwDQYJKoZIhvcNAQEFBQAwgZ8xCzAJBgNVBAYTAlVTMREwDwYD
VQQIDAhOZXcgWW9yazEPMA0GA1UEBwwGQXJtb25rMTQwMgYDVQQKDCtJbnRlcm5h
dGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uMTYwNAYDVQQDDC1N
USBMaWdodCBFeHBpcmVkIENBIChmb3IgZXhwaXJlZCBzaWduZWQgY2VydCkwHhcN
MTUwMzI4MTMwNDI2WhcNMTUwMzI5MTMwNDI2WjBVMQswCQYDVQQGEwJHQjESMBAG
A1UECAwJSGFtcHNoaXJlMRAwDgYDVQQHDAdIdXJzbGV5MQwwCgYDVQQKDANJQk0x
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMeNfSaC0XZoi9CHXLUHz7BA8frIlz+gnl1sjaGimsofiMjd8a0c4pOhlusR
kvB4qAQDxmDYhh9QTuqiJZvQxzTI3sNt4W3kcm/bEVawg8HvsWBY40fKkWJYlypV
K4Oizcri7CLaeUwgpJlrSlYiJSzjaaytTDeC1F+RSTrdDg0CxI+pfhxIkc9+HPMC
oSv1ynxktcJPnCLGRIIHYCE4jm1ZsYxAkSV1crja5OQdd3czEMz6wfHdYzTJUEa1
pmnTOa9lhuxlYb8ykt7G2CK66tXaoN0SsAsy6sT2SblI16RDkyOL5XJk56ThhHrn
XjjWr3Zo4/tE/pgn5fd+91oi2+ECAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAZNZn
OJVQ54NLCzCyTiTauG2jJU+3aYEG4hRhpLM6N11vrukIFTeVfbrr1uKp7sLHYB0E
6xLgTxhKF2lDHzCPjA3bOO0tDsxwkOZNP//jmMi+9VKd6Voh/UENOVnBHaXLb5G2
9OXi70W/K8eQU7Qi+tu+snWNLYHb5nsYKnPed3+h/zLV3iNB7cz2DCNCas2cKekx
6hJo+tWoC+jXcpM97pnqY6saYNmKmugIdZ1W77jueoEIIkSMAZvd8sgXzE6Ad8mD
bTMimX9ri0APgxZewaF51YzR2yKqgkpvLVBef0nCbjCDK5zgJVSQHtVJswE4mIcL
J3PbSxtmt3BcIr9jmYZZjmoXSjK0+YQkDYT9/uiE5h+6KXrk4AOTkcO9kuxQcBAD
QYJB8Hr7h9OcWmpOOJDjOz4BspBwQ7Vs2swHBQgWu9mS9I187JFSFm46dp9CnqSV
K5i5amsrJUcRtqlBs4JzqsLivUaet+BtQwlWDfl52TgWpWeIs2EiPFERZxiEggVr
pIhjZ9F2d0pL1Oj5jCWMRGWrz1px5W4r92uzfYvTrT/eyGNGGNdDeAgidJ4SftXu
XMcqgVjAy0kKvQEK9bCqfoOxTllFqLcneaPI6O0hLREph6sti6eDvJeMsUGoYm/7
MxfCaqBU1HStl0HHPaaqHnPP+FW+/xuXhHij1hY=
-----END CERTIFICATE-----

Binary file not shown.

View File

@@ -0,0 +1,35 @@
-----BEGIN CERTIFICATE-----
MIIGEzCCA/ugAwIBAgIJAI+sAC+/ups4MA0GCSqGSIb3DQEBBQUAMIGfMQswCQYD
VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxDzANBgNVBAcMBkFybW9uazE0MDIG
A1UECgwrSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlv
bjE2MDQGA1UEAwwtTVEgTGlnaHQgRXhwaXJlZCBDQSAoZm9yIGV4cGlyZWQgc2ln
bmVkIGNlcnQpMB4XDTE1MDQwMTExNTkxNloXDTQyMDgxNjExNTkxNlowgZ8xCzAJ
BgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEPMA0GA1UEBwwGQXJtb25rMTQw
MgYDVQQKDCtJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0
aW9uMTYwNAYDVQQDDC1NUSBMaWdodCBFeHBpcmVkIENBIChmb3IgZXhwaXJlZCBz
aWduZWQgY2VydCkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLGn4P
97BZteNO/5zIlGH4F067TPlOjFiLI1TFI/bKp3bx1fHpsQdMX5C9y1s6BqoOzMJV
VHDJH4NlxvnMUGNzYvluynjujejhyDryDrb4uY3JMcewvnHmrWArzbfZw4eBzANr
feBkro4xr6m5HWMxM4GJZeFaEGqbXNE5vAYhZ270qUKqrkSHv4g/LqapITaBPJDC
3tAtV0UD4/HmwB2ogZlXy4DkbBsgcc2rS4xPxx3Qki78DeA9oT6aeLP7KZnoEgo9
Xqb/UfRuZ5MYR17u8yTuJz/JdAs6Saf80t5PLDO/SRKj7Uu1lt+HbkpEghdEdB/V
pPdmlIfo7uNe7rFG/OWif2qwVm2t9o02oIUqlAHggS4WYeOmcB8L9EtmlfZHaoDA
H0a0xlbZ+XlE/EMpphgrzSE5g9h9Vw7vvH5Ygzks8lSXKd5VS8C9y8tWqaMCynAy
5MTIZdXMvouG8vy5Ip+iWck4QSo6eJBryLNt/vzljxo6XntveXRZVvywyjh3NuVu
nVLPe0CFkmRHXK5/zA6H8rZeGb3eK8Y4VcLKj7x4Lnluo47BeGnKH7UcKBA2AREC
VGFVsHcr0HwKgCCSsyv4qRefY/mJWO59BL38shHuzydLxlKHf/uPGdsZ3DU0rb6i
QXMCHC6lzAjJHVCDJ2witiPSjmW2LRZzRqdTqwIDAQABo1AwTjAdBgNVHQ4EFgQU
dv3XdSdsOkZJDWgusfuZqBx/jpMwHwYDVR0jBBgwFoAUdv3XdSdsOkZJDWgusfuZ
qBx/jpMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAR9o32FR4AjTZ
LV5nH5rsQ9OVon1TCv9yemAI4coh08RHWVf7cDyIp8XKy3gTM/lq70wzsXUHwaAS
4xSOjc/fBLP0UTEwCrdyy1guRs9ZjKIhqth1AkB92sF9HV4P811vUNppVfA/BDmb
Ttl6i1Joyl6nhnDxn1HzjcSBB4ZVt/1MRwIaEfRXrqAklYbMOtw8D6Onth6IQ7dS
27ulUPD+AA8H5Ilm2XhPI6ttnR+822+mgB1K9WAjmuIbDJwQJl32UmTUiXPwdlWm
KqyKZGST8wV6Jylha84ETL99IlJsxoAMGmNshMe4t773n0LousAvnbVt9uZcBNUH
d/53EWP7kw1PPhY6jo0gLVK/ZQt8MHBJuT3f5IM9dmkLJmyM9t8tEmvjNEoC2xSW
JHxoWfbMOxxFx+S5CwwcvySpKltio7s5bf/dYexE+Dv/+zMDeMb8GXv811TCqsD2
lm4kTsHjwd+zSGCuvH+R4vWbkSrd65CATmFsVpVPLsIVXDa3DrgFQBmUI/q9UFaG
K25HztaHk8GJkBZdBA7xXxzSJxW37yqPGKqQ/ZoqSz6XFnsgy5AsW0fDM+cPUl7l
tftOlLeSqkaBq9O++76yY2asb0AyqjNs0tajluzxGFZ38DOqA1xkltV/c+KYnEv3
q+K4agMHIKMr7lGJfSBevz3mG+NJ7AU=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID2zCCAsOgAwIBAgIUdbPSj6WWhFu2amL9voKbyCMKiB4wDQYJKoZIhvcNAQEL
BQAwfTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQwwCgYDVQQHDANCTFIxDDAK
BgNVBAoMA0lCTTEMMAoGA1UECwwDSVNMMRAwDgYDVQQDDAdNUU1GVFFNMSUwIwYJ
KoZIhvcNAQkBFhZzaGFzaGlrYW50aEBpbi5pYm0uY29tMB4XDTIzMDEyNTA1MjEz
NloXDTI4MDEyNDA1MjEzNlowfTELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQww
CgYDVQQHDANCTFIxDDAKBgNVBAoMA0lCTTEMMAoGA1UECwwDSVNMMRAwDgYDVQQD
DAdNUU1GVFFNMSUwIwYJKoZIhvcNAQkBFhZzaGFzaGlrYW50aEBpbi5pYm0uY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwl9MlmCNG7kzk7qKGuBX
jTONcn2OcifKfwgJlvzTqHcf8X/BIiyOOiwoeznke///LLtt9ygF0iyBMQYM/CG/
rzOR6tbzI4y4Bmx6VqY02CkXi/p66ywQ7B5N2Fdp9Bop3SnthTcT4NoXBSEUhI1O
ob8lDFv1KMRkCULD2sA0FUYCrHtw0M/vEOqsA9VVjyzOXsIlbbR1BSXtlWNneGeL
OAdmQWO3QYCku/YrCyJlscvIisjp4s7guGnQh0Ws8h50R5sqag8RvdHUwExVLUfZ
L1Od0+hCiO5mNfKekT0cs9owplcwgNHw88b8q4/aHDBtQRgsukkMxTpo00ftPJxI
nwIDAQABo1MwUTAdBgNVHQ4EFgQUOyw89AeB0jXb5WCZv/5oDY8oWxkwHwYDVR0j
BBgwFoAUOyw89AeB0jXb5WCZv/5oDY8oWxkwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAQEAtbybQQ9GpY5gH7xz4EWOUZ7XMmBYtuGXVrqUd+76hvCA
H/SB0nl2bGp7tAKBttmXhfKVac6wFCbXvYe49B+Q9+iL7H9st9VZUPKLQ6K3Uet6
L1ggMm2BhecpuYbwkG7ZidVFo/SuUCbCTnXBgHjvq4IkVCaJe7aKZmejSCh7gsIR
BQkZvz/22Vx/WPTEYp0x/riIvSViBjLCuD25Y+nCtS8c2xGVBjs9Q4GWCOAvEfAr
Tqs42brH1Vs92xS143p2h/wv52tmhfJI6X9QVQBBUoIjPR/VDFqZU5EYhAvuQPBi
UADz9hNYGQ9wBzZGvzbrorpoT+7aW9nGtmUsvvupBA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,3 @@
This directory contains private key and a certificate that signed by CA.
The directory also contains the CA certificate. The certificate and it's
CA certificate have same Subject DNs.

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDgTCCAmkCFClOtyvBoQXVAGMcX0ObUawZJuX/MA0GCSqGSIb3DQEBCwUAMH0x
CzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEMMAoGA1UEBwwDQkxSMQwwCgYDVQQK
DANJQk0xDDAKBgNVBAsMA0lTTDEQMA4GA1UEAwwHTVFNRlRRTTElMCMGCSqGSIb3
DQEJARYWc2hhc2hpa2FudGhAaW4uaWJtLmNvbTAeFw0yMzAxMjUwNTM4MzBaFw0y
NTA0MjkwNTM4MzBaMH0xCzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEMMAoGA1UE
BwwDQkxSMQwwCgYDVQQKDANJQk0xDDAKBgNVBAsMA0lTTDEQMA4GA1UEAwwHTVFN
RlRRTTElMCMGCSqGSIb3DQEJARYWc2hhc2hpa2FudGhAaW4uaWJtLmNvbTCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJNAGirCyLzsHpV2cyso8pc2BOP
4j6lu2ZTsdSE+WVZsqX3YWmV8TCYpJQRD4jmlrYIEdYAGmKPZvbvWjhzZWOJIxfI
MGRwQ4dl8bSDZpcc7OAcHgLaW1OnMy2/1NgVyyXOKTaG4PmzZCzSKnhDF8/+FhUm
rIYi5EU6bn1MuY34HOswAau0G7YVeroBUPs+LUjUpQx4vp5Baz9sWBzWcvsZsoSo
LTMWEqCocqYOhj1ALrwN61NzdRwVtoS41dcjHAiFKEVTKIbqE0ib57Of1sohO9dr
JgjegBNi18lsVUqDnYvydbe1hTEZfoXyN3QHm6QZLYtKB0RqR4HlcufnFWkCAwEA
ATANBgkqhkiG9w0BAQsFAAOCAQEAtgG/2/7q2xPJG+Z0xJIyS9O7h6Igus2LhrAw
tkudX5FZtJclBmDx3KvtJMPzpoGFRF48nXaqNcDSI3+8MiMk+JfpfGtmFbYuaa+l
seqk/3byv/y1ofd8JMk0olY219tI1/BK4AU+fPP1obYV0tFcwIDOqQaS6f/N4RP1
MO0PE+j9dDO6GQjIEUHZVVis70WvGaTc6DfGPVehZzDbNW9nTdkuacZf+XtlLVXq
LzJpGeMxvX7SRRkdyegNigiWHJzOchVcoNnO+rUm9JDjY8pukDC08uZEQVqNpOXD
tO1t4rpBT9HWxPRCLt8IwOhoYAGb5DWwUeIaiY637CSPTJVjCQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsk0AaKsLIvOwelXZzKyjylzYE4/iPqW7ZlOx1IT5ZVmypfdh
aZXxMJiklBEPiOaWtggR1gAaYo9m9u9aOHNlY4kjF8gwZHBDh2XxtINmlxzs4Bwe
AtpbU6czLb/U2BXLJc4pNobg+bNkLNIqeEMXz/4WFSashiLkRTpufUy5jfgc6zAB
q7QbthV6ugFQ+z4tSNSlDHi+nkFrP2xYHNZy+xmyhKgtMxYSoKhypg6GPUAuvA3r
U3N1HBW2hLjV1yMcCIUoRVMohuoTSJvns5/WyiE712smCN6AE2LXyWxVSoOdi/J1
t7WFMRl+hfI3dAebpBkti0oHRGpHgeVy5+cVaQIDAQABAoIBAGlAmVAwQBe24OOm
kDaJZvrLSeZqVnUC4pgqKdy5Tnusso/Uc5WfpMw6H1UkqRX4gNkd9GFumCS8YFy+
uHSAckaKqsOcMizoNITWAhO8SbBEq/QzxOeMPMMp/UUxa5TPcKd1htCgWGgupKDs
w5NQj9sBM8nylX9tU3EmaBjhVNvfsZSeA76s0z+JDDwJLUlH33dwvgidw+baRxYM
U6Tr3Z7YCFZ7+iZbOTHZjkKVtS2EqHtU5OW/pQltbBSovhYQMXjBsCHpTK78+jbV
jKjtDUYWplcAYoN/O8ljYHU6lKQlTfo8KQInLtek/Ycen7uOCT6kFAreWFg08g4x
5IH/pXECgYEA4ivLQjKR1BHiO+6rDZIfQxvbTa2RgT3Yr9W923OpGY1LiuapGFfJ
97PjVKQf6HromQuzveYZR9YFKR4u8YTUn5PCB16v9MEc7nxnwIfE1kH5aEMvMSq9
MvxvYObs3dJu4dx+AF8q8REuviBkQ2br34ukbl8ssaB/7zHPXyNJDt0CgYEAydD3
BNtPRwKorQKOC1VXQxAFtlu/iiia4LEocAODDUX8N0iGxRBpQcfY/OuqV2j8Alfx
n7+Zv/NGEah+WLaApc6wZVvOOuJevam/3ZJReawUtpCcG5em388WSQDuIj3AKhVV
IzRRRFlGrTuHENdsqG5rBzbYWvans4lpVkB6Kf0CgYA0YUQfvqp7XPDyRGIlMHRB
DJCLuuj576LhhjUEQBMnscuPDcCXvK0vyt+ZWLFzHBQGbelgz4uHUY+8aBsjIEpF
8uh64HkLzDWxHerBcjAqFvl2Jiklz+olhsUcwh6VeQjpEjG0UFYXoo0ax1GxMoLq
MOMSFMS7FprKgNSwCfH/mQKBgBLA8lNnNcS5gIcjN6Ph+EvpDz7U48Wo5EuA6usN
yH3RRRC2Ep/5WG6ebZGDLL8WqGRnW7KmkVj++EHn0GXZ/7ZosIeasl1Sb89cGNI0
KJIP5ZTZd0gxHXaqvb1m8roH1vWSKektkWeyjBjI8VIlUpmMOTHgbNZ3GTpbyIgV
UcTZAoGAJp5AX+5u6OhLcCI56dpKYGiIS+8fXd2+oz7uZYf2yNTZONulehh2earM
4soiUF5ArPgc3KbZhorvIXjOUSb5wc7I2nQKxXQt9j2fyZMD8qsyI1kBqLQ53Z0r
agAkX1xMvhvHMQFKmPMXt3pUfXEx/oa32f3ciyPAhyyQNpv5gx4=
-----END RSA PRIVATE KEY-----

View File

@@ -56,14 +56,16 @@ FILE_NAME=
BUILD_ID=
REGISTRY_HOSTNAME=
FILE_LOCATION=
PROPERTY_NAME=
CHECK=false
UPLOAD=false
GET=false
GET_PROPERTY=false
DELETE=false
DELETE_NAMESPACE=false
num_commands_selected=0
while getopts "f:u:p:c:l:-:" flag
while getopts "f:u:p:c:l:n:-:" flag
do
case "${flag}" in
f) FILE_NAME=${OPTARG};;
@@ -71,6 +73,7 @@ do
p) CREDENTIAL=${OPTARG};;
c) CACHE_PATH=${OPTARG};;
l) FILE_LOCATION=${OPTARG};;
n) PROPERTY_NAME=${OPTARG};;
-)
case "${OPTARG}" in
check)
@@ -85,6 +88,10 @@ do
GET=true
num_commands_selected=$((num_commands_selected+1))
;;
get-property)
GET_PROPERTY=true
num_commands_selected=$((num_commands_selected+1))
;;
delete)
DELETE=true
num_commands_selected=$((num_commands_selected+1))
@@ -167,6 +174,43 @@ if [ "$GET" == "true" ]; then
fi
fi
if [ "$GET_PROPERTY" == "true" ]; then
if [[ -z $PROPERTY_NAME ]]; then
printf "${REDCROSS} Property name to retrieve from '${FILE_NAME}' was not supplied please do so\n"
printf $SPACER
printf "${ERROR}$usage${END}\n"
exit 1
fi
if [[ -z $FILE_LOCATION ]]; then
printf "${REDCROSS} File location to store property value in was not supplied please do so\n"
printf $SPACER
printf "${ERROR}$usage${END}\n"
exit 1
fi
printf "${GREENRIGHTARROW} Attempting to retrieve ${PROPERTY_NAME} of ${FILE_NAME} from repository ${REMOTE_PATH} and store it in ${FILE_LOCATION}\n"
query_url="${FILE_NAME}"
query_url="${query_url/\/artifactory\//\/artifactory\/api\/storage\//}?properties=${PROPERTY_NAME}"
request_result="$(curl -s -u ${USER}:${CREDENTIAL} "${query_url}")"
if [ $? != 0 ]; then
printf "Unable to retrieve properties from ${query_url}"
exit 1
else
printf "${GREENTICK} Properties retrieved from ${query_url}"
fi
jq -r '.properties.snapshot|first' <<<"$request_result" > ${FILE_LOCATION}
if [ $? != 0 ]; then
printf "Unable to write snapshot property to ${FILE_LOCATION}"
exit 1
else
printf "${GREENTICK} Property written to ${FILE_LOCATION}"
fi
fi
if [ "$DELETE" == "true" ]; then
printf "${GREENRIGHTARROW} Checking to see if file ${FILE_NAME} exists in repository ${REMOTE_PATH} before delete\n"
FILE_FOUND=`curl -u ${USER}:${CREDENTIAL} -X GET "${REMOTE_PATH}/${FILE_NAME}" -o /dev/null -w "%{http_code}" -s`

View File

@@ -16,6 +16,30 @@
set -e
archive_level_cache_dir="$(mktemp -d)"
get_archive_level() {
local level_path
local archive_variable
archive_variable="$1"
MQ_ARCHIVE_LEVEL=""
level_path="${archive_level_cache_dir}/${archive_variable}.level"
if [[ ! -f "$level_path" ]]; then
if [[ -z "${REPOSITORY_USER}" || -z "${REPOSITORY_CREDENTIAL}" ]]; then
echo 'Skipping level lookup as repository credentials not set'
return
fi
if [[ -z "${!archive_variable}" ]]; then
echo "Skipping level lookup as '\$${archive_variable}' is not set"
return
fi
./travis-build-scripts/artifact-util.sh -f "${!archive_variable}" -u "${REPOSITORY_USER}" -p "${REPOSITORY_CREDENTIAL}" -l "$level_path" -n snapshot --get-property
fi
read -r MQ_ARCHIVE_LEVEL < "$level_path"
export MQ_ARCHIVE_LEVEL
}
if [ "$TRAVIS_BRANCH" = "$MAIN_BRANCH" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
echo 'Retrieving global tagcache' && echo -en 'travis_fold:start:tag-cache-retrieve\\r'
./travis-build-scripts/artifact-util.sh -c ${CACHE_PATH} -u ${REPOSITORY_USER} -p ${REPOSITORY_CREDENTIAL} -f cache/${TAGCACHE_FILE} -l ./.tagcache --check
@@ -28,12 +52,14 @@ if [ -z "$BUILD_INTERNAL_LEVEL" ] ; then
make build-devjmstest
echo -en 'travis_fold:end:build-devjmstest\\r'
echo 'Building Developer image...' && echo -en 'travis_fold:start:build-devserver\\r'
get_archive_level MQ_ARCHIVE_REPOSITORY_DEV
make build-devserver
echo -en 'travis_fold:end:build-devserver\\r'
fi
if [ "$BUILD_ALL" = true ] || [ "$LTS" = true ] ; then
if [[ "$ARCH" = "amd64" || "$ARCH" = "s390x" ]] ; then
if [[ "$ARCH" = "amd64" || "$ARCH" = "s390x" || "$ARCH" = "ppc64le" ]] ; then
echo 'Building Production image...' && echo -en 'travis_fold:start:build-advancedserver\\r'
get_archive_level MQ_ARCHIVE_REPOSITORY
make build-advancedserver
echo -en 'travis_fold:end:build-advancedserver\\r'
fi
@@ -45,10 +71,12 @@ else
if [[ "$BUILD_INTERNAL_LEVEL" == *".DE"* ]]; then
echo 'Building Developer image...' && echo -en 'travis_fold:start:build-devserver\\r'
get_archive_level MQ_ARCHIVE_REPOSITORY_DEV
make build-devserver
echo -en 'travis_fold:end:build-devserver\\r'
else
echo 'Building Production image...' && echo -en 'travis_fold:start:build-advancedserver\\r'
get_archive_level MQ_ARCHIVE_REPOSITORY
make build-advancedserver
echo -en 'travis_fold:end:build-advancedserver\\r'
fi

Some files were not shown because too many files have changed in this diff Show More