diff --git a/go.mod b/go.mod index c9b5938..abdaaf7 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/equinix/equinix-sdk-go v0.30.0 github.com/google/uuid v1.3.1 - github.com/packethost/packngo v0.30.0 + github.com/gorilla/mux v1.8.1 github.com/pallinder/go-randomdata v1.2.0 go.universe.tf/metallb v0.13.7 golang.org/x/exp v0.0.0-20231006140011-7918f672742d @@ -15,7 +15,6 @@ require ( k8s.io/client-go v0.26.10 k8s.io/cloud-provider v0.26.10 k8s.io/component-base v0.26.10 - k8s.io/klog v1.0.0 k8s.io/klog/v2 v2.100.1 k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 sigs.k8s.io/controller-runtime v0.14.7 diff --git a/go.sum b/go.sum index 09864ae..3051de0 100644 --- a/go.sum +++ b/go.sum @@ -92,8 +92,6 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -137,7 +135,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= @@ -231,6 +228,8 @@ github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= @@ -290,7 +289,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -302,8 +300,6 @@ github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/packethost/packngo v0.30.0 h1:JVeTwbXXETsLTDQncUbYwIFpkOp/xevXrffM2HrFECI= -github.com/packethost/packngo v0.30.0/go.mod h1:BT/XcdwLVmeMtGPbovnxCpnI1s9ylSE1cs/7pq007NE= github.com/pallinder/go-randomdata v1.2.0 h1:EJPxw+sgM1mbMW8RBu5zkG4FbloJpDOCCqPccdWto8A= github.com/pallinder/go-randomdata v1.2.0/go.mod h1:p8CasZQiWDLuaKy5ihVvdshqc7LlL6ovmRxAuNXgi3U= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -359,17 +355,12 @@ github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ai github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= @@ -443,7 +434,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= @@ -802,8 +792,6 @@ k8s.io/component-helpers v0.26.10 h1:KEwLNxzTE65R2kNz4UZ26h1G9O8xd6+iXVz7jkLgEYc k8s.io/component-helpers v0.26.10/go.mod h1:HYtL0UXL9zrYuuAmweYvHX/iQ0d0MURnvTOL3emC/r0= k8s.io/controller-manager v0.26.10 h1:oP6PZi3tAZJq/68zahXyvNul6myMyjm88SA6dNuJDCI= k8s.io/controller-manager v0.26.10/go.mod h1:XFqOI1Rys/Z4VGZY3BNVV2Hf17r7H5+yVpKdzcjCy4Y= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kms v0.26.10 h1:QFkYcCEonlYSZy6iUpZqSn9itsPwXbNgndkM4uAtgOk= diff --git a/metal/bgp.go b/metal/bgp.go index cfdb4db..e403186 100644 --- a/metal/bgp.go +++ b/metal/bgp.go @@ -9,7 +9,6 @@ import ( metal "github.com/equinix/equinix-sdk-go/services/metalv1" "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" - "k8s.io/utils/pointer" ) type bgp struct { @@ -62,7 +61,7 @@ func (b *bgp) enableBGP() error { Asn: int32(b.localASN), Md5: &b.bgpPass, DeploymentType: "local", - UseCase: pointer.String("kubernetes-load-balancer"), + UseCase: metal.PtrString("kubernetes-load-balancer"), } _, err = b.client. RequestBgpConfig(context.Background(), b.project). diff --git a/metal/cloud.go b/metal/cloud.go index 9380fe9..00be36d 100644 --- a/metal/cloud.go +++ b/metal/cloud.go @@ -7,7 +7,7 @@ import ( metal "github.com/equinix/equinix-sdk-go/services/metalv1" cloudprovider "k8s.io/cloud-provider" "k8s.io/component-base/version" - "k8s.io/klog" + "k8s.io/klog/v2" ) const ( diff --git a/metal/cloud_test.go b/metal/cloud_test.go index d64b7a0..7dd83c2 100644 --- a/metal/cloud_test.go +++ b/metal/cloud_test.go @@ -1,16 +1,15 @@ package metal import ( - "encoding/json" "fmt" - "net/http" "net/http/httptest" "net/url" "testing" + metaltest "github.com/equinix/cloud-provider-equinix-metal/metal/testing" + metal "github.com/equinix/equinix-sdk-go/services/metalv1" "github.com/google/uuid" - "github.com/gorilla/mux" clientset "k8s.io/client-go/kubernetes" k8sfake "k8s.io/client-go/kubernetes/fake" restclient "k8s.io/client-go/rest" @@ -26,16 +25,6 @@ const ( validZoneCode = "ewr1" ) -type MockMetalServer struct { - DeviceStore map[string]*metal.Device - ProjectStore map[string]struct { - Devices []*metal.Device - BgpEnabled bool - } - - T *testing.T -} - // mockControllerClientBuilder mock implementation of https://pkg.go.dev/k8s.io/cloud-provider#ControllerClientBuilder // so we can pass it to cloud.Initialize() type mockControllerClientBuilder struct{} @@ -57,14 +46,9 @@ func (m mockControllerClientBuilder) ClientOrDie(name string) clientset.Interfac } // create a valid cloud with a client -func testGetValidCloud(t *testing.T, LoadBalancerSetting string) (*cloud, *MockMetalServer) { - mockServer := &MockMetalServer{ - DeviceStore: map[string]*metal.Device{}, - ProjectStore: map[string]struct { - Devices []*metal.Device - BgpEnabled bool - }{}, - } +func testGetValidCloud(t *testing.T, LoadBalancerSetting string) (*cloud, *metaltest.MockMetalServer) { + mockServer := metaltest.NewMockMetalServer(t) + // mock endpoint so our client can handle it ts := httptest.NewServer(mockServer.CreateHandler()) @@ -210,22 +194,12 @@ func TestHasClusterID(t *testing.T) { // builds an Equinix Metal client func constructClient(authToken string, baseUrl *string) *metal.APIClient { - configuration := &metal.Configuration{ - DefaultHeader: make(map[string]string), - UserAgent: "metal-go/0.29.0", - Debug: false, - Servers: metal.ServerConfigurations{}, - OperationServers: map[string]metal.ServerConfigurations{}, - } + configuration := metal.NewConfiguration() + configuration.AddDefaultHeader("X-Auth-Token", authToken) + configuration.UserAgent = fmt.Sprintf("cloud-provider-equinix-metal/%s %s", version.Get(), configuration.UserAgent) - servers := metal.ServerConfigurations{ - { - URL: "https://api.equinix.com/metal/v1", - Description: "No description provided", - }, - } if baseUrl != nil { - servers = metal.ServerConfigurations{ + configuration.Servers = metal.ServerConfigurations{ { URL: *baseUrl, Description: "No description provided", @@ -233,65 +207,5 @@ func constructClient(authToken string, baseUrl *string) *metal.APIClient { } } - configuration.Servers = servers - configuration.AddDefaultHeader("X-Auth-Token", authToken) - configuration.UserAgent = fmt.Sprintf("cloud-provider-equinix-metal/%s %s", version.Get(), configuration.UserAgent) return metal.NewAPIClient(configuration) } - -func (s *MockMetalServer) CreateHandler() http.Handler { - r := mux.NewRouter() - // create a BGP config for a project - r.HandleFunc("/projects/{projectID}/bgp-configs", s.createBGPHandler).Methods("POST") - // get all devices for a project - r.HandleFunc("/projects/{projectID}/devices", s.listDevicesHandler).Methods("GET") - // get a single device - r.HandleFunc("/devices/{deviceID}", s.getDeviceHandler).Methods("GET") - // handle metadata requests - return r -} - -func (s *MockMetalServer) listDevicesHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - projectID := vars["projectID"] - - data := s.ProjectStore[projectID] - devices := data.Devices - var resp = struct { - Devices []*metal.Device `json:"devices"` - }{ - Devices: devices, - } - - w.Header().Set("Content-Type", "application/json") - if err := json.NewEncoder(w).Encode(&resp); err != nil { - s.T.Fatal(err.Error()) - } -} - -// get information about a specific device -func (s *MockMetalServer) getDeviceHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - volID := vars["deviceID"] - dev := s.DeviceStore[volID] - w.Header().Set("Content-Type", "application/json") - if dev != nil { - err := json.NewEncoder(w).Encode(dev) - if err != nil { - s.T.Fatal(err) - } - return - } - w.WriteHeader(http.StatusNotFound) -} - -// createBGPHandler enable BGP for a project -func (s *MockMetalServer) createBGPHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - projectID := vars["projectID"] - projectData := s.ProjectStore[projectID] - projectData.BgpEnabled = true - s.ProjectStore[projectID] = projectData - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) -} diff --git a/metal/testing/server.go b/metal/testing/server.go new file mode 100644 index 0000000..7346816 --- /dev/null +++ b/metal/testing/server.go @@ -0,0 +1,88 @@ +package testing + +import ( + "encoding/json" + "net/http" + "testing" + + metal "github.com/equinix/equinix-sdk-go/services/metalv1" + "github.com/gorilla/mux" +) + +type MockMetalServer struct { + DeviceStore map[string]*metal.Device + ProjectStore map[string]struct { + Devices []*metal.Device + BgpEnabled bool + } + + T *testing.T +} + +func NewMockMetalServer(t *testing.T) *MockMetalServer { + return &MockMetalServer{ + DeviceStore: map[string]*metal.Device{}, + ProjectStore: map[string]struct { + Devices []*metal.Device + BgpEnabled bool + }{}, + T: t, + } +} + +func (s *MockMetalServer) CreateHandler() http.Handler { + r := mux.NewRouter() + // create a BGP config for a project + r.HandleFunc("/projects/{projectID}/bgp-configs", s.createBGPHandler).Methods("POST") + // get all devices for a project + r.HandleFunc("/projects/{projectID}/devices", s.listDevicesHandler).Methods("GET") + // get a single device + r.HandleFunc("/devices/{deviceID}", s.getDeviceHandler).Methods("GET") + // handle metadata requests + return r +} + +func (s *MockMetalServer) listDevicesHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + projectID := vars["projectID"] + + data := s.ProjectStore[projectID] + devices := data.Devices + var resp = struct { + Devices []*metal.Device `json:"devices"` + }{ + Devices: devices, + } + + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(&resp); err != nil { + s.T.Fatal(err.Error()) + } +} + +// get information about a specific device +func (s *MockMetalServer) getDeviceHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + volID := vars["deviceID"] + dev := s.DeviceStore[volID] + w.Header().Set("Content-Type", "application/json") + if dev != nil { + err := json.NewEncoder(w).Encode(dev) + if err != nil { + s.T.Fatal(err) + } + return + } + w.WriteHeader(http.StatusNotFound) +} + +// createBGPHandler enable BGP for a project +func (s *MockMetalServer) createBGPHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + projectID := vars["projectID"] + projectData := s.ProjectStore[projectID] + projectData.BgpEnabled = true + s.ProjectStore[projectID] = projectData + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) +}