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 }