github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/test/dockerutil/network.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package dockerutil
    16  
    17  import (
    18  	"context"
    19  	"net"
    20  
    21  	"github.com/docker/docker/api/types"
    22  	"github.com/docker/docker/api/types/network"
    23  	"github.com/docker/docker/client"
    24  	"github.com/SagerNet/gvisor/pkg/test/testutil"
    25  )
    26  
    27  // Network is a docker network.
    28  type Network struct {
    29  	client     *client.Client
    30  	id         string
    31  	logger     testutil.Logger
    32  	Name       string
    33  	containers []*Container
    34  	Subnet     *net.IPNet
    35  }
    36  
    37  // NewNetwork sets up the struct for a Docker network. Names of networks
    38  // will be unique.
    39  func NewNetwork(ctx context.Context, logger testutil.Logger) *Network {
    40  	client, err := client.NewClientWithOpts(client.FromEnv)
    41  	if err != nil {
    42  		logger.Logf("create client failed with: %v", err)
    43  		return nil
    44  	}
    45  	client.NegotiateAPIVersion(ctx)
    46  
    47  	return &Network{
    48  		logger: logger,
    49  		Name:   testutil.RandomID(logger.Name()),
    50  		client: client,
    51  	}
    52  }
    53  
    54  func (n *Network) networkCreate() types.NetworkCreate {
    55  
    56  	var subnet string
    57  	if n.Subnet != nil {
    58  		subnet = n.Subnet.String()
    59  	}
    60  
    61  	ipam := network.IPAM{
    62  		Config: []network.IPAMConfig{{
    63  			Subnet: subnet,
    64  		}},
    65  	}
    66  
    67  	return types.NetworkCreate{
    68  		CheckDuplicate: true,
    69  		IPAM:           &ipam,
    70  	}
    71  }
    72  
    73  // Create is analogous to 'docker network create'.
    74  func (n *Network) Create(ctx context.Context) error {
    75  
    76  	opts := n.networkCreate()
    77  	resp, err := n.client.NetworkCreate(ctx, n.Name, opts)
    78  	if err != nil {
    79  		return err
    80  	}
    81  	n.id = resp.ID
    82  	return nil
    83  }
    84  
    85  // Connect is analogous to 'docker network connect' with the arguments provided.
    86  func (n *Network) Connect(ctx context.Context, container *Container, ipv4, ipv6 string) error {
    87  	settings := network.EndpointSettings{
    88  		IPAMConfig: &network.EndpointIPAMConfig{
    89  			IPv4Address: ipv4,
    90  			IPv6Address: ipv6,
    91  		},
    92  	}
    93  	err := n.client.NetworkConnect(ctx, n.id, container.id, &settings)
    94  	if err == nil {
    95  		n.containers = append(n.containers, container)
    96  	}
    97  	return err
    98  }
    99  
   100  // Inspect returns this network's info.
   101  func (n *Network) Inspect(ctx context.Context) (types.NetworkResource, error) {
   102  	return n.client.NetworkInspect(ctx, n.id, types.NetworkInspectOptions{Verbose: true})
   103  }
   104  
   105  // Cleanup cleans up the docker network.
   106  func (n *Network) Cleanup(ctx context.Context) error {
   107  	n.containers = nil
   108  
   109  	return n.client.NetworkRemove(ctx, n.id)
   110  }