diff --git a/Makefile b/Makefile index 23f7f9da3..a821bd3ad 100644 --- a/Makefile +++ b/Makefile @@ -59,8 +59,8 @@ GOTEST += -count=1 endif TEST_PACKAGE ?= ./... -COVER_OUT:=$(REPORTS_DIR)/cover.out -COVERFLAGS=-coverprofile=$(COVER_OUT) --covermode=count --coverpkg=./... +COVER_OUT:=$(REPORTS_DIR)/cover.txt +COVERFLAGS=-coverprofile=$(COVER_OUT) --covermode=atomic --coverpkg=./pkg/... .PHONY: list list: ## List all make targets @@ -73,9 +73,6 @@ help: full: check ## Build and run the tests check: build test ## Build and run the tests -get-test-deps: ## Install test dependencies - $(GO_NOMOD) get github.com/axw/gocov/gocov - $(GO_NOMOD) get -u gopkg.in/matm/v1/gocov-html print-version: ## Print version @echo $(VERSION) @@ -97,17 +94,16 @@ make-reports-dir: mkdir -p $(REPORTS_DIR) test: ## Run tests with the "unit" build tag - KUBECONFIG=/cluster/connections/not/allowed JX_NO_KUBERNETES=true CGO_ENABLED=$(CGO_ENABLED) $(GOTEST) --tags=unit -failfast -short ./... $(TEST_BUILDFLAGS) + KUBECONFIG=/cluster/connections/not/allowed CGO_ENABLED=$(CGO_ENABLED) $(GOTEST) --tags=unit -failfast -short ./... $(TEST_BUILDFLAGS) test-coverage : make-reports-dir ## Run tests and coverage for all tests with the "unit" build tag CGO_ENABLED=$(CGO_ENABLED) $(GOTEST) --tags=unit $(COVERFLAGS) -failfast -short ./... $(TEST_BUILDFLAGS) -test-report: make-reports-dir get-test-deps test-coverage ## Create the test report - @gocov convert $(COVER_OUT) | gocov report - -test-report-html: make-reports-dir get-test-deps test-coverage ## Create the test report in HTML format - @gocov convert $(COVER_OUT) | gocov-html > $(REPORTS_DIR)/cover.html && open $(REPORTS_DIR)/cover.html +test-report-html: make-reports-dir test-coverage + $(GO) tool cover -html=$(COVER_OUT) +test-total-cov: make-reports-dir test-coverage + $(GO) tool cover -func=$(COVER_OUT) install: $(GO_DEPENDENCIES) ## Install the binary GOBIN=${GOPATH}/bin $(GO) install $(BUILDFLAGS) $(MAIN_SRC_FILE) diff --git a/pkg/cmd/helmfile/move/move.go b/pkg/cmd/helmfile/move/move.go index 14ab53a6b..7edbe2185 100644 --- a/pkg/cmd/helmfile/move/move.go +++ b/pkg/cmd/helmfile/move/move.go @@ -9,12 +9,10 @@ import ( "github.com/jenkins-x-plugins/jx-gitops/pkg/helmhelpers" "github.com/jenkins-x-plugins/jx-gitops/pkg/rootcmd" - "github.com/jenkins-x/jx-api/v4/pkg/client/clientset/versioned" "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/helper" "github.com/jenkins-x/jx-helpers/v3/pkg/cobras/templates" "github.com/jenkins-x/jx-helpers/v3/pkg/files" "github.com/jenkins-x/jx-helpers/v3/pkg/kube" - "github.com/jenkins-x/jx-helpers/v3/pkg/kube/jxclient" "github.com/jenkins-x/jx-helpers/v3/pkg/kyamls" "github.com/jenkins-x/jx-helpers/v3/pkg/termcolor" "github.com/jenkins-x/jx-helpers/v3/pkg/yamls" @@ -24,6 +22,7 @@ import ( "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" "sigs.k8s.io/kustomize/kyaml/yaml" ) @@ -55,6 +54,7 @@ If supplied with --dir-includes-release-name then by default we will annotate th // NamespaceOptions the options for the command type Options struct { kyamls.Filter + KubeClient kubernetes.Interface Dir string OutputDir string ClusterDir string @@ -223,8 +223,13 @@ func (o *Options) lazyCreateNamespaceResource(ns string) error { } func (o *Options) moveFilesToClusterOrNamespacesFolder(dir, ns, releaseName, chartName string) error { + var err error o.ClusterWide = make(map[string]bool) - JXClient, err := jxclient.LazyCreateJXClient(nil) + o.KubeClient, err = kube.LazyCreateKubeClient(o.KubeClient) + if err != nil { + return err + } + err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { //nolint:staticcheck if info == nil || info.IsDir() { return nil @@ -292,7 +297,7 @@ func (o *Options) moveFilesToClusterOrNamespacesFolder(dir, ns, releaseName, cha if kyamls.IsCustomResourceDefinition(kind) { outDir = filepath.Join(o.CustomResourceDefinitionsDir, ns, pathName) } else { - isClusterKind, err := o.isClusterWide(kind, kyamls.GetAPIVersion(node, path), JXClient) + isClusterKind, err := o.isClusterWide(kind, kyamls.GetAPIVersion(node, path), o.KubeClient) if err != nil { return err } @@ -330,11 +335,7 @@ func (o *Options) moveFilesToClusterOrNamespacesFolder(dir, ns, releaseName, cha return nil } -func (o *Options) isClusterWide(kind string, apiVersion string, client versioned.Interface) (bool, error) { - if kube.IsNoKubernetes() { - // Approximates the truth - return kyamls.IsClusterKind(kind), nil - } +func (o *Options) isClusterWide(kind, apiVersion string, client kubernetes.Interface) (bool, error) { val, ok := o.ClusterWide[kind] if !ok { apiResourceList, err := client.Discovery().ServerResourcesForGroupVersion(apiVersion) @@ -342,9 +343,11 @@ func (o *Options) isClusterWide(kind string, apiVersion string, client versioned return true, err } - for _, resource := range apiResourceList.APIResources { + for k := range apiResourceList.APIResources { + resource := apiResourceList.APIResources[k] o.ClusterWide[resource.Kind] = !resource.Namespaced } + val, ok = o.ClusterWide[kind] if !ok { return false, fmt.Errorf("the server doesn't have %s of %s", kind, apiVersion) diff --git a/pkg/cmd/helmfile/move/move_test.go b/pkg/cmd/helmfile/move/move_test.go index 80f2afc6f..4cd26f350 100644 --- a/pkg/cmd/helmfile/move/move_test.go +++ b/pkg/cmd/helmfile/move/move_test.go @@ -9,7 +9,10 @@ import ( "github.com/jenkins-x/jx-helpers/v3/pkg/yamls" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/kubernetes/fake" ) func TestUpdateNamespaceInYamlFiles(t *testing.T) { @@ -49,17 +52,54 @@ func TestUpdateNamespaceInYamlFiles(t *testing.T) { } for _, test := range tests { - tmpDir := t.TempDir() - _, o := move.NewCmdHelmfileMove() - t.Logf("generating output to %s\n", tmpDir) - + kubeClient := fake.NewSimpleClientset() + fakeDiscovery, ok := kubeClient.Discovery().(*fakediscovery.FakeDiscovery) + if !ok { + t.Fatalf("couldn't convert Discovery() to *FakeDiscovery") + } + fakeDiscovery.Resources = []*v1.APIResourceList{ + { + TypeMeta: v1.TypeMeta{}, + GroupVersion: "apps/v1", + APIResources: []v1.APIResource{ + { + Name: "test-deployment", + Namespaced: true, + Kind: "Deployment", + }, + }, + }, + { + TypeMeta: v1.TypeMeta{}, + GroupVersion: "rbac.authorization.k8s.io/v1", + APIResources: []v1.APIResource{ + { + Name: "test-clusterRole", + Namespaced: false, + Kind: "ClusterRole", + }, + }, + }, + { + TypeMeta: v1.TypeMeta{}, + GroupVersion: "example.io/v1", + APIResources: []v1.APIResource{ + { + Name: "test-example", + Namespaced: true, + Kind: "Example", + }, + }, + }, + } o.Dir = filepath.Join("test_data", test.folder) o.OutputDir = tmpDir o.DirIncludesReleaseName = test.hasReleaseName o.AnnotateReleaseNames = true + o.KubeClient = kubeClient err := o.Run() require.NoError(t, err, "failed to run helmfile move")