github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/environs/networking.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package environs
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names/v5"
     9  
    10  	"github.com/juju/juju/core/instance"
    11  	"github.com/juju/juju/core/network"
    12  	"github.com/juju/juju/environs/context"
    13  )
    14  
    15  // SupportsNetworking is a convenience helper to check if an environment
    16  // supports networking. It returns an interface containing Environ and
    17  // Networking in this case.
    18  var SupportsNetworking = supportsNetworking
    19  
    20  // DefaultSpaceInfo should be passed into Networking.ProviderSpaceInfo
    21  // to get information about the default space.
    22  var DefaultSpaceInfo *network.SpaceInfo
    23  
    24  // Networking interface defines methods that environments
    25  // with networking capabilities must implement.
    26  type Networking interface {
    27  	// Subnets returns basic information about subnets known
    28  	// by the provider for the environment.
    29  	Subnets(
    30  		ctx context.ProviderCallContext, inst instance.Id, subnetIds []network.Id,
    31  	) ([]network.SubnetInfo, error)
    32  
    33  	// SuperSubnets returns information about aggregated subnets - eg. global CIDR
    34  	// for EC2 VPC.
    35  	SuperSubnets(ctx context.ProviderCallContext) ([]string, error)
    36  
    37  	// NetworkInterfaces returns a slice with the network interfaces that
    38  	// correspond to the given instance IDs. If no instances where found,
    39  	// but there was no other error, it will return ErrNoInstances. If some
    40  	// but not all of the instances were found, the returned slice will
    41  	// have some nil slots, and an ErrPartialInstances error will be
    42  	// returned.
    43  	NetworkInterfaces(ctx context.ProviderCallContext, ids []instance.Id) ([]network.InterfaceInfos, error)
    44  
    45  	// SupportsSpaces returns whether the current environment supports
    46  	// spaces. The returned error satisfies errors.IsNotSupported(),
    47  	// unless a general API failure occurs.
    48  	SupportsSpaces(ctx context.ProviderCallContext) (bool, error)
    49  
    50  	// SupportsSpaceDiscovery returns whether the current environment
    51  	// supports discovering spaces from the provider. The returned error
    52  	// satisfies errors.IsNotSupported(), unless a general API failure occurs.
    53  	SupportsSpaceDiscovery(ctx context.ProviderCallContext) (bool, error)
    54  
    55  	// Spaces returns a slice of network.SpaceInfo with info, including
    56  	// details of all associated subnets, about all spaces known to the
    57  	// provider that have subnets available.
    58  	Spaces(ctx context.ProviderCallContext) (network.SpaceInfos, error)
    59  
    60  	// ProviderSpaceInfo returns the details of the space requested as
    61  	// a ProviderSpaceInfo. This will contain everything needed to
    62  	// decide whether an Environ of the same type in another
    63  	// controller could route to the space. Details for the default
    64  	// space can be retrieved by passing DefaultSpaceInfo (which is nil).
    65  	//
    66  	// This method accepts a SpaceInfo with details of the space that
    67  	// we need provider details for - this is the Juju model's view of
    68  	// what subnets are in the space. If the provider supports spaces
    69  	// and space discovery then it is the authority on what subnets
    70  	// are actually in the space, and it's free to collect the full
    71  	// space and subnet info using the space's ProviderId (discarding
    72  	// the subnet details passed in which might be out-of date).
    73  	//
    74  	// If the provider doesn't support space discovery then the Juju
    75  	// model's opinion of what subnets are in the space is
    76  	// authoritative. In that case the provider should collect up any
    77  	// other information needed to determine routability and include
    78  	// the passed-in space info in the ProviderSpaceInfo returned.
    79  	ProviderSpaceInfo(ctx context.ProviderCallContext, space *network.SpaceInfo) (*ProviderSpaceInfo, error)
    80  
    81  	// AreSpacesRoutable returns whether the communication between the
    82  	// two spaces can use cloud-local addresses.
    83  	AreSpacesRoutable(ctx context.ProviderCallContext, space1, space2 *ProviderSpaceInfo) (bool, error)
    84  
    85  	// SupportsContainerAddresses returns true if the current environment is
    86  	// able to allocate addresses for containers. If returning false, we also
    87  	// return an IsNotSupported error.
    88  	SupportsContainerAddresses(ctx context.ProviderCallContext) (bool, error)
    89  
    90  	// AllocateContainerAddresses allocates a static address for each of the
    91  	// container NICs in preparedInfo, hosted by the hostInstanceID. Returns the
    92  	// network config including all allocated addresses on success.
    93  	AllocateContainerAddresses(ctx context.ProviderCallContext, hostInstanceID instance.Id, containerTag names.MachineTag, preparedInfo network.InterfaceInfos) (network.InterfaceInfos, error)
    94  
    95  	// ReleaseContainerAddresses releases the previously allocated
    96  	// addresses matching the interface details passed in.
    97  	ReleaseContainerAddresses(ctx context.ProviderCallContext, interfaces []network.ProviderInterfaceInfo) error
    98  }
    99  
   100  // NetworkingEnviron combines the standard Environ interface with the
   101  // functionality for networking.
   102  type NetworkingEnviron interface {
   103  	// Environ represents a juju environment.
   104  	Environ
   105  
   106  	// Networking defines the methods of networking capable environments.
   107  	Networking
   108  }
   109  
   110  // NoSpaceDiscoveryEnviron implements methods from Networking that represent an
   111  // environ without native space support (all but MAAS at the time of writing).
   112  // None of the method receiver references are used, so it can be embedded
   113  // as nil without fear of panics.
   114  type NoSpaceDiscoveryEnviron struct{}
   115  
   116  // SupportsSpaceDiscovery (Networking) indicates that
   117  // this environ does not support space discovery.
   118  func (*NoSpaceDiscoveryEnviron) SupportsSpaceDiscovery(context.ProviderCallContext) (bool, error) {
   119  	return false, nil
   120  }
   121  
   122  // Spaces (Networking) indicates that this provider
   123  // does not support returning spaces.
   124  func (*NoSpaceDiscoveryEnviron) Spaces(context.ProviderCallContext) (network.SpaceInfos, error) {
   125  	return nil, errors.NotSupportedf("Spaces")
   126  }
   127  
   128  // ProviderSpaceInfo (Networking) indicates that this provider
   129  // does not support returning provider info for the input space.
   130  func (*NoSpaceDiscoveryEnviron) ProviderSpaceInfo(
   131  	context.ProviderCallContext, *network.SpaceInfo,
   132  ) (*ProviderSpaceInfo, error) {
   133  	return nil, errors.NotSupportedf("ProviderSpaceInfo")
   134  }
   135  
   136  func supportsNetworking(environ BootstrapEnviron) (NetworkingEnviron, bool) {
   137  	ne, ok := environ.(NetworkingEnviron)
   138  	return ne, ok
   139  }
   140  
   141  // SupportsSpaces checks if the environment implements NetworkingEnviron
   142  // and also if it supports spaces.
   143  func SupportsSpaces(ctx context.ProviderCallContext, env BootstrapEnviron) bool {
   144  	netEnv, ok := supportsNetworking(env)
   145  	if !ok {
   146  		return false
   147  	}
   148  	ok, err := netEnv.SupportsSpaces(ctx)
   149  	if err != nil {
   150  		if !errors.IsNotSupported(err) {
   151  			logger.Errorf("checking model spaces support failed with: %v", err)
   152  		}
   153  		return false
   154  	}
   155  	return ok
   156  }
   157  
   158  // SupportsContainerAddresses checks if the environment will let us allocate
   159  // addresses for containers from the host ranges.
   160  func SupportsContainerAddresses(ctx context.ProviderCallContext, env BootstrapEnviron) bool {
   161  	netEnv, ok := supportsNetworking(env)
   162  	if !ok {
   163  		return false
   164  	}
   165  	ok, err := netEnv.SupportsContainerAddresses(ctx)
   166  	if err != nil {
   167  		if !errors.IsNotSupported(err) {
   168  			logger.Errorf("checking model container address support failed with: %v", err)
   169  		}
   170  		return false
   171  	}
   172  	return ok
   173  }
   174  
   175  // ProviderSpaceInfo contains all the information about a space needed
   176  // by another environ to decide whether it can be routed to.
   177  type ProviderSpaceInfo struct {
   178  	network.SpaceInfo
   179  
   180  	// Cloud type governs what attributes will exist in the
   181  	// provider-specific map.
   182  	CloudType string
   183  
   184  	// Any provider-specific information to needed to identify the
   185  	// network within the cloud, e.g. VPC ID for EC2.
   186  	ProviderAttributes map[string]interface{}
   187  }