github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/network/containerizer/shim.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package containerizer
     5  
     6  import (
     7  	"github.com/juju/collections/set"
     8  	"github.com/juju/errors"
     9  
    10  	"github.com/juju/juju/core/constraints"
    11  	"github.com/juju/juju/core/instance"
    12  	"github.com/juju/juju/core/network"
    13  	"github.com/juju/juju/state"
    14  )
    15  
    16  //go:generate go run go.uber.org/mock/mockgen -package containerizer -destination bridgepolicy_mock_test.go github.com/juju/juju/network/containerizer Container,Address,Subnet,LinkLayerDevice
    17  
    18  // SpaceBacking describes the retrieval of all spaces from the DB.
    19  type SpaceBacking interface {
    20  	AllSpaceInfos() (network.SpaceInfos, error)
    21  }
    22  
    23  // LinkLayerDevice is an indirection for state.LinkLayerDevice.
    24  // It facilitates testing the provisioner's use of this package.
    25  type LinkLayerDevice interface {
    26  	Name() string
    27  	Type() network.LinkLayerDeviceType
    28  	MACAddress() string
    29  	ParentName() string
    30  	ParentDevice() (LinkLayerDevice, error)
    31  	EthernetDeviceForBridge(name string, askForProviderAddress bool) (network.InterfaceInfo, error)
    32  	Addresses() ([]*state.Address, error)
    33  	VirtualPortType() network.VirtualPortType
    34  
    35  	// These are recruited in tests. See comment on Machine below.
    36  	MTU() uint
    37  	IsUp() bool
    38  	IsAutoStart() bool
    39  }
    40  
    41  // linkLayerDevice implements LinkLayerDevice.
    42  // We need our own implementation of the indirection above in order to mock the
    43  // return of ParentDevice, which in the state package returns a reference to a
    44  // raw state.LinkLayerDevice.
    45  type linkLayerDevice struct {
    46  	*state.LinkLayerDevice
    47  }
    48  
    49  // ParentDevice implements LinkLayerDevice by wrapping the response from the
    50  // inner device's call in a new instance of linkLayerDevice.
    51  func (l *linkLayerDevice) ParentDevice() (LinkLayerDevice, error) {
    52  	dev, err := l.LinkLayerDevice.ParentDevice()
    53  	if err != nil {
    54  		return nil, errors.Trace(err)
    55  	}
    56  	return NewLinkLayerDevice(dev), nil
    57  }
    58  
    59  // NewLinkLayerDevice wraps the given state.LinkLayerDevice
    60  // in a linkLayerDevice.
    61  func NewLinkLayerDevice(dev *state.LinkLayerDevice) LinkLayerDevice {
    62  	return &linkLayerDevice{dev}
    63  }
    64  
    65  var _ LinkLayerDevice = (*linkLayerDevice)(nil)
    66  
    67  // Machine is an indirection for state.Machine,
    68  // describing a machine that is to host containers.
    69  type Machine interface {
    70  	Id() string
    71  	AllDeviceAddresses() ([]Address, error)
    72  	AllSpaces() (set.Strings, error)
    73  	SetLinkLayerDevices(devicesArgs ...state.LinkLayerDeviceArgs) (err error)
    74  	AllLinkLayerDevices() ([]LinkLayerDevice, error)
    75  
    76  	// TODO (manadart 2018-10-10) These methods are used in tests, which rely
    77  	// on the StateSuite. Some of them are recruited via the Container
    78  	// interface below, but they are all located here for simplicity.
    79  	// A better approach could be sought that does not require their
    80  	// presence here.
    81  	SetDevicesAddresses(devicesAddresses ...state.LinkLayerDeviceAddress) (err error)
    82  	SetConstraints(cons constraints.Value) (err error)
    83  	RemoveAllAddresses() error
    84  	Raw() *state.Machine
    85  }
    86  
    87  // MachineShim implements Machine.
    88  // It is required to mock the return of LinkLayerDevicesForSpaces,
    89  // which includes raw state.LinkLayerDevice references.
    90  type MachineShim struct {
    91  	*state.Machine
    92  }
    93  
    94  // NewMachine wraps the given state.machine in a MachineShim.
    95  func NewMachine(m *state.Machine) *MachineShim {
    96  	return &MachineShim{Machine: m}
    97  }
    98  
    99  // AllLinkLayerDevices implements Machine by wrapping each
   100  // state.LinkLayerDevice reference in returned collection with the local
   101  // LinkLayerDevice implementation.
   102  func (m *MachineShim) AllLinkLayerDevices() ([]LinkLayerDevice, error) {
   103  	devs, err := m.Machine.AllLinkLayerDevices()
   104  	if err != nil {
   105  		return nil, errors.Trace(err)
   106  	}
   107  
   108  	wrapped := make([]LinkLayerDevice, len(devs))
   109  	for i, d := range devs {
   110  		wrapped[i] = NewLinkLayerDevice(d)
   111  	}
   112  	return wrapped, nil
   113  }
   114  
   115  // AllDeviceAddresses implements Machine by wrapping each state.Address
   116  // reference in returned collection with the local Address implementation.
   117  func (m *MachineShim) AllDeviceAddresses() ([]Address, error) {
   118  	addrs, err := m.Machine.AllDeviceAddresses()
   119  	if err != nil {
   120  		return nil, errors.Trace(err)
   121  	}
   122  
   123  	wrapped := make([]Address, len(addrs))
   124  	for i, a := range addrs {
   125  		wrapped[i] = NewAddress(a)
   126  	}
   127  	return wrapped, nil
   128  }
   129  
   130  // Raw returns the inner state.Machine reference.
   131  func (m *MachineShim) Raw() *state.Machine {
   132  	return m.Machine
   133  }
   134  
   135  // Address is an indirection for state.Address.
   136  type Address interface {
   137  	Subnet() (Subnet, error)
   138  	DeviceName() string
   139  }
   140  
   141  // addressShim implements Address.
   142  type addressShim struct {
   143  	*state.Address
   144  }
   145  
   146  // NewAddress wraps the given state.Address in an addressShim.
   147  func NewAddress(a *state.Address) Address {
   148  	return &addressShim{Address: a}
   149  }
   150  
   151  func (a *addressShim) Subnet() (Subnet, error) {
   152  	return a.Address.Subnet()
   153  }
   154  
   155  // Subnet is an indirection for state.Subnet.
   156  type Subnet interface {
   157  	SpaceID() string
   158  }
   159  
   160  // Container is an indirection for state.Machine, describing a container.
   161  type Container interface {
   162  	Machine
   163  	ContainerType() instance.ContainerType
   164  	Constraints() (constraints.Value, error)
   165  }
   166  
   167  var _ Container = (*MachineShim)(nil)