Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)

Expand Down
23 changes: 13 additions & 10 deletions pkg/cmd/helmfile/move/move.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need jxclient? Unit tests pass with normal kubeclient, but I am not sure ...

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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -330,21 +335,19 @@ 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() {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this anymore?

// 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)
if err != nil {
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)
Expand Down
48 changes: 44 additions & 4 deletions pkg/cmd/helmfile/move/move_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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")
Expand Down