github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/equinix/environ_network_test.go (about) 1 // Copyright 2021 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package equinix 5 6 import ( 7 "net/http" 8 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 "github.com/packethost/packngo" 12 "go.uber.org/mock/gomock" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/core/instance" 16 "github.com/juju/juju/environs" 17 environscloudspec "github.com/juju/juju/environs/cloudspec" 18 "github.com/juju/juju/environs/context" 19 envtesting "github.com/juju/juju/environs/testing" 20 "github.com/juju/juju/provider/equinix/mocks" 21 ) 22 23 type networkSuite struct { 24 testing.IsolationSuite 25 provider environs.EnvironProvider 26 spec environscloudspec.CloudSpec 27 } 28 29 var _ = gc.Suite(&networkSuite{}) 30 31 func (s *networkSuite) SetUpTest(c *gc.C) { 32 s.IsolationSuite.SetUpTest(c) 33 s.provider = NewProvider() 34 s.spec = environscloudspec.CloudSpec{ 35 Type: "equnix", 36 Name: "equnix metal", 37 Region: "am", 38 Endpoint: "https://api.packet.net/", 39 Credential: fakeServicePrincipalCredential(), 40 } 41 } 42 43 func (s *networkSuite) TestListIPsByProjectIDAndRegion(c *gc.C) { 44 cntrl := gomock.NewController(c) 45 projectIP := mocks.NewMockProjectIPService(cntrl) 46 projectIP.EXPECT().List(gomock.Eq("12345c2a-6789-4d4f-a3c4-7367d6b7cca8"), &packngo.ListOptions{ 47 Includes: []string{"available_in_metros"}, 48 }).Times(1).Return([]packngo.IPAddressReservation{ 49 { 50 Facility: &packngo.Facility{ 51 Metro: &packngo.Metro{ 52 Code: "am", 53 }, 54 }, 55 IpAddressCommon: packngo.IpAddressCommon{ 56 ID: "100", 57 Address: "147.75.81.53", 58 Gateway: "147.75.81.52", 59 Network: "147.75.81.52", 60 AddressFamily: 4, 61 Netmask: "255.255.255.254", 62 Public: true, 63 CIDR: 31, 64 Management: true, 65 Manageable: true, 66 Global: false, 67 Metro: &packngo.Metro{ 68 Code: "am", 69 }, 70 }, 71 }, 72 { 73 Facility: &packngo.Facility{ 74 Metro: &packngo.Metro{ 75 Code: "to", 76 }, 77 }, 78 IpAddressCommon: packngo.IpAddressCommon{ 79 ID: "106", 80 Address: "2604:1380:2000:9d00::3", 81 Gateway: "2604:1380:2000:9d00::2", 82 Network: "2604:1380:2000:9d00::2", 83 AddressFamily: 6, 84 Netmask: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe", 85 Public: true, 86 CIDR: 127, 87 Management: true, 88 Manageable: true, 89 Global: false, 90 Metro: &packngo.Metro{ 91 Code: "to", 92 }, 93 }, 94 }, 95 }, &packngo.Response{}, nil) 96 s.PatchValue(&equinixClient, func(spec environscloudspec.CloudSpec) *packngo.Client { 97 cl := &packngo.Client{} 98 cl.ProjectIPs = projectIP 99 return cl 100 }) 101 ctx := envtesting.BootstrapTODOContext(c) 102 env, err := environs.Open(ctx.Context(), s.provider, environs.OpenParams{ 103 Cloud: s.spec, 104 Config: makeTestModelConfig(c), 105 }) 106 c.Assert(err, jc.ErrorIsNil) 107 c.Assert(env, gc.NotNil) 108 netEnviron, _ := env.(*environ) 109 ips, err := netEnviron.listIPsByProjectIDAndRegion("12345c2a-6789-4d4f-a3c4-7367d6b7cca8", netEnviron.cloud.Region) 110 c.Assert(err, jc.ErrorIsNil) 111 c.Assert(len(ips), jc.DeepEquals, 1) 112 } 113 114 func (s *networkSuite) TestNetworkInterfaces(c *gc.C) { 115 cntrl := gomock.NewController(c) 116 defer cntrl.Finish() 117 device := mocks.NewMockDeviceService(cntrl) 118 device.EXPECT().Get(gomock.Eq("100"), nil).Times(2).Return(&packngo.Device{ 119 ID: "100", 120 Tags: []string{"juju-model-uuid=deadbeef-0bad-400d-8000-4b1d0d06f00d"}, 121 Network: []*packngo.IPAddressAssignment{ 122 { 123 IpAddressCommon: packngo.IpAddressCommon{ 124 ID: "100", 125 Address: "147.75.81.53", 126 Gateway: "147.75.81.52", 127 Network: "147.75.81.52", 128 AddressFamily: 4, 129 Netmask: "255.255.255.254", 130 Public: true, 131 CIDR: 31, 132 Management: true, 133 Manageable: true, 134 Global: false, 135 Metro: &packngo.Metro{ 136 Code: "am", 137 }, 138 }, 139 }, 140 { 141 IpAddressCommon: packngo.IpAddressCommon{ 142 ID: "106", 143 Address: "2604:1380:2000:9d00::3", 144 Gateway: "2604:1380:2000:9d00::2", 145 Network: "2604:1380:2000:9d00::2", 146 AddressFamily: 6, 147 Netmask: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe", 148 Public: true, 149 CIDR: 127, 150 Management: true, 151 Manageable: true, 152 Global: false, 153 Metro: &packngo.Metro{ 154 Code: "am", 155 }, 156 }, 157 }, 158 { 159 IpAddressCommon: packngo.IpAddressCommon{ 160 ID: "101", 161 Address: "10.80.96.3", 162 Gateway: "10.80.96.2", 163 Network: "10.80.96.2", 164 AddressFamily: 4, 165 Netmask: "255.255.255.254", 166 Public: false, 167 CIDR: 31, 168 Management: true, 169 Manageable: true, 170 Global: false, 171 Metro: &packngo.Metro{ 172 Code: "am", 173 }, 174 }, 175 }, 176 }, 177 NetworkPorts: []packngo.Port{ 178 { 179 ID: "200", 180 Name: "bond0", 181 Type: "NetworkBondPort", 182 Data: packngo.PortData{ 183 Bonded: true, 184 }, 185 DisbondOperationSupported: true, 186 NetworkType: "layer3", 187 }, 188 { 189 ID: "201", 190 Name: "eth0", 191 Type: "NetworkPort", 192 Data: packngo.PortData{ 193 Bonded: true, 194 MAC: "24:8a:07:e7:71:70", 195 }, 196 DisbondOperationSupported: true, 197 NetworkType: "layer3", 198 Bond: &packngo.BondData{ 199 ID: "200", 200 Name: "bond0", 201 }, 202 }, 203 { 204 ID: "202", 205 Name: "eth1", 206 Type: "NetworkPort", 207 Data: packngo.PortData{ 208 Bonded: true, 209 MAC: "24:8a:07:e7:71:71", 210 }, 211 DisbondOperationSupported: true, 212 NetworkType: "layer3", 213 Bond: &packngo.BondData{ 214 ID: "200", 215 Name: "bond0", 216 }, 217 }, 218 }, 219 }, &packngo.Response{ 220 Response: &http.Response{ 221 StatusCode: http.StatusOK, 222 }, 223 }, nil) 224 projectIP := mocks.NewMockProjectIPService(cntrl) 225 projectIP.EXPECT().List(gomock.Eq("12345c2a-6789-4d4f-a3c4-7367d6b7cca8"), &packngo.ListOptions{ 226 Includes: []string{"available_in_metros"}, 227 }).Times(1).Return([]packngo.IPAddressReservation{ 228 { 229 Facility: &packngo.Facility{ 230 Metro: &packngo.Metro{ 231 Code: "am", 232 }, 233 }, 234 IpAddressCommon: packngo.IpAddressCommon{ 235 ID: "100", 236 Address: "147.75.81.53", 237 Gateway: "147.75.81.52", 238 Network: "147.75.81.52", 239 AddressFamily: 4, 240 Netmask: "255.255.255.254", 241 Public: true, 242 CIDR: 31, 243 Management: true, 244 Manageable: true, 245 Global: false, 246 Metro: &packngo.Metro{ 247 Code: "am", 248 }, 249 }, 250 }, 251 { 252 Facility: &packngo.Facility{ 253 Metro: &packngo.Metro{ 254 Code: "am", 255 }, 256 }, 257 IpAddressCommon: packngo.IpAddressCommon{ 258 ID: "106", 259 Address: "2604:1380:2000:9d00::3", 260 Gateway: "2604:1380:2000:9d00::2", 261 Network: "2604:1380:2000:9d00::2", 262 AddressFamily: 6, 263 Netmask: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe", 264 Public: true, 265 CIDR: 127, 266 Management: true, 267 Manageable: true, 268 Global: false, 269 Metro: &packngo.Metro{ 270 Code: "am", 271 }, 272 }, 273 }, 274 { 275 Facility: &packngo.Facility{ 276 Metro: &packngo.Metro{ 277 Code: "am", 278 }, 279 }, 280 IpAddressCommon: packngo.IpAddressCommon{ 281 ID: "101", 282 Address: "10.80.96.3", 283 Gateway: "10.80.96.2", 284 Network: "10.80.96.2", 285 AddressFamily: 4, 286 Netmask: "255.255.255.254", 287 Public: false, 288 CIDR: 31, 289 Management: true, 290 Manageable: true, 291 Global: false, 292 Metro: &packngo.Metro{ 293 Code: "am", 294 }, 295 }, 296 }, 297 }, &packngo.Response{}, nil) 298 s.PatchValue(&equinixClient, func(spec environscloudspec.CloudSpec) *packngo.Client { 299 cl := &packngo.Client{} 300 cl.Devices = device 301 cl.ProjectIPs = projectIP 302 return cl 303 }) 304 ctx := envtesting.BootstrapTODOContext(c) 305 env, err := environs.Open(ctx.Context(), s.provider, environs.OpenParams{ 306 Cloud: s.spec, 307 Config: makeTestModelConfig(c), 308 }) 309 c.Assert(err, jc.ErrorIsNil) 310 c.Assert(env, gc.NotNil) 311 netEnviron, ok := env.(environs.NetworkingEnviron) 312 c.Assert(ok, jc.IsTrue, gc.Commentf("expected environ to implement environs.Networking")) 313 ii, err := netEnviron.NetworkInterfaces(&context.CloudCallContext{}, []instance.Id{"100"}) 314 c.Assert(err, jc.ErrorIsNil) 315 c.Assert(len(ii[0]), jc.DeepEquals, 3) 316 }