Hi, I am attempting to configure environments for ...
# pact-broker
g
Hi, I am attempting to configure environments for our deployed Pact Broker using the Pact Broker CLI. I built a docker image of the Pact CLI and have a script that creates the environments if they don't exist. When I make the call using http, the command works. When we switched the Pact Broker to https, I get this error: "NoMethodError - undefined method `request_uri' for an instance of URI::Generic". This happens for both the pact broker list-environments and create-environment commands. I have passed the url as a hard-coded value and as a env variable. Not sure why Ruby isn't picking up the https.
m
mind sharing a bit more about how you run the command? Ideally, a call with
--verbose
? That will help us dive a bit deeper
g
PACT_BROKER_BASE_URL is set to: <https://some-website.domain.com>
PACT_BROKER_USERNAME is set to: pactbroker
PACT_BROKER_PASSWORD is set to: ***
Listing environments
Standard Output:
opening connection to <http://some-website.domain.com:443|some-website.domain.com:443>...
opened
starting SSL for <http://some-website.domain.com:443|some-website.domain.com:443>...
SSL established, protocol: TLSv1.2, cipher: ECDHE-ECDSA-CHACHA20-POLY1305
GET /? HTTP/1.1\r\nAccept: application/hal+json\r\nUser-Agent: Ruby\r\nAuthorization: [redacted]\r\n
HTTP/1.1 200 OK\r\n
Date: Thu, 10 Oct 2024 03:17:21 GMT\r\n
Content-Type: application/hal+json;charset=utf-8\r\n
Content-Length: 4720\r\n
Connection: keep-alive\r\n
Set-Cookie: ARRAffinity=b08b793703ed90c29d190499db3bc194822d9b232329810c8844678e66822c18;Path=/;HttpOnly;Secure;Domain=<http://some-website.domain.com|some-website.domain.com>\r\n
Vary: Accept\r\n
X-Pact-Broker-Version: 2.106.0\r\n
X-Content-Type-Options: nosniff\r\n
CF-Cache-Status: DYNAMIC\r\n
Set-Cookie: ARRAffinitySameSite=b08b793703ed90c29d190499db3bc194822d9b232329810c8844678e66822c18;Path=/;HttpOnly;SameSite=None;Secure;Domain=<http://some-website.domain.com|some-website.domain.com>\r\n
Set-Cookie: _cfuvid=vUFJsISOdU05_yMkz4LL4Jjbxoy.lGgOOC78dp2.TgY-1728530241177-0.0.1.1-604800000; path=/; domain=.<http://domain.com|domain.com>; HttpOnly; Secure; SameSite=None\r\n
Server: cloudflare\r\n
CF-RAY: 8d0374f488e907a8-IAD\r\n
\r\n
reading 4720 bytes...
{
"_links": {
"self": {
"href": "<http://some-website.domain.com|some-website.domain.com>",
"title": "Index",
"templated": false
},
"pb:publish-pact": {
"href": "<http://some-website.domain.com/pacts/provider/{provider}/consumer/{consumer}/version/{consumerApplicationVersion}|some-website.domain.com/pacts/provider/{provider}/consumer/{consumer}/version/{consumerApplicationVersion}>",
"title": "Publish a pact",
"templated": true
},
"pb:publish-contracts": {
"href": "<http://some-website.domain.com/contracts/publish|some-website.domain.com/contracts/publish>",
"title": "Publish contracts",
"templated": false
},
"pb:latest-pact-versions": {
"href": "<http://some-website.domain.com/pacts/latest|some-website.domain.com/pacts/latest>",
"title": "Latest pact versions",
"templated": false
},
"pb:tagged-pact-versions": {
"href": "<http://some-website.domain.com/pacts/provider/{provider}/consumer/{consumer}/tag/{tag}|some-website.domain.com/pacts/provider/{provider}/consumer/{consumer}/tag/{tag}>",
"title": "All versions of a pact for a given consumer, provider and consumer version tag",
"templated": false
},
"pb:pacticipants": {
"href": "<http://some-website.domain.com/pacticipants|some-website.domain.com/pacticipants>",
"title": "Pacticipants",
"templated": false
},
"pb:pacticipant": {
"href": "<http://some-website.domain.com/pacticipants/{pacticipant}|some-website.domain.com/pacticipants/{pacticipant}>",
"title": "Fetch pacticipant by name",
"templated": true
},
"pb:latest-provider-pacts": {
"href": "<http://some-website.domain.com/pacts/provider/{provider}/latest|some-website.domain.com/pacts/provider/{provider}/latest>",
"title": "Latest pacts by provider",
"templated": true
},
"pb:latest-provider-pacts-with-tag": {
"href": "<http://some-website.domain.com/pacts/provider/{provider}/latest/{tag}|some-website.domain.com/pacts/provider/{provider}/latest/{tag}>",
"title": "Latest pacts for provider with the specified tag",
"templated": true
},
"pb:provider-pacts-with-tag": {
"href": "<http://some-website.domain.com/pacts/provider/{provider}/tag/{tag}|some-website.domain.com/pacts/provider/{provider}/tag/{tag}>",
"title": "All pact versions for the provider with the specified consumer version tag",
"templated": true
},
"pb:provider-pacts": {
"href": "<http://some-website.domain.com/pacts/provider/{provider}|some-website.domain.com/pacts/provider/{provider}>",
"title": "All pact versions for the specified provider",
"templated": true
},
"pb:latest-version": {
"href": "<http://some-website.domain.com/pacticipants/{pacticipant}/latest-version|some-website.domain.com/pacticipants/{pacticipant}/latest-version>",
"title": "Latest pacticipant version",
"templated": true
},
"pb:latest-tagged-version": {
"href": "<http://some-website.domain.com/pacticipants/{pacticipant}/latest-version/{tag}|some-website.domain.com/pacticipants/{pacticipant}/latest-version/{tag}>",
"title": "Latest pacticipant version with the specified tag",
"templated": true
},
"pb:webhooks": {
"href": "<http://some-website.domain.com/webhooks|some-website.domain.com/webhooks>",
"title": "Webhooks",
"templated": false
},
"pb:webhook": {
"href": "<http://some-website.domain.com/webhooks/{uuid}|some-website.domain.com/webhooks/{uuid}>",
"title": "Webhook",
"templated": true
},
"pb:integrations": {
"href": "<http://some-website.domain.com/integrations|some-website.domain.com/integrations>",
"title": "Integrations",
"templated": false
},
"pb:pacticipant-version-tag": {
"href": "<http://some-website.domain.com/pacticipants/{pacticipant}/versions/{version}/tags/{tag}|some-website.domain.com/pacticipants/{pacticipant}/versions/{version}/tags/{tag}>",
"title": "Get, create or delete a tag for a pacticipant version",
"templated": true
},
"pb:pacticipant-branch-version": {
"href": "<http://some-website.domain.com/pacticipants/{pacticipant}/branches/{branch}/versions/{version}|some-website.domain.com/pacticipants/{pacticipant}/branches/{branch}/versions/{version}>",
"title": "Get or add/create a pacticipant version for a branch",
"templated": true
},
"pb:pacticipant-version": {
"href": "<http://some-website.domain.com/pacticipants/{pacticipant}/versions/{version}|some-website.domain.com/pacticipants/{pacticipant}/versions/{version}>",
"title": "Get, create or delete a pacticipant version",
"templated": true
},
"pb:metrics": {
"href": "<http://some-website.domain.com/metrics|some-website.domain.com/metrics>",
"title": "Get Pact Broker metrics"
},
"pb:can-i-deploy-pacticipant-version-to-tag": {
"href": "<http://some-website.domain.com/can-i-deploy?pacticipant={pacticipant}&version={version}&to={tag}|some-website.domain.com/can-i-deploy?pacticipant={pacticipant}&version={version}&to={tag}>",
"title": "Determine if an application version can be safely deployed to an environment identified by the given tag",
"templated": true
},
"pb:can-i-deploy-pacticipant-version-to-environment": {
"href": "<http://some-website.domain.com/can-i-deploy?pacticipant={pacticipant}&version={version}&environment={environment}|some-website.domain.com/can-i-deploy?pacticipant={pacticipant}&version={version}&environment={environment}>",
"title": "Determine if an application version can be safely deployed to an environment",
"templated": true
},
"pb:provider-pacts-for-verification": {
"href": "<http://some-website.domain.com/pacts/provider/{provider}/for-verification|some-website.domain.com/pacts/provider/{provider}/for-verification>",
"title": "Pact versions to be verified for the specified provider",
"templated": true
},
"beta:provider-pacts-for-verification": {
"name": "beta",
"href": "<http://some-website.domain.com/pacts/provider/{provider}/for-verification|some-website.domain.com/pacts/provider/{provider}/for-verification>",
"title": "DEPRECATED - please use pb:provider-pacts-for-verification",
"templated": true
},
"curies": [
{
"name": "pb",
"href": "<http://some-website.domain.com/doc/{rel}?context=index|some-website.domain.com/doc/{rel}?context=index>",
"templated": true
},
{
"name": "beta",
"href": "<http://some-website.domain.com/doc/{rel}?context=index|some-website.domain.com/doc/{rel}?context=index>",
"templated": true
}
],
"pb:environments": {
"title": "Environments",
"href": "<http://some-website.domain.com/environments|some-website.domain.com/environments>",
"templated": false
},
"pb:environment": {
"title": "Environment",
"href": "<http://some-website.domain.com/environments/{uuid}|some-website.domain.com/environments/{uuid}>",
"templated": true
}
}
}
read 4720 bytes
Conn keep-alive
`NoMethodError - undefined method
request_uri' for an instance of URI::Generic
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/hal/http_client.rb49in
create_request'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/hal/http_client.rb25in
get'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/hal/link.rb41in
get'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/hal/link.rb45in
get!'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/environments/list_environments.rb17in
environments_resource'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/environments/list_environments.rb24in
result_message'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/environments/list_environments.rb13in
do_call'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/base_command.rb25in
call'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/base_command.rb13in
call'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/cli/environment_commands.rb60in
execute_environment_command'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/cli/environment_commands.rb45in
list_environments'
`/usr/lib/ruby/gems/3.3.0/gems/thor-1.3.2/lib/thor/command.rb28in
run'
`/usr/lib/ruby/gems/3.3.0/gems/thor-1.3.2/lib/thor/invocation.rb127in
invoke_command'
`/usr/lib/ruby/gems/3.3.0/gems/thor-1.3.2/lib/thor.rb538in
dispatch'
`/usr/lib/ruby/gems/3.3.0/gems/thor-1.3.2/lib/thor/base.rb584in
start'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/lib/pact_broker/client/cli/custom_thor.rb34in
start'
`/usr/lib/ruby/gems/3.3.0/gems/pact_broker-client-1.76.1/bin/pact-broker10in
<top (required)>'
`/usr/bin/pact-broker25in
load'
`/usr/bin/pact-broker25in
<main>'
Standard Error:
Exit Status:
1
Yesterday, I rewrote the script in ruby, same result.
The script:
#!/usr/bin/env ruby
require 'open3'
def environment_exists?(name)
puts "PACT_BROKER_BASE_URL is set to: #{ENV['PACT_BROKER_BASE_URL']}"
puts "PACT_BROKER_USERNAME is set to: #{ENV['PACT_BROKER_USERNAME']}"
puts "PACT_BROKER_PASSWORD is set to: #{ENV['PACT_BROKER_PASSWORD']}"
stdout, stderr, status = Open3.capture3("pact-broker list-environments --verbose")
stdout.include?(name)
end
def create_environment_if_not_exists(name, display_name, options)
if environment_exists?(name)
puts "Environment #{name} already exists."
else
puts "Creating environment #{name}, ruby implementation"
system("pact-broker create-environment --verbose --name #{name} --display-name \"#{display_name}\" #{options}")
end
end
# Create Environments if they do not exist
create_environment_if_not_exists("dev1", "dev1", "--no-production")
create_environment_if_not_exists("dev2", "dev2", "--no-production")
create_environment_if_not_exists("stg-us", "stg-us", "--no-production")
create_environment_if_not_exists("stg-de", "stg-de", "--no-production")
create_environment_if_not_exists("prod-us", "prod-us", "")
create_environment_if_not_exists("prod-ca", "prod-ca", "")
create_environment_if_not_exists("prod-de", "prod-de", "")
create_environment_if_not_exists("prod-uk", "prod-uk", "")
I have figured it out. We set our PACT_BROKER_BASE_URL on the pact broker deployment to "some-website.domain.com" instead of "https://some-website.domain.com".
m
Yes, you can see that this is the problem because the first request works, it fetches the HAL resource but all of the links were missing the protocol