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  }