diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index cf90f96..b986278 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -22,6 +22,8 @@ jobs: go-version: ${{ env.GOVER }} - name: kubebuilder tests run: make test + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 golang-ci-lint: runs-on: ubuntu-20.04 diff --git a/.github/workflows/linters/.golangci.yml b/.github/workflows/linters/.golangci.yml index f7f49bd..4d27067 100644 --- a/.github/workflows/linters/.golangci.yml +++ b/.github/workflows/linters/.golangci.yml @@ -33,7 +33,6 @@ linters: - gosimple - govet - ineffassign - - lll - misspell - nakedret - noctx @@ -59,9 +58,6 @@ linters: - nestif - prealloc - wsl -linters-settings: - lll: - line-length: 140 issues: # https://github.com/golangci/golangci-lint/issues/2439#issuecomment-1002912465 @@ -74,4 +70,6 @@ issues: # - structcheck # - unused # - unparam + - goerr113 + - gochecknoglobals - funlen diff --git a/Makefile b/Makefile index 7e96a05..b7bc510 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ ENVTEST_ASSETS_DIR=$(shell pwd)/testbin test: manifests generate fmt vet ## Run tests. mkdir -p ${ENVTEST_ASSETS_DIR} test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.3/hack/setup-envtest.sh - source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out + source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); CGO_ENABLED=1 go test ./... -race -coverprofile coverage.out -covermode atomic ##@ Build diff --git a/api/clientset/v1alpha1/srlinux.go b/api/clientset/v1alpha1/srlinux.go index 772eb21..3b94050 100644 --- a/api/clientset/v1alpha1/srlinux.go +++ b/api/clientset/v1alpha1/srlinux.go @@ -25,26 +25,13 @@ var ErrUpdateFailed = errors.New("operation update failed") // SrlinuxInterface provides access to the Srlinux CRD. type SrlinuxInterface interface { - List(ctx context.Context, opts *metav1.ListOptions) (*typesv1alpha1.SrlinuxList, error) - Get( - ctx context.Context, - name string, - options *metav1.GetOptions, - ) (*typesv1alpha1.Srlinux, error) + List(ctx context.Context, opts metav1.ListOptions) (*typesv1alpha1.SrlinuxList, error) + Get(ctx context.Context, name string, opts metav1.GetOptions) (*typesv1alpha1.Srlinux, error) Create(ctx context.Context, srlinux *typesv1alpha1.Srlinux) (*typesv1alpha1.Srlinux, error) - Delete(ctx context.Context, name string, opts *metav1.DeleteOptions) error - Watch(ctx context.Context, opts *metav1.ListOptions) (watch.Interface, error) - Unstructured( - ctx context.Context, - name string, - opts *metav1.GetOptions, - subresources ...string, - ) (*unstructured.Unstructured, error) - Update( - ctx context.Context, - obj *unstructured.Unstructured, - opts *metav1.UpdateOptions, - ) (*typesv1alpha1.Srlinux, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Unstructured(ctx context.Context, name string, opts metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) + Update(ctx context.Context, obj *unstructured.Unstructured, opts metav1.UpdateOptions) (*typesv1alpha1.Srlinux, error) } // Interface is the clientset interface for srlinux. @@ -58,16 +45,25 @@ type Clientset struct { restClient rest.Interface } -var gvr = schema.GroupVersionResource{ // nolint: gochecknoglobals - Group: typesv1alpha1.GroupVersion.Group, - Version: typesv1alpha1.GroupVersion.Version, - Resource: "srlinuxes", +func GVR() schema.GroupVersionResource { + return schema.GroupVersionResource{ + Group: typesv1alpha1.GroupName, + Version: typesv1alpha1.GroupVersion, + Resource: "srlinuxes", + } +} + +func GV() *schema.GroupVersion { + return &schema.GroupVersion{ + Group: typesv1alpha1.GroupName, + Version: typesv1alpha1.GroupVersion, + } } // NewForConfig returns a new Clientset based on c. func NewForConfig(c *rest.Config) (*Clientset, error) { config := *c - config.ContentConfig.GroupVersion = &schema.GroupVersion{Group: gvr.Group, Version: gvr.Version} + config.ContentConfig.GroupVersion = &schema.GroupVersion{Group: GVR().Group, Version: GVR().Version} config.APIPath = "/apis" config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() config.UserAgent = rest.DefaultKubernetesUserAgent() @@ -77,7 +73,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { return nil, err } - dInterface := dClient.Resource(gvr) + dInterface := dClient.Resource(GVR()) rClient, err := rest.RESTClientFor(&config) if err != nil { @@ -108,14 +104,14 @@ type srlinuxClient struct { // List gets a list of SRLinux resources. func (s *srlinuxClient) List( ctx context.Context, - opts *metav1.ListOptions, + opts metav1.ListOptions, // skipcq: CRT-P0003 ) (*typesv1alpha1.SrlinuxList, error) { result := typesv1alpha1.SrlinuxList{} err := s.restClient. Get(). Namespace(s.ns). - Resource(gvr.Resource). - VersionedParams(opts, scheme.ParameterCodec). + Resource(GVR().Resource). + VersionedParams(&opts, scheme.ParameterCodec). Do(ctx). Into(&result) @@ -126,15 +122,15 @@ func (s *srlinuxClient) List( func (s *srlinuxClient) Get( ctx context.Context, name string, - opts *metav1.GetOptions, + opts metav1.GetOptions, ) (*typesv1alpha1.Srlinux, error) { result := typesv1alpha1.Srlinux{} err := s.restClient. Get(). Namespace(s.ns). - Resource(gvr.Resource). + Resource(GVR().Resource). Name(name). - VersionedParams(opts, scheme.ParameterCodec). + VersionedParams(&opts, scheme.ParameterCodec). Do(ctx). Into(&result) @@ -150,7 +146,7 @@ func (s *srlinuxClient) Create( err := s.restClient. Post(). Namespace(s.ns). - Resource(gvr.Resource). + Resource(GVR().Resource). Body(srlinux). Do(ctx). Into(&result) @@ -160,24 +156,27 @@ func (s *srlinuxClient) Create( func (s *srlinuxClient) Watch( ctx context.Context, - opts *metav1.ListOptions, + opts metav1.ListOptions, // skipcq: CRT-P0003 ) (watch.Interface, error) { opts.Watch = true return s.restClient. Get(). Namespace(s.ns). - Resource(gvr.Resource). - VersionedParams(opts, scheme.ParameterCodec). + Resource(GVR().Resource). + VersionedParams(&opts, scheme.ParameterCodec). Watch(ctx) } -func (s *srlinuxClient) Delete(ctx context.Context, name string, opts *metav1.DeleteOptions) error { +func (s *srlinuxClient) Delete(ctx context.Context, + name string, + opts metav1.DeleteOptions, // skipcq: CRT-P0003 +) error { return s.restClient. Delete(). Namespace(s.ns). - Resource(gvr.Resource). - VersionedParams(opts, scheme.ParameterCodec). + Resource(GVR().Resource). + VersionedParams(&opts, scheme.ParameterCodec). Name(name). Do(ctx). Error() @@ -186,11 +185,11 @@ func (s *srlinuxClient) Delete(ctx context.Context, name string, opts *metav1.De func (s *srlinuxClient) Update( ctx context.Context, obj *unstructured.Unstructured, - _ *metav1.UpdateOptions, + opts metav1.UpdateOptions, ) (*typesv1alpha1.Srlinux, error) { result := typesv1alpha1.Srlinux{} - obj, err := s.dInterface.Namespace(s.ns).UpdateStatus(ctx, obj, metav1.UpdateOptions{}) + obj, err := s.dInterface.Namespace(s.ns).UpdateStatus(ctx, obj, opts) if err != nil { return nil, err } @@ -203,15 +202,14 @@ func (s *srlinuxClient) Update( return &result, nil } -func (s *srlinuxClient) Unstructured( - ctx context.Context, - name string, - opts *metav1.GetOptions, +func (s *srlinuxClient) Unstructured(ctx context.Context, name string, opts metav1.GetOptions, subresources ...string, ) (*unstructured.Unstructured, error) { - return s.dInterface.Namespace(s.ns).Get(ctx, name, *opts, subresources...) + return s.dInterface.Namespace(s.ns).Get(ctx, name, opts, subresources...) } func init() { - _ = typesv1alpha1.AddToScheme(scheme.Scheme) + if err := typesv1alpha1.AddToScheme(scheme.Scheme); err != nil { + panic(err) + } } diff --git a/api/clientset/v1alpha1/srlinux_test.go b/api/clientset/v1alpha1/srlinux_test.go new file mode 100644 index 0000000..4805720 --- /dev/null +++ b/api/clientset/v1alpha1/srlinux_test.go @@ -0,0 +1,463 @@ +package v1alpha1 + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "reflect" + "testing" + + "github.com/h-fam/errdiff" + "github.com/kr/pretty" + srlinuxv1 "github.com/srl-labs/srl-controller/api/types/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + ktest "k8s.io/client-go/testing" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + dynamicfake "k8s.io/client-go/dynamic/fake" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + restfake "k8s.io/client-go/rest/fake" +) + +var ( + obj1 = &srlinuxv1.Srlinux{ + TypeMeta: metav1.TypeMeta{ + Kind: "Srlinux", + APIVersion: "kne.srlinux.dev/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "obj1", + Namespace: "test", + Generation: 1, + }, + Status: srlinuxv1.SrlinuxStatus{}, + Spec: srlinuxv1.SrlinuxSpec{ + Config: &srlinuxv1.NodeConfig{}, + NumInterfaces: 2, + Model: "fake", + Version: "1", + }, + } + + obj2 = &srlinuxv1.Srlinux{ + TypeMeta: metav1.TypeMeta{ + Kind: "Srlinux", + APIVersion: "kne.srlinux.dev/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "obj2", + Namespace: "test", + Generation: 1, + }, + Status: srlinuxv1.SrlinuxStatus{}, + Spec: srlinuxv1.SrlinuxSpec{ + Config: &srlinuxv1.NodeConfig{}, + NumInterfaces: 2, + Model: "fake1", + Version: "2", + }, + } +) + +func setUp(t *testing.T) (*Clientset, *restfake.RESTClient) { + t.Helper() + + gv := GV() + + fakeClient := &restfake.RESTClient{ + NegotiatedSerializer: scheme.Codecs.WithoutConversion(), + GroupVersion: *gv, + VersionedAPIPath: GVR().Version, + } + + cs, err := NewForConfig(&rest.Config{}) + if err != nil { + t.Fatalf("NewForConfig() failed: %v", err) + } + + objs := []runtime.Object{obj1, obj2} + cs.restClient = fakeClient + f := dynamicfake.NewSimpleDynamicClient(scheme.Scheme, objs...) + f.PrependReactor("get", "*", func(action ktest.Action) (bool, runtime.Object, error) { + gAction := action.(ktest.GetAction) + switch gAction.GetName() { + case "obj1": + return true, obj1, nil + case "obj2": + return true, obj2, nil + } + + return false, nil, nil + }) + + f.PrependReactor("update", "*", func(action ktest.Action) (bool, runtime.Object, error) { + uAction, ok := action.(ktest.UpdateAction) + if !ok { + return false, nil, nil + } + + uObj := uAction.GetObject().(*unstructured.Unstructured) + sObj := &srlinuxv1.Srlinux{} + + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(uObj.Object, sObj); err != nil { + return true, nil, fmt.Errorf("failed to convert object: %v", err) + } + + if sObj.ObjectMeta.Name == "doesnotexist" { + return true, nil, fmt.Errorf("doesnotexist") + } + + return true, uAction.GetObject(), nil + }) + + cs.dInterface = f.Resource(GVR()) + + return cs, fakeClient +} + +func TestCreate(t *testing.T) { + cs, fakeClient := setUp(t) + + tests := []struct { + desc string + resp *http.Response + want *srlinuxv1.Srlinux + wantErr string + }{{ + desc: "Error", + wantErr: "TEST ERROR", + }, { + desc: "Valid Node", + resp: &http.Response{ + StatusCode: http.StatusOK, + }, + want: obj1, + }} + + for _, tt := range tests { + fakeClient.Err = nil + if tt.wantErr != "" { + fakeClient.Err = fmt.Errorf(tt.wantErr) + } + + fakeClient.Resp = tt.resp + + if tt.want != nil { + b, _ := json.Marshal(tt.want) + tt.resp.Body = io.NopCloser(bytes.NewReader(b)) + } + + t.Run(tt.desc, func(t *testing.T) { + tc := cs.Srlinux("foo") + got, err := tc.Create(context.Background(), tt.want) + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + if tt.wantErr != "" { + return + } + want := tt.want.DeepCopy() + want.TypeMeta = metav1.TypeMeta{} + if !reflect.DeepEqual(got, want) { + t.Fatalf("Create(%+v) failed: diff\n%s", tt.want, pretty.Diff(got, want)) + } + }) + } +} + +func TestList(t *testing.T) { + cs, fakeClient := setUp(t) + tests := []struct { + desc string + resp *http.Response + want *srlinuxv1.SrlinuxList + wantErr string + }{{ + desc: "Error", + wantErr: "TEST ERROR", + }, { + desc: "Valid Node", + resp: &http.Response{ + StatusCode: http.StatusOK, + }, + want: &srlinuxv1.SrlinuxList{ + Items: []srlinuxv1.Srlinux{*obj1, *obj2}, + }, + }} + + for _, tt := range tests { + fakeClient.Err = nil + + if tt.wantErr != "" { + fakeClient.Err = fmt.Errorf(tt.wantErr) + } + + fakeClient.Resp = tt.resp + + if tt.want != nil { + b, _ := json.Marshal(tt.want) + tt.resp.Body = io.NopCloser(bytes.NewReader(b)) + } + + t.Run(tt.desc, func(t *testing.T) { + tc := cs.Srlinux("foo") + + got, err := tc.List(context.Background(), metav1.ListOptions{}) + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + + if tt.wantErr != "" { + return + } + + if !reflect.DeepEqual(got, tt.want) { + t.Fatalf("List() failed: got %v, want %v", got, tt.want) + } + }) + } +} + +func TestGet(t *testing.T) { + cs, fakeClient := setUp(t) + tests := []struct { + desc string + resp *http.Response + want *srlinuxv1.Srlinux + wantErr string + }{{ + desc: "Error", + wantErr: "TEST ERROR", + }, { + desc: "Valid Node", + resp: &http.Response{ + StatusCode: http.StatusOK, + }, + want: obj1, + }} + + for _, tt := range tests { + fakeClient.Err = nil + + if tt.wantErr != "" { + fakeClient.Err = fmt.Errorf(tt.wantErr) + } + + fakeClient.Resp = tt.resp + + if tt.want != nil { + b, _ := json.Marshal(tt.want) + tt.resp.Body = io.NopCloser(bytes.NewReader(b)) + } + + t.Run(tt.desc, func(t *testing.T) { + tc := cs.Srlinux("foo") + + got, err := tc.Get(context.Background(), "test", metav1.GetOptions{}) + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + + if tt.wantErr != "" { + return + } + + want := tt.want.DeepCopy() + want.TypeMeta = metav1.TypeMeta{} + if !reflect.DeepEqual(got, want) { + t.Fatalf("Get() failed: got %v, want %v", got, want) + } + }) + } +} + +func TestDelete(t *testing.T) { + cs, fakeClient := setUp(t) + tests := []struct { + desc string + resp *http.Response + wantErr string + }{{ + desc: "Error", + wantErr: "TEST ERROR", + }, { + desc: "Valid Node", + resp: &http.Response{ + StatusCode: http.StatusOK, + }, + }} + + for _, tt := range tests { + fakeClient.Err = nil + + if tt.wantErr != "" { + fakeClient.Err = fmt.Errorf(tt.wantErr) + } + + fakeClient.Resp = tt.resp + + t.Run(tt.desc, func(t *testing.T) { + tc := cs.Srlinux("foo") + err := tc.Delete(context.Background(), "obj1", metav1.DeleteOptions{}) + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + if tt.wantErr != "" { + return + } + }) + } +} + +func TestWatch(t *testing.T) { + cs, fakeClient := setUp(t) + tests := []struct { + desc string + resp *http.Response + want *watch.Event + wantErr string + }{{ + desc: "Error", + wantErr: "TEST ERROR", + }} + + for _, tt := range tests { + fakeClient.Err = nil + + if tt.wantErr != "" { + fakeClient.Err = fmt.Errorf(tt.wantErr) + } + + fakeClient.Resp = tt.resp + + if tt.want != nil { + b, _ := json.Marshal(tt.want) + tt.resp.Body = io.NopCloser(bytes.NewReader(b)) + } + + t.Run(tt.desc, func(t *testing.T) { + tc := cs.Srlinux("foo") + w, err := tc.Watch(context.Background(), metav1.ListOptions{}) + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + + if tt.wantErr != "" { + return + } + + e := <-w.ResultChan() + if !reflect.DeepEqual(e, tt.want) { + t.Fatalf("Watch() failed: got %v, want %v", e, tt.want) + } + }) + } +} + +func TestUnstructured(t *testing.T) { + cs, _ := setUp(t) + tests := []struct { + desc string + in string + want *srlinuxv1.Srlinux + wantErr string + }{{ + desc: "Error", + in: "missingObj", + wantErr: `"missingObj" not found`, + }, { + desc: "Valid Node", + in: obj1.GetObjectMeta().GetName(), + want: obj1, + }, { + desc: "Valid Node", + in: obj2.GetObjectMeta().GetName(), + want: obj2, + }} + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + tc := cs.Srlinux("test") + got, err := tc.Unstructured(context.Background(), tt.in, metav1.GetOptions{}) + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + + if tt.wantErr != "" { + return + } + + uObj1 := &srlinuxv1.Srlinux{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(got.Object, uObj1); err != nil { + t.Fatalf("failed to turn response into a topology: %v", err) + } + + if !reflect.DeepEqual(uObj1, tt.want) { + t.Fatalf("Unstructured(%q) failed: got %+v, want %+v", tt.in, uObj1, tt.want) + } + }) + } +} + +func TestUpdate(t *testing.T) { + cs, _ := setUp(t) + tests := []struct { + desc string + want *srlinuxv1.Srlinux + wantErr string + }{{ + desc: "Error", + want: &srlinuxv1.Srlinux{ + TypeMeta: metav1.TypeMeta{ + Kind: "Srlinux", + APIVersion: "kne.srlinux.dev/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "doesnotexist", + Namespace: "test", + Generation: 1, + }, + }, + wantErr: "doesnotexist", + }, { + desc: "Valid Topology", + want: obj1, + }} + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + sc := cs.Srlinux("test") + updateObj := tt.want.DeepCopy() + updateObj.Spec.Version = "updated version" + + update, err := runtime.DefaultUnstructuredConverter.ToUnstructured(updateObj) + if err != nil { + t.Fatalf("failed to generate update: %v", err) + } + + got, err := sc.Update(context.Background(), &unstructured.Unstructured{ + Object: update, + }, metav1.UpdateOptions{}) + + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + + if tt.wantErr != "" { + return + } + + want := tt.want.DeepCopy() + want.TypeMeta = metav1.TypeMeta{} + if !reflect.DeepEqual(got, updateObj) { + t.Fatalf("Update() failed: got %+v, want %+v", got, want) + } + }) + } +} diff --git a/api/types/v1alpha1/groupversion_info.go b/api/types/v1alpha1/groupversion_info.go index 35e47e7..08e76d9 100644 --- a/api/types/v1alpha1/groupversion_info.go +++ b/api/types/v1alpha1/groupversion_info.go @@ -20,20 +20,29 @@ limitations under the License. package v1alpha1 import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" ) +const ( + GroupName = "kne.srlinux.dev" + GroupVersion = "v1alpha1" +) + +// nolint: gochecknoglobals var ( - // GroupVersion is group version used to register these objects. - GroupVersion = schema.GroupVersion{ // nolint: gochecknoglobals - Group: "kne.srlinux.dev", - Version: "v1alpha1", - } + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme + SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: GroupVersion} +) - // SchemeBuilder is used to add go types to the GroupVersionKind scheme. - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} // nolint: gochecknoglobals +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Srlinux{}, + &SrlinuxList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme // nolint: gochecknoglobals -) + return nil +} diff --git a/api/types/v1alpha1/srlinux_types.go b/api/types/v1alpha1/srlinux_types.go index 525b9a2..70171b7 100644 --- a/api/types/v1alpha1/srlinux_types.go +++ b/api/types/v1alpha1/srlinux_types.go @@ -72,10 +72,6 @@ type SrlinuxList struct { Items []Srlinux `json:"items"` } -func init() { - SchemeBuilder.Register(&Srlinux{}, &SrlinuxList{}) -} - // GetConfig gets config from srlinux spec. func (s *SrlinuxSpec) GetConfig() *NodeConfig { if s.Config != nil { diff --git a/api/types/v1alpha1/zz_generated.deepcopy.go b/api/types/v1alpha1/zz_generated.deepcopy.go index f0ec889..11e7ee8 100644 --- a/api/types/v1alpha1/zz_generated.deepcopy.go +++ b/api/types/v1alpha1/zz_generated.deepcopy.go @@ -36,7 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package v1alpha1 import ( - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 3025c25..a0cbd35 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -37,8 +37,8 @@ import ( // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. var ( - k8sClient client.Client // nolint: gochecknoglobals - testEnv *envtest.Environment // nolint: gochecknoglobals + k8sClient client.Client + testEnv *envtest.Environment ) func TestAPIs(t *testing.T) { diff --git a/go.mod b/go.mod index 416cffa..ce67c78 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,9 @@ go 1.17 require ( github.com/go-logr/logr v0.4.0 + github.com/google/go-cmp v0.5.8 + github.com/h-fam/errdiff v1.0.2 + github.com/kr/pretty v0.2.1 github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.13.0 github.com/openconfig/kne v0.1.1 @@ -32,13 +35,13 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.2.0 // indirect github.com/googleapis/gnostic v0.5.5 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/json-iterator/go v1.1.11 // indirect + github.com/kr/text v0.2.0 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -65,12 +68,13 @@ require ( golang.org/x/tools v0.1.5 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20220322021311-435b647f9ef2 // indirect + google.golang.org/grpc v1.45.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - gotest.tools v2.2.0+incompatible // indirect k8s.io/apiextensions-apiserver v0.21.2 // indirect k8s.io/component-base v0.21.2 // indirect k8s.io/klog/v2 v2.8.0 // indirect diff --git a/go.sum b/go.sum index 3ab08aa..acc610e 100644 --- a/go.sum +++ b/go.sum @@ -380,7 +380,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -424,6 +423,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h-fam/errdiff v1.0.2 h1:rPsW4ob2fMOIulwTEoZXaaUIuud7XUudw5SLKTZj3Ss= github.com/h-fam/errdiff v1.0.2/go.mod h1:FOzgnHXSEE3rRvmGXgmiqWl+H3lwLywYm9CSXqXrSTg= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -487,6 +487,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= @@ -1040,7 +1041,6 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= @@ -1091,6 +1091,7 @@ google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20220322021311-435b647f9ef2 h1:3n0D2NdPGm0g0wrVJzXJWW5CBOoqgGBkDX9cRMJHZAY= google.golang.org/genproto v0.0.0-20220322021311-435b647f9ef2/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1113,6 +1114,7 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1166,7 +1168,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=