Hello again, I have another query about plugins th...
# pact-plugins
a
Hello again, I have another query about plugins that provide a transport. With the WebSocket plugin that we are creating we need to be able to support
ws
and
wss
connections, mostly to providers at the moment but it may be that we need it for consumers also. Currently our plugin just adds one "transport" to the catalogue:
websockets
. But this means that when verifying contracts there is no way to tell the pact-standalone-verifier to use a
wss
scheme when connecting to the provider server. We noticed that the
ProviderInfo
struct has a
scheme
field which looks like it would be perfect for our use case but the pact-standalone-verifier does not expose this option. Looking at the source code here [1] it looks like it used to, but this is not listed in the docs a the top. We considered having the plugin create two transports
ws
and
wss
but this then meant that the consumer would have to determine which transport to choose so that it is written into the contract. We weren't sure if this was correct as it doesn't really matter for the contract contents if the connection is secure or not. Also we wanted to avoid consumer users from having to create self-signed certs to create contracts unless they really wanted to test with the mock server over wss. Guidance as to the intended approach would be most appreciated 🙂 Side, but related, note: in pact-consumer it looks like
tls
is hard-coded to false [2]. Why is that? Has this not been implemented yet or are secure connections supposed to be solved a different way? [1] https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_verifier_cli/src/main.rs#L673 [2] https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_consumer/src/mock_server/plugin_mock_server.rs#L64
m
Interesting. I didn’t quite get why you needed
wss
though, is that because your providers only run on TLS? I usually don’t consider TLS a helpful thing in contract testing (i.e. we don’t learn anything new usually), but I know a lot of tooling is making it harder / the default to use TLS so it’s something to consider. @uglyog might be able to answer tomorrow (he’s just returned from PTO, so bare with him as he wades through the inevitable pile of emails/slack messages 😆 )
u
TLS doesn't provide any benefit, but adds a whole bunch of complexity (needing to then deal with keystores/truststores, self-signed certs, custom root CAs, etc). It is not as easy as just saying tls=true. We have support for it for where people have no other option, but it is not currently well supported (at the moment it only supports the use of self-signed certs).
The way the use transports are designed, the plugin can support as many as required, and the consumer test then specifies the transport that is required, and then there is a new attribute added to the V4 interaction to store this.
The
ProviderInfo
struct doesn't have a scheme field? It does have a list of transports.
Copy code
/// Information about the Provider to verify
#[derive(Debug, Clone)]
pub struct ProviderInfo {
    /// Provider Name
    pub name: String,
    /// Provider protocol, defaults to HTTP
    #[deprecated(note = "Use transports instead")]
    pub protocol: String,
    /// Hostname of the provider
    pub host: String,
    /// Port the provider is running on, defaults to 8080
    #[deprecated(note = "Use transports instead")]
    pub port: Option<u16>,
    /// Base path for the provider, defaults to /
    #[deprecated(note = "Use transports instead")]
    pub path: String,
    /// Transports configured for the provider
    pub transports: Vec<ProviderTransport>
}
m
Ah, yes!
a
This is coming from a scenario we currently face where a consumer has submitted a contract using the
websockets
transport and we are trying to verify it against a provider. This provider only accepts
wss
TLS connections but another provider we have supports only
ws
connections. We didn't want the consumer to have to decide if the provider would be tested with or without TLS because, as you say, it doesn't change the contract and it adds a lot of complications in creating, trusting and using self-signed certs. So it felt odd for the consumer to say "this contract is for wss", "this contract is for ws" as really we only care about this when verifying the contract. What we landed on for now is to use a plugin config item "useSecureSocket" which when set to true will set the mock WS server hostname to
localhost
and send messages over
wss
instead of
ws
which allows a provider to choose whether or not to test using TLS. The problem then becomes verifying two providers on the same host (or rather same CI build container image) which want different config values as it needs to be changed / configured before running the verification. So the recommendation would be the following? • Do not support using TLS during consumer testing • Have the plugin offer two transports -
ws
and
wss
• Have the consumer specify whether or not to use
wss
or
ws
when creating the consumer contract • Verify the provider according to the transport in the contract. I am not sure if this would be better to the plugin config method or not 🤔
👍 1
m
I think you could let the contract record
ws
or
wss
but let both sides choose whether or not to use the secure variant. A config seems a reasonable option to expose that, but i’d default to non-secure for most people (because of the reasons listed by Ron above)
I think it’s OK to expose both options. But even in regular Pact world, I’ve rarely seen the SSL variant used (it’s mostly only needed when you’re testing against a real endpoint, and that real endpoint has a stupid self-signed certificate on it so you need to be able to disable or configure the transport).
a
If the user will set config and decide whether or not to use a secure connection then we do not really need to expose two transports do we? We can just expose the transport
websockets
as we are now and hide the scheme choice from the users. I think consumer side TLS/SSL is going to be an extremely rare or even non-existent use case but secure providers is something that will (has) come up because the binaries we are testing (and will deploy) use self-signed certificates for inter component communication on a device. We are testing against binaries that will be deployed to devices and they are configured in this way. The cert is embedded in the provider and the host running the tests is configured to trust it. We currently have the config value default to false
👍 1
m
yes, that makes sense to me!
gratitude thank you 1