github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/azure/environ_network_test.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package azure_test
     5  
     6  import (
     7  	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
     8  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
     9  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/core/instance"
    14  	corenetwork "github.com/juju/juju/core/network"
    15  	"github.com/juju/juju/environs"
    16  	"github.com/juju/juju/provider/azure/internal/azuretesting"
    17  )
    18  
    19  func (s *environSuite) TestSubnetsInstanceIDError(c *gc.C) {
    20  	env := s.openEnviron(c)
    21  
    22  	netEnv, ok := environs.SupportsNetworking(env)
    23  	c.Assert(ok, jc.IsTrue)
    24  
    25  	_, err := netEnv.Subnets(s.callCtx, "some-ID", nil)
    26  	c.Assert(err, jc.Satisfies, errors.IsNotSupported)
    27  }
    28  
    29  func (s *environSuite) TestSubnetsSuccess(c *gc.C) {
    30  	env := s.openEnviron(c)
    31  
    32  	// We wait for common resource creation, then query subnets
    33  	// in the default virtual network created for every model.
    34  	s.sender = azuretesting.Senders{
    35  		makeSender("/deployments/common", s.commonDeployment),
    36  		makeSender("/virtualNetworks/juju-internal-network/subnets", armnetwork.SubnetListResult{
    37  			Value: []*armnetwork.Subnet{
    38  				{
    39  					ID: to.Ptr("provider-sub-id"),
    40  					Properties: &armnetwork.SubnetPropertiesFormat{
    41  						AddressPrefix: to.Ptr("10.0.0.0/24"),
    42  					},
    43  				},
    44  				{
    45  					// Result without an address prefix is ignored.
    46  					Properties: &armnetwork.SubnetPropertiesFormat{},
    47  				},
    48  			},
    49  		}),
    50  	}
    51  
    52  	netEnv, ok := environs.SupportsNetworking(env)
    53  	c.Assert(ok, jc.IsTrue)
    54  
    55  	subs, err := netEnv.Subnets(s.callCtx, instance.UnknownId, nil)
    56  	c.Assert(err, jc.ErrorIsNil)
    57  
    58  	c.Assert(subs, gc.HasLen, 1)
    59  	c.Check(subs[0].ProviderId, gc.Equals, corenetwork.Id("provider-sub-id"))
    60  	c.Check(subs[0].CIDR, gc.Equals, "10.0.0.0/24")
    61  }
    62  
    63  func (s *environSuite) TestNetworkInterfacesSuccess(c *gc.C) {
    64  	env := s.openEnviron(c)
    65  
    66  	// We wait for common resource creation, then query subnets
    67  	// in the default virtual network created for every model.
    68  	s.sender = azuretesting.Senders{
    69  		makeSender("/deployments/common", s.commonDeployment),
    70  		makeSender("/virtualNetworks/juju-internal-network/subnets", armnetwork.SubnetListResult{
    71  			Value: []*armnetwork.Subnet{
    72  				{
    73  					ID: to.Ptr("subnet-42"),
    74  					Properties: &armnetwork.SubnetPropertiesFormat{
    75  						AddressPrefix: to.Ptr("10.0.0.0/24"),
    76  					},
    77  				},
    78  				{
    79  					ID: to.Ptr("subnet-665"),
    80  					Properties: &armnetwork.SubnetPropertiesFormat{
    81  						AddressPrefix: to.Ptr("172.0.0.0/24"),
    82  					},
    83  				},
    84  			},
    85  		}),
    86  		makeSender(".*/networkInterfaces", armnetwork.InterfaceListResult{
    87  			Value: []*armnetwork.Interface{
    88  				{
    89  					ID: to.Ptr("az-nic-0"),
    90  					Properties: &armnetwork.InterfacePropertiesFormat{
    91  						Primary:    to.Ptr(true),
    92  						MacAddress: to.Ptr("AA-BB-CC-DD-EE-FF"), // azure reports MACs in this format; they are normalized internally
    93  						IPConfigurations: []*armnetwork.InterfaceIPConfiguration{
    94  							{
    95  								Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
    96  									PrivateIPAddress:          to.Ptr("10.0.0.42"),
    97  									PrivateIPAllocationMethod: to.Ptr(armnetwork.IPAllocationMethodDynamic),
    98  									Subnet: &armnetwork.Subnet{
    99  										ID: to.Ptr("subnet-42"), // should match one of values returned by the Subnets() call
   100  									},
   101  									Primary: to.Ptr(false),
   102  								},
   103  							},
   104  							{
   105  								Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
   106  									PrivateIPAddress:          to.Ptr("172.0.0.99"),
   107  									PrivateIPAllocationMethod: to.Ptr(armnetwork.IPAllocationMethodStatic),
   108  									Subnet: &armnetwork.Subnet{
   109  										ID: to.Ptr("subnet-665"), // should match one of values returned by the Subnets() call
   110  									},
   111  									// This is the primary address for the NIC and should appear first in the mapped interface.
   112  									Primary: to.Ptr(true),
   113  									PublicIPAddress: &armnetwork.PublicIPAddress{
   114  										ID: to.Ptr("bogus"), // should be ignored
   115  									},
   116  								},
   117  							},
   118  						},
   119  					},
   120  					Tags: map[string]*string{
   121  						"juju-machine-name": to.Ptr("machine-0"),
   122  					},
   123  				},
   124  				{
   125  					ID: to.Ptr("az-nic-1"),
   126  					Properties: &armnetwork.InterfacePropertiesFormat{
   127  						Primary:    to.Ptr(true),
   128  						MacAddress: to.Ptr("BA-D0-C0-FF-EE-42"), // azure reports MACs in this format; they are normalized internally
   129  						IPConfigurations: []*armnetwork.InterfaceIPConfiguration{
   130  							{
   131  								Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
   132  									Subnet: &armnetwork.Subnet{
   133  										ID: to.Ptr("subnet-42"), // should match one of values returned by the Subnets() call
   134  									},
   135  									PublicIPAddress: &armnetwork.PublicIPAddress{
   136  										ID: to.Ptr("az-ip-1"),
   137  									},
   138  									Primary: to.Ptr(true),
   139  								},
   140  							},
   141  						},
   142  					},
   143  					Tags: map[string]*string{
   144  						"juju-machine-name": to.Ptr("machine-0"),
   145  					},
   146  				},
   147  			},
   148  		}),
   149  		makeSender(".*/publicIPAddresses", armnetwork.PublicIPAddressListResult{
   150  			Value: []*armnetwork.PublicIPAddress{
   151  				{
   152  					ID: to.Ptr("az-ip-0"),
   153  					Properties: &armnetwork.PublicIPAddressPropertiesFormat{
   154  						PublicIPAllocationMethod: to.Ptr(armnetwork.IPAllocationMethodStatic),
   155  						IPAddress:                to.Ptr("20.30.40.50"),
   156  					},
   157  				},
   158  				{
   159  					ID: to.Ptr("az-ip-1"),
   160  					Properties: &armnetwork.PublicIPAddressPropertiesFormat{
   161  						PublicIPAllocationMethod: to.Ptr(armnetwork.IPAllocationMethodDynamic),
   162  						IPAddress:                to.Ptr("1.2.3.4"),
   163  					},
   164  				},
   165  			},
   166  		}),
   167  	}
   168  
   169  	netEnv, ok := environs.SupportsNetworking(env)
   170  	c.Assert(ok, jc.IsTrue)
   171  
   172  	res, err := netEnv.NetworkInterfaces(s.callCtx, []instance.Id{"machine-0"})
   173  	c.Assert(err, jc.ErrorIsNil)
   174  
   175  	c.Assert(res, gc.HasLen, 1)
   176  	c.Assert(res[0], gc.HasLen, 2, gc.Commentf("expected to get 2 NICs for machine-0"))
   177  
   178  	nic0 := res[0][0]
   179  	c.Assert(nic0.InterfaceType, gc.Equals, corenetwork.EthernetDevice)
   180  	c.Assert(nic0.Origin, gc.Equals, corenetwork.OriginProvider)
   181  	c.Assert(nic0.MACAddress, gc.Equals, "aa:bb:cc:dd:ee:ff")
   182  	c.Assert(nic0.Addresses, gc.DeepEquals, corenetwork.ProviderAddresses{
   183  		// The primary IP address for the NIC should appear first.
   184  		corenetwork.NewMachineAddress(
   185  			"172.0.0.99",
   186  			corenetwork.WithCIDR("172.0.0.0/24"),
   187  			corenetwork.WithScope(corenetwork.ScopeCloudLocal),
   188  			corenetwork.WithConfigType(corenetwork.ConfigStatic),
   189  		).AsProviderAddress(),
   190  		corenetwork.NewMachineAddress(
   191  			"10.0.0.42",
   192  			corenetwork.WithCIDR("10.0.0.0/24"),
   193  			corenetwork.WithScope(corenetwork.ScopeCloudLocal),
   194  			corenetwork.WithConfigType(corenetwork.ConfigDHCP),
   195  		).AsProviderAddress(),
   196  	})
   197  	c.Assert(nic0.ShadowAddresses, gc.HasLen, 0)
   198  	c.Assert(nic0.ProviderId, gc.Equals, corenetwork.Id("az-nic-0"))
   199  	c.Assert(nic0.ProviderSubnetId, gc.Equals, corenetwork.Id("subnet-665"), gc.Commentf("expected NIC to use the provider subnet ID for the primary NIC address"))
   200  	c.Assert(nic0.ConfigType, gc.Equals, corenetwork.ConfigStatic, gc.Commentf("expected NIC to use the config type for the primary NIC address"))
   201  
   202  	nic1 := res[0][1]
   203  	c.Assert(nic1.InterfaceType, gc.Equals, corenetwork.EthernetDevice)
   204  	c.Assert(nic1.Origin, gc.Equals, corenetwork.OriginProvider)
   205  	c.Assert(nic1.MACAddress, gc.Equals, "ba:d0:c0:ff:ee:42")
   206  	c.Assert(nic1.Addresses, gc.HasLen, 0)
   207  	c.Assert(nic1.ShadowAddresses, gc.DeepEquals, corenetwork.ProviderAddresses{
   208  		corenetwork.NewMachineAddress(
   209  			"1.2.3.4",
   210  			corenetwork.WithScope(corenetwork.ScopePublic),
   211  			corenetwork.WithConfigType(corenetwork.ConfigDHCP),
   212  		).AsProviderAddress(),
   213  	}, gc.Commentf("expected public address to be also included in the shadow addresses list"))
   214  	c.Assert(nic1.ProviderId, gc.Equals, corenetwork.Id("az-nic-1"))
   215  	c.Assert(nic1.ConfigType, gc.Equals, corenetwork.ConfigDHCP, gc.Commentf("expected NIC to use the config type for the primary NIC address"))
   216  }
   217  
   218  func (s *environSuite) TestNetworkInterfacesPartialMatch(c *gc.C) {
   219  	env := s.openEnviron(c)
   220  
   221  	// We wait for common resource creation, then query subnets
   222  	// in the default virtual network created for every model.
   223  	s.sender = azuretesting.Senders{
   224  		makeSender("/deployments/common", s.commonDeployment),
   225  		makeSender("/virtualNetworks/juju-internal-network/subnets", armnetwork.SubnetListResult{
   226  			Value: []*armnetwork.Subnet{},
   227  		}),
   228  		makeSender(".*/networkInterfaces", armnetwork.InterfaceListResult{
   229  			Value: []*armnetwork.Interface{
   230  				{
   231  					ID: to.Ptr("az-nic-0"),
   232  					Properties: &armnetwork.InterfacePropertiesFormat{
   233  						Primary:    to.Ptr(true),
   234  						MacAddress: to.Ptr("AA-BB-CC-DD-EE-FF"), // azure reports MACs in this format; they are normalized internally
   235  					},
   236  					Tags: map[string]*string{
   237  						"juju-machine-name": to.Ptr("machine-0"),
   238  					},
   239  				},
   240  			},
   241  		}),
   242  		makeSender(".*/publicIPAddresses", armnetwork.PublicIPAddressListResult{}),
   243  	}
   244  
   245  	netEnv, ok := environs.SupportsNetworking(env)
   246  	c.Assert(ok, jc.IsTrue)
   247  
   248  	res, err := netEnv.NetworkInterfaces(s.callCtx, []instance.Id{"machine-0", "bogus-0"})
   249  	c.Assert(err, gc.Equals, environs.ErrPartialInstances)
   250  
   251  	c.Assert(res, gc.HasLen, 2)
   252  	c.Assert(res[0], gc.HasLen, 1, gc.Commentf("expected to get 1 NIC for machine-0"))
   253  	c.Assert(res[1], gc.IsNil, gc.Commentf("expected a nil slice for non-matched machines"))
   254  }