Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose a WithNetwork functional option #1887

Merged
merged 2 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/features/common_functional_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ It also exports an `Executable` interface, defining one single method: `AsComman

You could use this feature to run a custom script, or to run a command that is not supported by the module right after the container is started.

#### WithNetwork

- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

By default, the container is started in the default Docker network. If you want to use a different Docker network, you can use the `WithNetwork(networkName string, alias string)` option, which receives the new network name and an alias as parameters, creating the new network, attaching the container to it, and setting the network alias for that network.

If the network already exists, _Testcontainers for Go_ won't create a new one, but it will attach the container to it and set the network alias.

#### Docker type modifiers

If you need an advanced configuration for the container, you can leverage the following Docker type modifiers:
Expand Down
4 changes: 0 additions & 4 deletions docs/modules/localstack.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ With simply passing the `testcontainers.CustomizeRequest` functional option to t

In the above example you can check how it's possible to set certain environment variables that are needed by the tests, the most important ones are the AWS services you want to use. Besides, the container runs in a separate Docker network with an alias.

#### WithNetwork

By default, the LocalStack container is started in the default Docker network. If you want to use a different Docker network, you can use the `WithNetwork(networkName string, alias string)` option, which receives the new network name and an alias as parameters, creating the new network, attaching the container to it, and setting the network alias for that network.

## Accessing hostname-sensitive services

Some Localstack APIs, such as SQS, require the container to be aware of the hostname that it is accessible on - for example, for construction of queue URLs in responses.
Expand Down
31 changes: 31 additions & 0 deletions generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -101,6 +102,36 @@ func WithHostConfigModifier(modifier func(hostConfig *container.HostConfig)) Cus
}
}

// WithNetwork creates a network with the given name and attaches the container to it, setting the network alias
// on that network to the given alias.
// If the network already exists, checking if the network name already exists, it will be reused.
func WithNetwork(networkName string, alias string) CustomizeRequestOption {
return func(req *GenericContainerRequest) {
_, err := GenericNetwork(context.Background(), GenericNetworkRequest{
NetworkRequest: NetworkRequest{
Name: networkName,
CheckDuplicate: true, // force the Docker provider to reuse an existing network
},
})
if err != nil && !strings.Contains(err.Error(), "already exists") {
logger := req.Logger
if logger == nil {
logger = Logger
}
logger.Printf("Failed to create network '%s'. Container won't be attached to this network: %v", networkName, err)
return
}

// attaching to the network because it was created with success or it already existed.
req.Networks = append(req.Networks, networkName)

if req.NetworkAliases == nil {
req.NetworkAliases = make(map[string][]string)
}
req.NetworkAliases[networkName] = []string{alias}
}
}

// Executable represents an executable command to be sent to a container
// as part of the PostStart lifecycle hook.
type Executable interface {
Expand Down
24 changes: 2 additions & 22 deletions modules/localstack/localstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,9 @@ func isVersion2(image string) bool {

// WithNetwork creates a network with the given name and attaches the container to it, setting the network alias
// on that network to the given alias.
// Deprecated: use testcontainers.WithNetwork instead
func WithNetwork(networkName string, alias string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
_, err := testcontainers.GenericNetwork(context.Background(), testcontainers.GenericNetworkRequest{
NetworkRequest: testcontainers.NetworkRequest{
Name: networkName,
},
})
if err != nil {
logger := req.Logger
if logger == nil {
logger = testcontainers.Logger
}
logger.Printf("Failed to create network '%s'. Container won't be attached to this network: %v", networkName, err)
return
}

req.Networks = append(req.Networks, networkName)

if req.NetworkAliases == nil {
req.NetworkAliases = make(map[string][]string)
}
req.NetworkAliases[networkName] = []string{alias}
}
return testcontainers.WithNetwork(networkName, alias)
}

// RunContainer creates an instance of the LocalStack container type, being possible to pass a custom request and options:
Expand Down