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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package params
     5  
     6  import (
     7  	"github.com/juju/juju/core/life"
     8  	"github.com/juju/juju/core/network"
     9  )
    10  
    11  // Subnet describes a single subnet within a network.
    12  type Subnet struct {
    13  	// CIDR of the subnet in IPv4 or IPv6 notation.
    14  	CIDR string `json:"cidr"`
    15  
    16  	// ProviderId is the provider-specific subnet ID (if applicable).
    17  	ProviderId string `json:"provider-id,omitempty"`
    18  
    19  	// ProviderNetworkId is the id of the network containing this
    20  	// subnet from the provider's perspective. It can be empty if the
    21  	// provider doesn't support distinct networks.
    22  	ProviderNetworkId string `json:"provider-network-id,omitempty"`
    23  
    24  	// ProviderSpaceId is the id of the space containing this subnet
    25  	// from the provider's perspective. It can be empty if the
    26  	// provider doesn't support spaces (in which case all subnets are
    27  	// effectively in the default space).
    28  	ProviderSpaceId string `json:"provider-space-id,omitempty"`
    29  
    30  	// VLANTag needs to be between 1 and 4094 for VLANs and 0 for
    31  	// normal networks. It's defined by IEEE 802.1Q standard.
    32  	VLANTag int `json:"vlan-tag"`
    33  
    34  	// Life is the subnet's life cycle value - Alive means the subnet
    35  	// is in use by one or more machines, Dying or Dead means the
    36  	// subnet is about to be removed.
    37  	Life life.Value `json:"life"`
    38  
    39  	// SpaceTag is the Juju network space this subnet is associated
    40  	// with.
    41  	SpaceTag string `json:"space-tag"`
    42  
    43  	// Zones contain one or more availability zones this subnet is
    44  	// associated with.
    45  	Zones []string `json:"zones"`
    46  
    47  	// TODO (jack-w-shaw 2022-02-22): Remove this. It is unused
    48  	//
    49  	// Status returns the status of the subnet, whether it is in use, not
    50  	// in use or terminating.
    51  	Status string `json:"status,omitempty"`
    52  }
    53  
    54  // SubnetV2 is used by versions of spaces/subnets APIs that must include
    55  // subnet ID in payloads.
    56  type SubnetV2 struct {
    57  	Subnet
    58  
    59  	// ID uniquely identifies the subnet.
    60  	ID string `json:"id,omitempty"`
    61  }
    62  
    63  // SubnetV3 is used by the SpaceInfos API call. Its payload matches the fields
    64  // of the core/network.SubnetInfo struct.
    65  type SubnetV3 struct {
    66  	SubnetV2
    67  
    68  	SpaceID  string          `json:"space-id"`
    69  	FanInfo  *FanConfigEntry `json:"fan-info,omitempty"`
    70  	IsPublic bool            `json:"is-public,omitempty"`
    71  }
    72  
    73  // NetworkRoute describes a special route that should be added for a given
    74  // network interface.
    75  type NetworkRoute struct {
    76  	// DestinationCIDR is the Subnet CIDR of traffic that needs a custom route.
    77  	DestinationCIDR string `json:"destination-cidr"`
    78  	// GatewayIP is the target IP to use as the next-hop when sending traffic to DestinationCIDR
    79  	GatewayIP string `json:"gateway-ip"`
    80  	// Metric is the cost for this particular route.
    81  	Metric int `json:"metric"`
    82  }
    83  
    84  // NetworkOrigin specifies where an address comes from, whether it was reported
    85  // by a provider or by a machine.
    86  type NetworkOrigin string
    87  
    88  // NetworkConfig describes the necessary information to configure
    89  // a single network interface on a machine. This mostly duplicates
    90  // network.InterfaceInfo type and it's defined here so it can be kept
    91  // separate and stable as definition to ensure proper wire-format for
    92  // the API.
    93  type NetworkConfig struct {
    94  	// DeviceIndex specifies the order in which the network interface
    95  	// appears on the host. The primary interface has an index of 0.
    96  	DeviceIndex int `json:"device-index"`
    97  
    98  	// MACAddress is the network interface's hardware MAC address
    99  	// (e.g. "aa:bb:cc:dd:ee:ff").
   100  	MACAddress string `json:"mac-address"`
   101  
   102  	// CIDR of the network, in 123.45.67.89/24 format.
   103  	CIDR string `json:"cidr"`
   104  
   105  	// MTU is the Maximum Transmission Unit controlling the maximum size of the
   106  	// protocol packets that the interface can pass through. It is only used
   107  	// when > 0.
   108  	MTU int `json:"mtu"`
   109  
   110  	// ProviderId is a provider-specific network interface id.
   111  	ProviderId string `json:"provider-id"`
   112  
   113  	// ProviderNetworkId is a provider-specific id for the network this
   114  	// interface is part of.
   115  	ProviderNetworkId string `json:"provider-network-id"`
   116  
   117  	// ProviderSubnetId is a provider-specific subnet id, to which the
   118  	// interface is attached to.
   119  	ProviderSubnetId string `json:"provider-subnet-id"`
   120  
   121  	// ProviderSpaceId is a provider-specific space id to which the interface
   122  	// is attached, if known and supported.
   123  	ProviderSpaceId string `json:"provider-space-id"`
   124  
   125  	// ProviderAddressId is the provider-specific id of the assigned address,
   126  	// if supported and known.
   127  	ProviderAddressId string `json:"provider-address-id"`
   128  
   129  	// ProviderVLANId is the provider-specific id of the assigned address's
   130  	// VLAN, if supported and known.
   131  	ProviderVLANId string `json:"provider-vlan-id"`
   132  
   133  	// VLANTag needs to be between 1 and 4094 for VLANs and 0 for
   134  	// normal networks. It's defined by IEEE 802.1Q standard.
   135  	VLANTag int `json:"vlan-tag"`
   136  
   137  	// InterfaceName is the raw OS-specific network device name (e.g.
   138  	// "eth1", even for a VLAN eth1.42 virtual interface).
   139  	InterfaceName string `json:"interface-name"`
   140  
   141  	// ParentInterfaceName is the name of the parent interface to use, if known.
   142  	ParentInterfaceName string `json:"parent-interface-name"`
   143  
   144  	// InterfaceType is the type of the interface.
   145  	InterfaceType string `json:"interface-type"`
   146  
   147  	// Disabled is true when the interface needs to be disabled on the
   148  	// machine, e.g. not to configure it at all or stop it if running.
   149  	Disabled bool `json:"disabled"`
   150  
   151  	// NoAutoStart is true when the interface should not be configured
   152  	// to start automatically on boot. By default and for
   153  	// backwards-compatibility, interfaces are configured to
   154  	// auto-start.
   155  	NoAutoStart bool `json:"no-auto-start,omitempty"`
   156  
   157  	// ConfigType, if set, defines what type of configuration to use.
   158  	// See network.AddressConfigType for more info. If not set, for
   159  	// backwards-compatibility, "dhcp" is assumed.
   160  	ConfigType string `json:"config-type,omitempty"`
   161  
   162  	// Address contains an optional static IP address to configure for
   163  	// this network interface. The subnet mask to set will be inferred
   164  	// from the CIDR value.
   165  	//
   166  	// NOTE(achilleasa) this field is retained for backwards compatibility
   167  	// purposes and will be removed in juju 3. New features should use
   168  	// the Addresses field below which also include scope information.
   169  	Address string `json:"address,omitempty"`
   170  
   171  	// Addresses contains an optional list of static IP address to
   172  	// configure for this network interface. The subnet mask to set will be
   173  	// inferred from the CIDR value of the first entry which is always
   174  	// assumed to be the primary IP address for the interface.
   175  	Addresses []Address `json:"addresses,omitempty"`
   176  
   177  	// ShadowAddresses contains an optional list of additional IP addresses
   178  	// that the underlying network provider associates with this network
   179  	// interface instance. These IP addresses are not typically visible
   180  	// to the machine that the interface is connected to.
   181  	ShadowAddresses []Address `json:"shadow-addresses,omitempty"`
   182  
   183  	// DNSServers contains an optional list of IP addresses and/or
   184  	// hostnames to configure as DNS servers for this network
   185  	// interface.
   186  	DNSServers []string `json:"dns-servers,omitempty"`
   187  
   188  	// DNSServers contains an optional list of IP addresses and/or
   189  	// hostnames to configure as DNS servers for this network
   190  	// interface.
   191  	DNSSearchDomains []string `json:"dns-search-domains,omitempty"`
   192  
   193  	// Gateway address, if set, defines the default gateway to
   194  	// configure for this network interface. For containers this
   195  	// usually (one of) the host address(es).
   196  	GatewayAddress string `json:"gateway-address,omitempty"`
   197  
   198  	// Routes is a list of routes that should be applied when this interface is
   199  	// active.
   200  	Routes []NetworkRoute `json:"routes,omitempty"`
   201  
   202  	// IsDefaultGateway marks an interface that is a default gateway for a machine.
   203  	IsDefaultGateway bool `json:"is-default-gateway,omitempty"`
   204  
   205  	// VirtualPortType provides additional information about the type of
   206  	// this device if it belongs to a virtual switch (e.g. when using
   207  	// open-vswitch).
   208  	VirtualPortType string `json:"virtual-port-type,omitempty"`
   209  
   210  	// NetworkOrigin represents the authoritative source of the NetworkConfig.
   211  	// It is expected that either the provider gave us this info or the
   212  	// machine gave us this info.
   213  	// Giving us this information allows us to reason about when a InterfaceInfo
   214  	// is in use.
   215  	NetworkOrigin NetworkOrigin `json:"origin,omitempty"`
   216  }
   217  
   218  // NetworkConfigFromInterfaceInfo converts a slice of network.InterfaceInfo into
   219  // the equivalent NetworkConfig slice.
   220  func NetworkConfigFromInterfaceInfo(interfaceInfos network.InterfaceInfos) []NetworkConfig {
   221  	result := make([]NetworkConfig, len(interfaceInfos))
   222  	for i, v := range interfaceInfos {
   223  		var dnsServers []string
   224  		for _, nameserver := range v.DNSServers {
   225  			dnsServers = append(dnsServers, nameserver.Value)
   226  		}
   227  
   228  		var routes []NetworkRoute
   229  		if len(v.Routes) != 0 {
   230  			routes = make([]NetworkRoute, len(v.Routes))
   231  			for j, route := range v.Routes {
   232  				routes[j] = NetworkRoute{
   233  					DestinationCIDR: route.DestinationCIDR,
   234  					GatewayIP:       route.GatewayIP,
   235  					Metric:          route.Metric,
   236  				}
   237  			}
   238  		}
   239  
   240  		result[i] = NetworkConfig{
   241  			DeviceIndex:         v.DeviceIndex,
   242  			MACAddress:          network.NormalizeMACAddress(v.MACAddress),
   243  			ConfigType:          string(v.ConfigType),
   244  			MTU:                 v.MTU,
   245  			ProviderId:          string(v.ProviderId),
   246  			ProviderNetworkId:   string(v.ProviderNetworkId),
   247  			ProviderSubnetId:    string(v.ProviderSubnetId),
   248  			ProviderSpaceId:     string(v.ProviderSpaceId),
   249  			ProviderVLANId:      string(v.ProviderVLANId),
   250  			ProviderAddressId:   string(v.ProviderAddressId),
   251  			VLANTag:             v.VLANTag,
   252  			InterfaceName:       v.InterfaceName,
   253  			ParentInterfaceName: v.ParentInterfaceName,
   254  			InterfaceType:       string(v.InterfaceType),
   255  			Disabled:            v.Disabled,
   256  			NoAutoStart:         v.NoAutoStart,
   257  			Addresses:           FromProviderAddresses(v.Addresses...),
   258  			ShadowAddresses:     FromProviderAddresses(v.ShadowAddresses...),
   259  			DNSServers:          dnsServers,
   260  			DNSSearchDomains:    v.DNSSearchDomains,
   261  			GatewayAddress:      v.GatewayAddress.Value,
   262  			Routes:              routes,
   263  			IsDefaultGateway:    v.IsDefaultGateway,
   264  			VirtualPortType:     string(v.VirtualPortType),
   265  			NetworkOrigin:       NetworkOrigin(v.Origin),
   266  
   267  			// TODO (manadart 2021-03-24): Retained for compatibility.
   268  			// Delete CIDR and Address for Juju 3/4.
   269  			CIDR:    v.PrimaryAddress().CIDR,
   270  			Address: v.PrimaryAddress().Value,
   271  		}
   272  	}
   273  	return result
   274  }
   275  
   276  // InterfaceInfoFromNetworkConfig converts a slice of NetworkConfig into the
   277  // equivalent network.InterfaceInfo slice.
   278  func InterfaceInfoFromNetworkConfig(configs []NetworkConfig) network.InterfaceInfos {
   279  	result := make(network.InterfaceInfos, len(configs))
   280  	for i, v := range configs {
   281  		var routes []network.Route
   282  		if len(v.Routes) != 0 {
   283  			routes = make([]network.Route, len(v.Routes))
   284  			for j, route := range v.Routes {
   285  				routes[j] = network.Route{
   286  					DestinationCIDR: route.DestinationCIDR,
   287  					GatewayIP:       route.GatewayIP,
   288  					Metric:          route.Metric,
   289  				}
   290  			}
   291  		}
   292  
   293  		configType := network.AddressConfigType(v.ConfigType)
   294  
   295  		result[i] = network.InterfaceInfo{
   296  			DeviceIndex:         v.DeviceIndex,
   297  			MACAddress:          network.NormalizeMACAddress(v.MACAddress),
   298  			MTU:                 v.MTU,
   299  			ProviderId:          network.Id(v.ProviderId),
   300  			ProviderNetworkId:   network.Id(v.ProviderNetworkId),
   301  			ProviderSubnetId:    network.Id(v.ProviderSubnetId),
   302  			ProviderSpaceId:     network.Id(v.ProviderSpaceId),
   303  			ProviderVLANId:      network.Id(v.ProviderVLANId),
   304  			ProviderAddressId:   network.Id(v.ProviderAddressId),
   305  			VLANTag:             v.VLANTag,
   306  			InterfaceName:       v.InterfaceName,
   307  			ParentInterfaceName: v.ParentInterfaceName,
   308  			InterfaceType:       network.LinkLayerDeviceType(v.InterfaceType),
   309  			Disabled:            v.Disabled,
   310  			NoAutoStart:         v.NoAutoStart,
   311  			ConfigType:          configType,
   312  			Addresses:           ToProviderAddresses(v.Addresses...),
   313  			ShadowAddresses:     ToProviderAddresses(v.ShadowAddresses...),
   314  			DNSServers:          network.NewMachineAddresses(v.DNSServers).AsProviderAddresses(),
   315  			DNSSearchDomains:    v.DNSSearchDomains,
   316  			GatewayAddress:      network.NewMachineAddress(v.GatewayAddress).AsProviderAddress(),
   317  			Routes:              routes,
   318  			IsDefaultGateway:    v.IsDefaultGateway,
   319  			VirtualPortType:     network.VirtualPortType(v.VirtualPortType),
   320  			Origin:              network.Origin(v.NetworkOrigin),
   321  		}
   322  
   323  		// Compatibility accommodations follow.
   324  		// TODO (manadart 2021-03-05): Juju 3/4 should require that only the
   325  		// address collections are used, and the following fields removed from
   326  		// the top-level interface:
   327  		// - CIDR
   328  		// - Address
   329  
   330  		// 1) For clients that populate Addresses, but still set
   331  		//    address-specific fields on the device.
   332  		//    Note that the assumption must hold (as it does at the time of
   333  		//    writing) that the collections are only populated with a single
   334  		//    member, with repeated devices for each address.
   335  		if len(result[i].Addresses) > 0 {
   336  			if result[i].Addresses[0].CIDR == "" {
   337  				result[i].Addresses[0].CIDR = v.CIDR
   338  			}
   339  			if result[i].Addresses[0].ConfigType == "" {
   340  				result[i].Addresses[0].ConfigType = configType
   341  			}
   342  		} else {
   343  			// 2) For even older clients that do not populate Addresses.
   344  			if v.Address != "" {
   345  				result[i].Addresses = network.ProviderAddresses{
   346  					network.NewMachineAddress(
   347  						v.Address,
   348  						network.WithCIDR(v.CIDR),
   349  						network.WithConfigType(configType),
   350  					).AsProviderAddress(),
   351  				}
   352  			}
   353  		}
   354  	}
   355  
   356  	return result
   357  }
   358  
   359  // DeviceBridgeInfo lists the host device and the expected bridge to be
   360  // created.
   361  type DeviceBridgeInfo struct {
   362  	HostDeviceName string `json:"host-device-name"`
   363  	BridgeName     string `json:"bridge-name"`
   364  	MACAddress     string `json:"mac-address"`
   365  }
   366  
   367  // ProviderInterfaceInfoResults holds the results of a
   368  // GetProviderInterfaceInfo call.
   369  type ProviderInterfaceInfoResults struct {
   370  	Results []ProviderInterfaceInfoResult `json:"results"`
   371  }
   372  
   373  // ProviderInterfaceInfoResult stores the provider interface
   374  // information for one machine, or any error that occurred getting the
   375  // information for that machine.
   376  type ProviderInterfaceInfoResult struct {
   377  	MachineTag string                  `json:"machine-tag"`
   378  	Interfaces []ProviderInterfaceInfo `json:"interfaces"`
   379  	Error      *Error                  `json:"error,omitempty"`
   380  }
   381  
   382  // ProviderInterfaceInfo stores the details needed to identify an
   383  // interface to a provider. It's the params equivalent of
   384  // network.ProviderInterfaceInfo, defined here separately to ensure
   385  // that API structures aren't inadvertently changed by internal
   386  // changes.
   387  type ProviderInterfaceInfo struct {
   388  	InterfaceName string `json:"interface-name"`
   389  	MACAddress    string `json:"mac-address"`
   390  	ProviderId    string `json:"provider-id"`
   391  }
   392  
   393  // Port encapsulates a protocol and port number. It is used in API
   394  // requests/responses. See also network.Port, from/to which this is
   395  // transformed.
   396  type Port struct {
   397  	Protocol string `json:"protocol"`
   398  	Number   int    `json:"number"`
   399  }
   400  
   401  // PortRange represents a single range of ports. It is used in API
   402  // requests/responses. See also network.PortRange, from/to which this is
   403  // transformed.
   404  type PortRange struct {
   405  	FromPort int    `json:"from-port"`
   406  	ToPort   int    `json:"to-port"`
   407  	Protocol string `json:"protocol"`
   408  }
   409  
   410  // FromNetworkPortRange is a convenience helper to create a parameter
   411  // out of the network type, here for PortRange.
   412  func FromNetworkPortRange(pr network.PortRange) PortRange {
   413  	return PortRange{
   414  		FromPort: pr.FromPort,
   415  		ToPort:   pr.ToPort,
   416  		Protocol: pr.Protocol,
   417  	}
   418  }
   419  
   420  // NetworkPortRange is a convenience helper to return the parameter
   421  // as network type, here for PortRange.
   422  func (pr PortRange) NetworkPortRange() network.PortRange {
   423  	return network.PortRange{
   424  		FromPort: pr.FromPort,
   425  		ToPort:   pr.ToPort,
   426  		Protocol: pr.Protocol,
   427  	}
   428  }
   429  
   430  // EntityPort holds an entity's tag, a protocol and a port.
   431  type EntityPort struct {
   432  	Tag      string `json:"tag"`
   433  	Protocol string `json:"protocol"`
   434  	Port     int    `json:"port"`
   435  }
   436  
   437  // EntitiesPorts holds the parameters for making an OpenPort or
   438  // ClosePort on some entities.
   439  type EntitiesPorts struct {
   440  	Entities []EntityPort `json:"entities"`
   441  }
   442  
   443  // EntityPortRange holds an entity's tag, a protocol and a port range.
   444  type EntityPortRange struct {
   445  	Tag      string `json:"tag"`
   446  	Protocol string `json:"protocol"`
   447  	FromPort int    `json:"from-port"`
   448  	ToPort   int    `json:"to-port"`
   449  
   450  	// Endpoint can be left empty to indicate that this port range applies
   451  	// to all application endpoints.
   452  	Endpoint string `json:"endpoint"`
   453  }
   454  
   455  // EntitiesPortRanges holds the parameters for making an OpenPorts or
   456  // ClosePorts on some entities.
   457  // TODO(juju3) - remove
   458  type EntitiesPortRanges struct {
   459  	Entities []EntityPortRange `json:"entities"`
   460  }
   461  
   462  // Address represents the location of a machine, including metadata
   463  // about what kind of location the address describes.
   464  // See also the address types in core/network that this type can be
   465  // transformed to/from.
   466  // TODO (manadart 2021-03-05): CIDR is here to correct the old cardinality
   467  // mismatch of having it on the parent NetworkConfig.
   468  // Once we are liberated from backwards compatibility concerns (Juju 3/4),
   469  // we should consider just ensuring that the Value field is in CIDR form.
   470  // This way we can push any required parsing to a single location server-side
   471  // instead of doing it for every implementation of environ.NetworkInterfaces
   472  // plus on-machine detection.
   473  // There are cases when we convert it *back* to the ip/mask form anyway.
   474  type Address struct {
   475  	Value           string `json:"value"`
   476  	CIDR            string `json:"cidr,omitempty"`
   477  	Type            string `json:"type"`
   478  	Scope           string `json:"scope"`
   479  	SpaceName       string `json:"space-name,omitempty"`
   480  	ProviderSpaceID string `json:"space-id,omitempty"`
   481  	ConfigType      string `json:"config-type,omitempty"`
   482  	IsSecondary     bool   `json:"is-secondary,omitempty"`
   483  }
   484  
   485  // MachineAddress transforms the Address to a MachineAddress,
   486  // effectively ignoring the space fields.
   487  func (addr Address) MachineAddress() network.MachineAddress {
   488  	return network.MachineAddress{
   489  		Value:       addr.Value,
   490  		CIDR:        addr.CIDR,
   491  		Type:        network.AddressType(addr.Type),
   492  		Scope:       network.Scope(addr.Scope),
   493  		ConfigType:  network.AddressConfigType(addr.ConfigType),
   494  		IsSecondary: addr.IsSecondary,
   495  	}
   496  }
   497  
   498  // ProviderAddress transforms the Address to a ProviderAddress.
   499  func (addr Address) ProviderAddress() network.ProviderAddress {
   500  	return network.ProviderAddress{
   501  		MachineAddress:  addr.MachineAddress(),
   502  		SpaceName:       network.SpaceName(addr.SpaceName),
   503  		ProviderSpaceID: network.Id(addr.ProviderSpaceID),
   504  	}
   505  }
   506  
   507  // ToProviderAddresses transforms multiple Addresses into a
   508  // ProviderAddresses collection.
   509  func ToProviderAddresses(addrs ...Address) network.ProviderAddresses {
   510  	if len(addrs) == 0 {
   511  		return nil
   512  	}
   513  
   514  	pAddrs := make([]network.ProviderAddress, len(addrs))
   515  	for i, addr := range addrs {
   516  		pAddrs[i] = addr.ProviderAddress()
   517  	}
   518  	return pAddrs
   519  }
   520  
   521  // FromProviderAddresses transforms multiple ProviderAddresses
   522  // into a slice of Address.
   523  func FromProviderAddresses(pAddrs ...network.ProviderAddress) []Address {
   524  	if len(pAddrs) == 0 {
   525  		return nil
   526  	}
   527  
   528  	addrs := make([]Address, len(pAddrs))
   529  	for i, pAddr := range pAddrs {
   530  		addrs[i] = FromProviderAddress(pAddr)
   531  	}
   532  	return addrs
   533  }
   534  
   535  // FromProviderAddress returns an Address for the input ProviderAddress.
   536  func FromProviderAddress(addr network.ProviderAddress) Address {
   537  	return Address{
   538  		Value:           addr.Value,
   539  		CIDR:            addr.CIDR,
   540  		Type:            string(addr.Type),
   541  		Scope:           string(addr.Scope),
   542  		SpaceName:       string(addr.SpaceName),
   543  		ProviderSpaceID: string(addr.ProviderSpaceID),
   544  		ConfigType:      string(addr.ConfigType),
   545  		IsSecondary:     addr.IsSecondary,
   546  	}
   547  }
   548  
   549  // FromMachineAddresses transforms multiple MachineAddresses
   550  // into a slice of Address.
   551  func FromMachineAddresses(mAddrs ...network.MachineAddress) []Address {
   552  	addrs := make([]Address, len(mAddrs))
   553  	for i, mAddr := range mAddrs {
   554  		addrs[i] = FromMachineAddress(mAddr)
   555  	}
   556  	return addrs
   557  }
   558  
   559  // FromMachineAddress returns an Address for the input MachineAddress.
   560  func FromMachineAddress(addr network.MachineAddress) Address {
   561  	return Address{
   562  		Value:       addr.Value,
   563  		CIDR:        addr.CIDR,
   564  		Type:        string(addr.Type),
   565  		Scope:       string(addr.Scope),
   566  		ConfigType:  string(addr.ConfigType),
   567  		IsSecondary: addr.IsSecondary,
   568  	}
   569  }
   570  
   571  // HostPort associates an address with a port. It's used in
   572  // the API requests/responses. See also network.HostPort, from/to
   573  // which this is transformed.
   574  type HostPort struct {
   575  	Address
   576  	Port int `json:"port"`
   577  }
   578  
   579  // MachineHostPort transforms the HostPort to a MachineHostPort.
   580  func (hp HostPort) MachineHostPort() network.MachineHostPort {
   581  	return network.MachineHostPort{MachineAddress: hp.Address.MachineAddress(), NetPort: network.NetPort(hp.Port)}
   582  }
   583  
   584  // ToMachineHostsPorts transforms slices of HostPort grouped by server into
   585  // a slice of MachineHostPorts collections.
   586  func ToMachineHostsPorts(hpm [][]HostPort) []network.MachineHostPorts {
   587  	mHpm := make([]network.MachineHostPorts, len(hpm))
   588  	for i, hps := range hpm {
   589  		mHpm[i] = ToMachineHostPorts(hps)
   590  	}
   591  	return mHpm
   592  }
   593  
   594  // ToMachineHostPorts transforms multiple Addresses into a
   595  // MachineHostPort collection.
   596  func ToMachineHostPorts(hps []HostPort) network.MachineHostPorts {
   597  	mHps := make(network.MachineHostPorts, len(hps))
   598  	for i, hp := range hps {
   599  		mHps[i] = hp.MachineHostPort()
   600  	}
   601  	return mHps
   602  }
   603  
   604  // ProviderHostPort transforms the HostPort to a ProviderHostPort.
   605  func (hp HostPort) ProviderHostPort() network.ProviderHostPort {
   606  	return network.ProviderHostPort{ProviderAddress: hp.Address.ProviderAddress(), NetPort: network.NetPort(hp.Port)}
   607  }
   608  
   609  // ToProviderHostsPorts transforms slices of HostPort grouped by server into
   610  // a slice of ProviderHostPort collections.
   611  func ToProviderHostsPorts(hpm [][]HostPort) []network.ProviderHostPorts {
   612  	pHpm := make([]network.ProviderHostPorts, len(hpm))
   613  	for i, hps := range hpm {
   614  		pHpm[i] = ToProviderHostPorts(hps)
   615  	}
   616  	return pHpm
   617  }
   618  
   619  // ToProviderHostPorts transforms multiple Addresses into a
   620  // ProviderHostPorts collection.
   621  func ToProviderHostPorts(hps []HostPort) network.ProviderHostPorts {
   622  	pHps := make(network.ProviderHostPorts, len(hps))
   623  	for i, hp := range hps {
   624  		pHps[i] = hp.ProviderHostPort()
   625  	}
   626  	return pHps
   627  }
   628  
   629  // FromProviderHostsPorts is a helper to create a parameter
   630  // out of the network type, here for a nested slice of HostPort.
   631  func FromProviderHostsPorts(nhpm []network.ProviderHostPorts) [][]HostPort {
   632  	hpm := make([][]HostPort, len(nhpm))
   633  	for i, nhps := range nhpm {
   634  		hpm[i] = FromProviderHostPorts(nhps)
   635  	}
   636  	return hpm
   637  }
   638  
   639  // FromProviderHostPorts is a helper to create a parameter
   640  // out of the network type, here for a slice of HostPort.
   641  func FromProviderHostPorts(nhps network.ProviderHostPorts) []HostPort {
   642  	hps := make([]HostPort, len(nhps))
   643  	for i, nhp := range nhps {
   644  		hps[i] = FromProviderHostPort(nhp)
   645  	}
   646  	return hps
   647  }
   648  
   649  // FromProviderHostPort is a convenience helper to create a parameter
   650  // out of the network type, here for ProviderHostPort.
   651  func FromProviderHostPort(nhp network.ProviderHostPort) HostPort {
   652  	return HostPort{FromProviderAddress(nhp.ProviderAddress), nhp.Port()}
   653  }
   654  
   655  // FromHostsPorts is a helper to create a parameter
   656  // out of the network type, here for a nested slice of HostPort.
   657  func FromHostsPorts(nhpm []network.HostPorts) [][]HostPort {
   658  	hpm := make([][]HostPort, len(nhpm))
   659  	for i, nhps := range nhpm {
   660  		hpm[i] = FromHostPorts(nhps)
   661  	}
   662  	return hpm
   663  }
   664  
   665  // FromHostPorts is a helper to create a parameter
   666  // out of the network type, here for a slice of HostPort.
   667  func FromHostPorts(nhps network.HostPorts) []HostPort {
   668  	hps := make([]HostPort, len(nhps))
   669  	for i, nhp := range nhps {
   670  		hps[i] = FromHostPort(nhp)
   671  	}
   672  	return hps
   673  }
   674  
   675  // FromHostPort is a convenience helper to create a parameter
   676  // out of the network type, here for HostPort.
   677  func FromHostPort(nhp network.HostPort) HostPort {
   678  	return HostPort{
   679  		Address: Address{
   680  			Value: nhp.Host(),
   681  			Type:  string(nhp.AddressType()),
   682  			Scope: string(nhp.AddressScope()),
   683  		},
   684  		Port: nhp.Port(),
   685  	}
   686  }
   687  
   688  // SetProviderNetworkConfig holds a slice of machine network configs sourced
   689  // from a provider.
   690  type SetProviderNetworkConfig struct {
   691  	Args []ProviderNetworkConfig `json:"args"`
   692  }
   693  
   694  // ProviderNetworkConfig holds a machine tag and a list of network interface
   695  // info obtained by querying the provider.
   696  type ProviderNetworkConfig struct {
   697  	Tag     string          `json:"tag"`
   698  	Configs []NetworkConfig `json:"config"`
   699  }
   700  
   701  // SetProviderNetworkConfigResults holds a list of SetProviderNetwork config
   702  // results.
   703  type SetProviderNetworkConfigResults struct {
   704  	Results []SetProviderNetworkConfigResult `json:"results"`
   705  }
   706  
   707  // SetProviderNetworkConfigResult holds a list of provider addresses or an
   708  // error.
   709  type SetProviderNetworkConfigResult struct {
   710  	Error     *Error    `json:"error,omitempty"`
   711  	Addresses []Address `json:"addresses"`
   712  
   713  	// Modified will be set to true if the provider address list has been
   714  	// updated.
   715  	Modified bool `json:"modified"`
   716  }
   717  
   718  // MachineAddresses holds an machine tag and addresses.
   719  type MachineAddresses struct {
   720  	Tag       string    `json:"tag"`
   721  	Addresses []Address `json:"addresses"`
   722  }
   723  
   724  // SetMachinesAddresses holds the parameters for making an
   725  // API call to update machine addresses.
   726  type SetMachinesAddresses struct {
   727  	MachineAddresses []MachineAddresses `json:"machine-addresses"`
   728  }
   729  
   730  // SetMachineNetworkConfig holds the parameters for making an API call to update
   731  // machine network config.
   732  type SetMachineNetworkConfig struct {
   733  	Tag    string          `json:"tag"`
   734  	Config []NetworkConfig `json:"config"`
   735  }
   736  
   737  // BackFillMachineOrigin sets all empty NetworkOrigin entries to indicate that
   738  // they are sourced from the local machine.
   739  // TODO (manadart 2020-05-12): This is used by superseded methods on the
   740  // Machiner and NetworkConfig APIs, which along with this should considered for
   741  // removing for Juju 3.0.
   742  func (c *SetMachineNetworkConfig) BackFillMachineOrigin() {
   743  	for i := range c.Config {
   744  		if c.Config[i].NetworkOrigin != "" {
   745  			continue
   746  		}
   747  		c.Config[i].NetworkOrigin = NetworkOrigin(network.OriginMachine)
   748  	}
   749  }
   750  
   751  // MachineAddressesResult holds a list of machine addresses or an
   752  // error.
   753  type MachineAddressesResult struct {
   754  	Error     *Error    `json:"error,omitempty"`
   755  	Addresses []Address `json:"addresses"`
   756  }
   757  
   758  // MachineAddressesResults holds the results of calling an API method
   759  // returning a list of addresses per machine.
   760  type MachineAddressesResults struct {
   761  	Results []MachineAddressesResult `json:"results"`
   762  }
   763  
   764  // MachinePortRange holds a single port range open on a machine for
   765  // the given unit and relation tags.
   766  type MachinePortRange struct {
   767  	UnitTag     string    `json:"unit-tag"`
   768  	RelationTag string    `json:"relation-tag"`
   769  	PortRange   PortRange `json:"port-range"`
   770  }
   771  
   772  // MachinePorts holds a machine and subnet tags. It's used when referring to
   773  // opened ports on the machine for a subnet.
   774  type MachinePorts struct {
   775  	MachineTag string `json:"machine-tag"`
   776  	SubnetTag  string `json:"subnet-tag"`
   777  }
   778  
   779  // PortsResults holds the bulk operation result of an API call
   780  // that returns a slice of Port.
   781  type PortsResults struct {
   782  	Results []PortsResult `json:"results"`
   783  }
   784  
   785  // PortsResult holds the result of an API call that returns a slice
   786  // of Port or an error.
   787  type PortsResult struct {
   788  	Error *Error `json:"error,omitempty"`
   789  	Ports []Port `json:"ports"`
   790  }
   791  
   792  // UnitNetworkConfigResult holds network configuration for a single unit.
   793  type UnitNetworkConfigResult struct {
   794  	Error *Error `json:"error,omitempty"`
   795  
   796  	// Tagged to Info due to compatibility reasons.
   797  	Config []NetworkConfig `json:"info"`
   798  }
   799  
   800  // UnitNetworkConfigResults holds network configuration for multiple units.
   801  type UnitNetworkConfigResults struct {
   802  	Results []UnitNetworkConfigResult `json:"results"`
   803  }
   804  
   805  // MachineNetworkConfigResult holds network configuration for a single machine.
   806  type MachineNetworkConfigResult struct {
   807  	Error *Error `json:"error,omitempty"`
   808  
   809  	// Tagged to Info due to compatibility reasons.
   810  	Config []NetworkConfig `json:"info"`
   811  }
   812  
   813  // MachineNetworkConfigResults holds network configuration for multiple machines.
   814  type MachineNetworkConfigResults struct {
   815  	Results []MachineNetworkConfigResult `json:"results"`
   816  }
   817  
   818  // HostNetworkChange holds the information about how a host machine should be
   819  // modified to prepare for a container.
   820  type HostNetworkChange struct {
   821  	Error *Error `json:"error,omitempty"`
   822  
   823  	// NewBridges lists the bridges that need to be created and what host
   824  	// device they should be connected to.
   825  	NewBridges []DeviceBridgeInfo `json:"new-bridges"`
   826  
   827  	// ReconfigureDelay is the duration in seconds to sleep before
   828  	// raising the bridged interface
   829  	ReconfigureDelay int `json:"reconfigure-delay"`
   830  }
   831  
   832  // HostNetworkChangeResults holds the network changes that are necessary for multiple containers to be created.
   833  type HostNetworkChangeResults struct {
   834  	Results []HostNetworkChange `json:"results"`
   835  }
   836  
   837  // ApplicationOpenedPorts describes the set of port ranges that have been
   838  // opened by an application for an endpoint.
   839  type ApplicationOpenedPorts struct {
   840  	Endpoint   string      `json:"endpoint"`
   841  	PortRanges []PortRange `json:"port-ranges"`
   842  }
   843  
   844  // ApplicationOpenedPortsResult holds a single result of the
   845  // CAASFirewallerEmbedded.GetOpenedPorts() API calls.
   846  type ApplicationOpenedPortsResult struct {
   847  	Error                 *Error                   `json:"error,omitempty"`
   848  	ApplicationPortRanges []ApplicationOpenedPorts `json:"application-port-ranges"`
   849  }
   850  
   851  // ApplicationOpenedPortsResults holds all the results of the
   852  // CAASFirewallerEmbedded.GetOpenedPorts() API calls.
   853  type ApplicationOpenedPortsResults struct {
   854  	Results []ApplicationOpenedPortsResult `json:"results"`
   855  }
   856  
   857  // OpenPortRangesByEndpointResults holds the results of a request to the
   858  // uniter's OpenedMachinePortRangesByEndpoint and OpenedPortRangesByEndpoint API.
   859  type OpenPortRangesByEndpointResults struct {
   860  	Results []OpenPortRangesByEndpointResult `json:"results"`
   861  }
   862  
   863  // OpenPortRangesByEndpointResult holds a single result of a request to
   864  // the uniter's OpenedMachinePortRangesByEndpoint and OpenedPortRangesByEndpoint API.
   865  type OpenPortRangesByEndpointResult struct {
   866  	Error *Error `json:"error,omitempty"`
   867  
   868  	// The set of opened port ranges grouped by unit tag.
   869  	UnitPortRanges map[string][]OpenUnitPortRangesByEndpoint `json:"unit-port-ranges"`
   870  }
   871  
   872  // OpenUnitPortRangesByEndpoint describes the set of port ranges that have been
   873  // opened by a unit on the machine it is deployed to for an endpoint.
   874  type OpenUnitPortRangesByEndpoint struct {
   875  	Endpoint   string      `json:"endpoint"`
   876  	PortRanges []PortRange `json:"port-ranges"`
   877  }
   878  
   879  // OpenMachinePortRangesResults holds the results of a request to the
   880  // firewaller's OpenedMachinePortRanges API.
   881  type OpenMachinePortRangesResults struct {
   882  	Results []OpenMachinePortRangesResult `json:"results"`
   883  }
   884  
   885  // OpenMachinePortRangesResult holds a single result of a request to
   886  // the firewaller's OpenedMachinePortRanges API.
   887  type OpenMachinePortRangesResult struct {
   888  	Error *Error `json:"error,omitempty"`
   889  
   890  	// The set of opened port ranges grouped by unit tag.
   891  	UnitPortRanges map[string][]OpenUnitPortRanges `json:"unit-port-ranges"`
   892  }
   893  
   894  // OpenUnitPortRanges describes the set of port ranges that have been
   895  // opened by a unit on the machine it is deployed to for an endpoint.
   896  type OpenUnitPortRanges struct {
   897  	Endpoint   string      `json:"endpoint"`
   898  	PortRanges []PortRange `json:"port-ranges"`
   899  
   900  	// The CIDRs that correspond to the subnets assigned to the space that
   901  	// this endpoint is bound to.
   902  	SubnetCIDRs []string `json:"subnet-cidrs"`
   903  }
   904  
   905  type IngressRulesResult struct {
   906  	Rules []IngressRule `json:"rules"`
   907  	Error *Error        `json:"error,omitempty"`
   908  }
   909  
   910  type IngressRule struct {
   911  	PortRange   PortRange `json:"port-range"`
   912  	SourceCIDRs []string  `json:"source-cidrs"`
   913  }
   914  
   915  // APIHostPortsResult holds the result of an APIHostPorts
   916  // call. Each element in the top level slice holds
   917  // the addresses for one API server.
   918  type APIHostPortsResult struct {
   919  	Servers [][]HostPort `json:"servers"`
   920  }
   921  
   922  // MachineHostsPorts transforms the APIHostPortsResult into a slice of
   923  // MachineHostPorts.
   924  func (r APIHostPortsResult) MachineHostsPorts() []network.MachineHostPorts {
   925  	return ToMachineHostsPorts(r.Servers)
   926  }
   927  
   928  // ZoneResult holds the result of an API call that returns an
   929  // availability zone name and whether it's available for use.
   930  type ZoneResult struct {
   931  	Error     *Error `json:"error,omitempty"`
   932  	Name      string `json:"name"`
   933  	Available bool   `json:"available"`
   934  }
   935  
   936  // ZoneResults holds multiple ZoneResult results
   937  type ZoneResults struct {
   938  	Results []ZoneResult `json:"results"`
   939  }
   940  
   941  // SpaceResult holds a single space tag or an error.
   942  type SpaceResult struct {
   943  	Error *Error `json:"error,omitempty"`
   944  	Tag   string `json:"tag"`
   945  }
   946  
   947  // SpaceResults holds the bulk operation result of an API call
   948  // that returns space tags or an errors.
   949  type SpaceResults struct {
   950  	Results []SpaceResult `json:"results"`
   951  }
   952  
   953  // RemoveSpaceParam holds a single space tag and whether it should be forced.
   954  type RemoveSpaceParam struct {
   955  	Space Entity `json:"space"`
   956  	// Force specifies whether the space removal will be forced, even if existing bindings, constraints or configurations are found.
   957  	Force bool `json:"force,omitempty"`
   958  	// DryRun specifies whether this command should only be run to return which constraints, bindings and configs are using given space.
   959  	// Without applying the remove operations.
   960  	DryRun bool `json:"dry-run,omitempty"`
   961  }
   962  
   963  // RemoveSpaceParams holds a single space tag and whether it should be forced.
   964  type RemoveSpaceParams struct {
   965  	SpaceParams []RemoveSpaceParam `json:"space-param"`
   966  }
   967  
   968  // RemoveSpaceResults contains multiple RemoveSpace results.
   969  type RemoveSpaceResults struct {
   970  	Results []RemoveSpaceResult `json:"results"`
   971  }
   972  
   973  // RemoveSpaceResult contains entries if removing a space is not possible.
   974  // Constraints are a slice of entities which has constraints on the space.
   975  // Bindings are a slice of entities which has bindings on that space.
   976  // Error is filled if an error has occurred which is unexpected.
   977  type RemoveSpaceResult struct {
   978  	Constraints        []Entity `json:"constraints,omitempty"`
   979  	Bindings           []Entity `json:"bindings,omitempty"`
   980  	ControllerSettings []string `json:"controller-settings,omitempty"`
   981  	Error              *Error   `json:"error,omitempty"`
   982  }
   983  
   984  // ListSubnetsResults holds the result of a ListSubnets API call.
   985  type ListSubnetsResults struct {
   986  	Results []Subnet `json:"results"`
   987  }
   988  
   989  // SubnetsFilters holds an optional SpaceTag and Zone for filtering
   990  // the subnets returned by a ListSubnets call.
   991  type SubnetsFilters struct {
   992  	SpaceTag string `json:"space-tag,omitempty"`
   993  	Zone     string `json:"zone,omitempty"`
   994  }
   995  
   996  // AddSubnetsParams holds the arguments of AddSubnets API call.
   997  type AddSubnetsParams struct {
   998  	Subnets []AddSubnetParams `json:"subnets"`
   999  }
  1000  
  1001  // AddSubnetParams holds a cidr and space tags, subnet provider ID,
  1002  // and a list of zones to associate the subnet to. Either SubnetTag or
  1003  // SubnetProviderId must be set, but not both. Zones can be empty if
  1004  // they can be discovered
  1005  type AddSubnetParams struct {
  1006  	CIDR              string   `json:"cidr,omitempty"`
  1007  	SubnetProviderId  string   `json:"subnet-provider-id,omitempty"`
  1008  	ProviderNetworkId string   `json:"provider-network-id,omitempty"`
  1009  	SpaceTag          string   `json:"space-tag"`
  1010  	VLANTag           int      `json:"vlan-tag,omitempty"`
  1011  	Zones             []string `json:"zones,omitempty"`
  1012  }
  1013  
  1014  // CreateSubnetsParams holds the arguments of CreateSubnets API call.
  1015  type CreateSubnetsParams struct {
  1016  	Subnets []CreateSubnetParams `json:"subnets"`
  1017  }
  1018  
  1019  // CreateSubnetParams holds a subnet and space tags, vlan tag,
  1020  // and a list of zones to associate the subnet to.
  1021  type CreateSubnetParams struct {
  1022  	SubnetTag string   `json:"subnet-tag,omitempty"`
  1023  	SpaceTag  string   `json:"space-tag"`
  1024  	Zones     []string `json:"zones,omitempty"`
  1025  	VLANTag   int      `json:"vlan-tag,omitempty"`
  1026  	IsPublic  bool     `json:"is-public"`
  1027  }
  1028  
  1029  // RenameSpaceParams holds params to rename a space.
  1030  // A `from` and `to` space tag.
  1031  type RenameSpaceParams struct {
  1032  	FromSpaceTag string `json:"from-space-tag"`
  1033  	ToSpaceTag   string `json:"to-space-tag"`
  1034  }
  1035  
  1036  // RenameSpacesParams holds the arguments of the RenameSpaces API call.
  1037  type RenameSpacesParams struct {
  1038  	Changes []RenameSpaceParams `json:"changes"`
  1039  }
  1040  
  1041  // CreateSpacesParams holds the arguments of the AddSpaces API call.
  1042  type CreateSpacesParams struct {
  1043  	Spaces []CreateSpaceParams `json:"spaces"`
  1044  }
  1045  
  1046  // CreateSpaceParams holds the space tag and at least one subnet
  1047  // tag required to create a new space.
  1048  type CreateSpaceParams struct {
  1049  	CIDRs      []string `json:"cidrs"`
  1050  	SpaceTag   string   `json:"space-tag"`
  1051  	Public     bool     `json:"public"`
  1052  	ProviderId string   `json:"provider-id,omitempty"`
  1053  }
  1054  
  1055  // MoveSubnetsParam contains the information required to
  1056  // move a collection of subnets into a space.
  1057  type MoveSubnetsParam struct {
  1058  	// SubnetTags identifies the subnets to move.
  1059  	SubnetTags []string `json:"subnets"`
  1060  
  1061  	// SpaceTag identifies the space that the subnets will move to.
  1062  	SpaceTag string `json:"space-tag"`
  1063  
  1064  	// Force, when true, moves the subnets despite existing constraints that
  1065  	// might be violated by such a topology change.
  1066  	Force bool `json:"force"`
  1067  }
  1068  
  1069  // MoveSubnetsParams contains the arguments of MoveSubnets API call.
  1070  type MoveSubnetsParams struct {
  1071  	Args []MoveSubnetsParam `json:"args"`
  1072  }
  1073  
  1074  // MovedSubnet represents the prior state of a relocated subnet.
  1075  type MovedSubnet struct {
  1076  	// SubnetTag identifies the subnet that was moved.
  1077  	SubnetTag string `json:"subnet"`
  1078  
  1079  	// OldSpaceTag identifies the space that the subnet was in before being
  1080  	// successfully moved.
  1081  	OldSpaceTag string `json:"old-space"`
  1082  
  1083  	// CIDR identifies the moved CIDR in the subnet move.
  1084  	CIDR string `json:"cidr"`
  1085  }
  1086  
  1087  // MoveSubnetsResult contains the result of moving
  1088  // a collection of subnets into a new space.
  1089  type MoveSubnetsResult struct {
  1090  	// MovedSubnets contains the prior state of relocated subnets.
  1091  	MovedSubnets []MovedSubnet `json:"moved-subnets,omitempty"`
  1092  
  1093  	// NewSpaceTag identifies the space that the the subnets were moved to.
  1094  	// It is intended to facilitate from/to confirmation messages without
  1095  	// clients needing to match up parameters with results.
  1096  	NewSpaceTag string `json:"new-space"`
  1097  
  1098  	// Error will be non-nil if the subnets could not be moved.
  1099  	Error *Error `json:"error,omitempty"`
  1100  }
  1101  
  1102  // MoveSubnetsResults contains the results of a call to MoveSubnets.
  1103  type MoveSubnetsResults struct {
  1104  	Results []MoveSubnetsResult `json:"results"`
  1105  }
  1106  
  1107  // ShowSpaceResult holds the list of all available spaces.
  1108  type ShowSpaceResult struct {
  1109  	// Information about a given space.
  1110  	Space Space `json:"space"`
  1111  	// Application names which are bound to a given space.
  1112  	Applications []string `json:"applications"`
  1113  	// MachineCount is the number of machines connected to a given space.
  1114  	MachineCount int    `json:"machine-count"`
  1115  	Error        *Error `json:"error,omitempty"`
  1116  }
  1117  
  1118  // ShowSpaceResults holds the list of all available spaces.
  1119  type ShowSpaceResults struct {
  1120  	Results []ShowSpaceResult `json:"results"`
  1121  }
  1122  
  1123  // ListSpacesResults holds the list of all available spaces.
  1124  type ListSpacesResults struct {
  1125  	Results []Space `json:"results"`
  1126  }
  1127  
  1128  // Space holds the information about a single space and its associated subnets.
  1129  type Space struct {
  1130  	Id      string   `json:"id"`
  1131  	Name    string   `json:"name"`
  1132  	Subnets []Subnet `json:"subnets"`
  1133  	Error   *Error   `json:"error,omitempty"`
  1134  }
  1135  
  1136  // ProviderSpace holds the information about a single space and its associated subnets.
  1137  type ProviderSpace struct {
  1138  	Name       string   `json:"name"`
  1139  	ProviderId string   `json:"provider-id"`
  1140  	Subnets    []Subnet `json:"subnets"`
  1141  	Error      *Error   `json:"error,omitempty"`
  1142  }
  1143  
  1144  type ProxyConfig struct {
  1145  	HTTP    string `json:"http"`
  1146  	HTTPS   string `json:"https"`
  1147  	FTP     string `json:"ftp"`
  1148  	NoProxy string `json:"no-proxy"`
  1149  }
  1150  
  1151  // ProxyConfigResult contains information needed to configure a clients proxy settings
  1152  type ProxyConfigResult struct {
  1153  	LegacyProxySettings      ProxyConfig `json:"legacy-proxy-settings"`
  1154  	JujuProxySettings        ProxyConfig `json:"juju-proxy-settings"`
  1155  	APTProxySettings         ProxyConfig `json:"apt-proxy-settings,omitempty"`
  1156  	SnapProxySettings        ProxyConfig `json:"snap-proxy-settings,omitempty"`
  1157  	SnapStoreProxyId         string      `json:"snap-store-id,omitempty"`
  1158  	SnapStoreProxyAssertions string      `json:"snap-store-assertions,omitempty"`
  1159  	SnapStoreProxyURL        string      `json:"snap-store-proxy-url,omitempty"`
  1160  	AptMirror                string      `json:"apt-mirror,omitempty"`
  1161  	Error                    *Error      `json:"error,omitempty"`
  1162  }
  1163  
  1164  // ProxyConfigResults contains information needed to configure multiple clients proxy settings
  1165  type ProxyConfigResults struct {
  1166  	Results []ProxyConfigResult `json:"results"`
  1167  }
  1168  
  1169  // ProxyConfigResultV1 contains information needed to configure a clients proxy settings.
  1170  // Result for facade v1 call.
  1171  type ProxyConfigResultV1 struct {
  1172  	ProxySettings    ProxyConfig `json:"proxy-settings"`
  1173  	APTProxySettings ProxyConfig `json:"apt-proxy-settings"`
  1174  	Error            *Error      `json:"error,omitempty"`
  1175  }
  1176  
  1177  // ProxyConfigResultsV1 contains information needed to configure multiple clients proxy settings.
  1178  // Result for facade v1 call.
  1179  type ProxyConfigResultsV1 struct {
  1180  	Results []ProxyConfigResultV1 `json:"results"`
  1181  }
  1182  
  1183  // InterfaceAddress represents a single address attached to the interface.
  1184  // The serialization is different between json and yaml because of accidental
  1185  // differences in the past, but should be preserved for compatibility
  1186  type InterfaceAddress struct {
  1187  	Hostname string `json:"hostname" yaml:"hostname"`
  1188  	Address  string `json:"value" yaml:"address"`
  1189  	CIDR     string `json:"cidr" yaml:"cidr"`
  1190  }
  1191  
  1192  // NetworkInfo describes one interface with IP addresses.
  1193  // The serialization is different between json and yaml because of accidental
  1194  // differences in the past, but should be preserved for compatibility
  1195  type NetworkInfo struct {
  1196  	// MACAddress is the network interface's hardware MAC address
  1197  	// (e.g. "aa:bb:cc:dd:ee:ff").
  1198  	MACAddress string `json:"mac-address" yaml:"macaddress"`
  1199  
  1200  	// InterfaceName is the raw OS-specific network device name (e.g.
  1201  	// "eth1", even for a VLAN eth1.42 virtual interface).
  1202  	InterfaceName string `json:"interface-name" yaml:"interfacename"`
  1203  
  1204  	// Addresses contains a list of addresses configured on the interface.
  1205  	Addresses []InterfaceAddress `json:"addresses" yaml:"addresses"`
  1206  }
  1207  
  1208  // NetworkInfoResult Adds egress and ingress subnets and changes the serialized
  1209  // `Info` key name in the yaml/json API protocol.
  1210  type NetworkInfoResult struct {
  1211  	Error            *Error        `json:"error,omitempty" yaml:"error,omitempty"`
  1212  	Info             []NetworkInfo `json:"bind-addresses,omitempty" yaml:"bind-addresses,omitempty"`
  1213  	EgressSubnets    []string      `json:"egress-subnets,omitempty" yaml:"egress-subnets,omitempty"`
  1214  	IngressAddresses []string      `json:"ingress-addresses,omitempty" yaml:"ingress-addresses,omitempty"`
  1215  }
  1216  
  1217  // NetworkInfoResults holds a mapping from binding name to NetworkInfoResult.
  1218  type NetworkInfoResults struct {
  1219  	Results map[string]NetworkInfoResult `json:"results"`
  1220  }
  1221  
  1222  // NetworkInfoParams holds a name of the unit and list of bindings for which we want to get NetworkInfos.
  1223  type NetworkInfoParams struct {
  1224  	Unit       string `json:"unit"`
  1225  	RelationId *int   `json:"relation-id,omitempty"`
  1226  	// TODO (manadart 2019-10-28): The name of this member was changed to
  1227  	// better indicate what it is, but the encoded name was left as-is to
  1228  	// avoid the need for facade schema regeneration.
  1229  	// Change it to "endpoints" if bumping the facade version for another
  1230  	// purpose.
  1231  	Endpoints []string `json:"bindings"`
  1232  }
  1233  
  1234  // FanConfigEntry holds configuration for a single fan.
  1235  type FanConfigEntry struct {
  1236  	Underlay string `json:"underlay"`
  1237  	Overlay  string `json:"overlay"`
  1238  }
  1239  
  1240  // FanConfigResult holds configuration for all fans in a model.
  1241  type FanConfigResult struct {
  1242  	Fans []FanConfigEntry `json:"fans"`
  1243  }
  1244  
  1245  // CIDRParams contains a slice of subnet CIDRs used for querying subnets.
  1246  type CIDRParams struct {
  1247  	CIDRS []string `json:"cidrs"`
  1248  }
  1249  
  1250  // SubnetsResult contains a collection of subnets or an error.
  1251  type SubnetsResult struct {
  1252  	Subnets []SubnetV2 `json:"subnets,omitempty"`
  1253  	Error   *Error     `json:"error,omitempty"`
  1254  }
  1255  
  1256  // SubnetsResults contains a collection of subnets results.
  1257  type SubnetsResults struct {
  1258  	Results []SubnetsResult `json:"results"`
  1259  }
  1260  
  1261  // SpaceInfosParams provides the arguments for a SpaceInfos call.
  1262  type SpaceInfosParams struct {
  1263  	// A list of space IDs for filtering the returned set of results. If
  1264  	// empty, all spaces will be returned.
  1265  	FilterBySpaceIDs []string `json:"space-ids,omitempty"`
  1266  }
  1267  
  1268  // SpaceInfos represents the result of a SpaceInfos API call.
  1269  type SpaceInfos struct {
  1270  	Infos []SpaceInfo `json:"space-infos,omitempty"`
  1271  }
  1272  
  1273  // SpaceInfo describes a space and its subnets.
  1274  type SpaceInfo struct {
  1275  	ID         string     `json:"id"`
  1276  	Name       string     `json:"name"`
  1277  	ProviderID string     `json:"provider-id,omitempty"`
  1278  	Subnets    []SubnetV3 `json:"subnets,omitempty"`
  1279  }
  1280  
  1281  // FromNetworkSpaceInfos converts a network.SpaceInfos into a serializable
  1282  // payload that can be sent over the wire.
  1283  func FromNetworkSpaceInfos(allInfos network.SpaceInfos) SpaceInfos {
  1284  	res := SpaceInfos{
  1285  		Infos: make([]SpaceInfo, len(allInfos)),
  1286  	}
  1287  
  1288  	for i, si := range allInfos {
  1289  		mappedSubnets := make([]SubnetV3, len(si.Subnets))
  1290  		for j, subnetInfo := range si.Subnets {
  1291  			var mappedFanInfo *FanConfigEntry
  1292  			if subnetInfo.FanInfo != nil {
  1293  				mappedFanInfo = &FanConfigEntry{
  1294  					Underlay: subnetInfo.FanInfo.FanLocalUnderlay,
  1295  					Overlay:  subnetInfo.FanInfo.FanOverlay,
  1296  				}
  1297  			}
  1298  
  1299  			mappedSubnets[j] = SubnetV3{
  1300  				SpaceID:  subnetInfo.SpaceID,
  1301  				FanInfo:  mappedFanInfo,
  1302  				IsPublic: subnetInfo.IsPublic,
  1303  
  1304  				SubnetV2: SubnetV2{
  1305  					ID: string(subnetInfo.ID),
  1306  					Subnet: Subnet{
  1307  						CIDR:              subnetInfo.CIDR,
  1308  						ProviderId:        string(subnetInfo.ProviderId),
  1309  						ProviderNetworkId: string(subnetInfo.ProviderNetworkId),
  1310  						ProviderSpaceId:   string(subnetInfo.ProviderSpaceId),
  1311  						VLANTag:           subnetInfo.VLANTag,
  1312  						Zones:             subnetInfo.AvailabilityZones,
  1313  						// NOTE(achilleasa): the SpaceTag is not populated
  1314  						// as we can grab the space name from the parent
  1315  						// SpaceInfo when unmarshaling.
  1316  					},
  1317  				},
  1318  			}
  1319  		}
  1320  
  1321  		res.Infos[i] = SpaceInfo{
  1322  			ID:         si.ID,
  1323  			Name:       string(si.Name),
  1324  			ProviderID: string(si.ProviderId),
  1325  			Subnets:    mappedSubnets,
  1326  		}
  1327  	}
  1328  
  1329  	return res
  1330  }
  1331  
  1332  // ToNetworkSpaceInfos converts a serializable SpaceInfos payload into a
  1333  // network.SpaceInfos instance.
  1334  func ToNetworkSpaceInfos(allInfos SpaceInfos) network.SpaceInfos {
  1335  	res := make(network.SpaceInfos, len(allInfos.Infos))
  1336  
  1337  	for i, si := range allInfos.Infos {
  1338  		mappedSubnets := make(network.SubnetInfos, len(si.Subnets))
  1339  		for j, subnetInfo := range si.Subnets {
  1340  			mappedSubnets[j] = network.SubnetInfo{
  1341  				ID:                network.Id(subnetInfo.ID),
  1342  				CIDR:              subnetInfo.CIDR,
  1343  				ProviderId:        network.Id(subnetInfo.ProviderId),
  1344  				ProviderSpaceId:   network.Id(subnetInfo.ProviderSpaceId),
  1345  				ProviderNetworkId: network.Id(subnetInfo.ProviderNetworkId),
  1346  				VLANTag:           subnetInfo.VLANTag,
  1347  				AvailabilityZones: subnetInfo.Zones,
  1348  				SpaceID:           subnetInfo.SpaceID,
  1349  				IsPublic:          subnetInfo.IsPublic,
  1350  				SpaceName:         si.Name,
  1351  			}
  1352  
  1353  			if subnetInfo.FanInfo != nil {
  1354  				mappedSubnets[j].SetFan(subnetInfo.FanInfo.Underlay, subnetInfo.FanInfo.Overlay)
  1355  			}
  1356  		}
  1357  
  1358  		res[i] = network.SpaceInfo{
  1359  			ID:         si.ID,
  1360  			Name:       network.SpaceName(si.Name),
  1361  			ProviderId: network.Id(si.ProviderID),
  1362  			Subnets:    mappedSubnets,
  1363  		}
  1364  	}
  1365  
  1366  	return res
  1367  }