Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

add --k8s-default-namespace argument to override default namespace #2625

Merged
merged 2 commits into from
Nov 28, 2019
Merged
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
11 changes: 6 additions & 5 deletions cmd/fluxd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"syscall"
"time"

helmopclient "github.com/fluxcd/helm-operator/pkg/client/clientset/versioned"
"github.com/go-kit/kit/log"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -51,6 +50,7 @@ import (
"github.com/fluxcd/flux/pkg/remote"
"github.com/fluxcd/flux/pkg/ssh"
fluxsync "github.com/fluxcd/flux/pkg/sync"
helmopclient "github.com/fluxcd/helm-operator/pkg/client/clientset/versioned"
)

var version = "unversioned"
Expand Down Expand Up @@ -170,10 +170,11 @@ func main() {
k8sSecretDataKey = fs.String("k8s-secret-data-key", "identity", "data key holding the private SSH key within the k8s secret")

// k8s-scope settings
k8sNamespaceWhitelist = fs.StringSlice("k8s-namespace-whitelist", []string{}, "restrict the view of the cluster to the namespaces listed. All namespaces are included if this is not set")
k8sAllowNamespace = fs.StringSlice("k8s-allow-namespace", []string{}, "restrict all operations to the provided namespaces")
k8sNamespaceWhitelist = fs.StringSlice("k8s-namespace-whitelist", []string{}, "restrict the view of the cluster to the namespaces listed. All namespaces are included if this is not set")
k8sAllowNamespace = fs.StringSlice("k8s-allow-namespace", []string{}, "restrict all operations to the provided namespaces")
k8sDefaultNamespace = fs.String("k8s-default-namespace", "", "the namespace to use for resources where a namespace is not specified")

k8sVerbosity = fs.Int("k8s-verbosity", 0, "klog verbosity level")
k8sVerbosity = fs.Int("k8s-verbosity", 0, "klog verbosity level")

// SSH key generation
sshKeyBits = optionalVar(fs, &ssh.KeyBitsValue{}, "ssh-keygen-bits", "-b argument to ssh-keygen (default unspecified)")
Expand Down Expand Up @@ -502,7 +503,7 @@ func main() {
imageCreds = k8sInst.ImagesToFetch
// There is only one way we currently interpret a repo of
// files as manifests, and that's as Kubernetes yamels.
namespacer, err := kubernetes.NewNamespacer(discoClientset)
namespacer, err := kubernetes.NewNamespacer(discoClientset, *k8sDefaultNamespace)
if err != nil {
logger.Log("err", err)
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions docs/references/daemon.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Version controlling of cluster manifests provides reproducibility and a historic
| --k8s-secret-data-key | `identity` | data key holding the private SSH key within the k8s secret
| **k8s configuration**
| --k8s-allow-namespace | | restrict all operations to the provided namespaces
| --k8s-default-namespace | | the namespace to use for resources where a namespace is not specified
| **upstream service**
| --connect | | connect to an upstream service e.g., Weave Cloud, at this base address
| --token | | authentication token for upstream service
Expand Down
8 changes: 4 additions & 4 deletions pkg/cluster/kubernetes/cached_disco_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ func TestCachedDiscovery(t *testing.T) {

cachedDisco := MakeCachedDiscovery(coreClient.Discovery(), crdClient, shutdown)

saved := getDefaultNamespace
getDefaultNamespace = func() (string, error) { return "bar-ns", nil }
defer func() { getDefaultNamespace = saved }()
namespacer, err := NewNamespacer(cachedDisco)
saved := getKubeconfigDefaultNamespace
getKubeconfigDefaultNamespace = func() (string, error) { return "bar-ns", nil }
defer func() { getKubeconfigDefaultNamespace = saved }()
namespacer, err := NewNamespacer(cachedDisco, "")
if err != nil {
t.Fatal(err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/cluster/kubernetes/manifests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
func TestLocalCRDScope(t *testing.T) {
coreClient := makeFakeClient()

nser, err := NewNamespacer(coreClient.Discovery())
nser, err := NewNamespacer(coreClient.Discovery(), "")
assert.NoError(t, err)
manifests := NewManifests(nser, log.NewLogfmtLogger(os.Stdout))

Expand Down Expand Up @@ -64,7 +64,7 @@ metadata:
func TestUnKnownCRDScope(t *testing.T) {
coreClient := makeFakeClient()

nser, err := NewNamespacer(coreClient.Discovery())
nser, err := NewNamespacer(coreClient.Discovery(), "")
assert.NoError(t, err)
logBuffer := bytes.NewBuffer(nil)
manifests := NewManifests(nser, log.NewLogfmtLogger(logBuffer))
Expand Down
27 changes: 17 additions & 10 deletions pkg/cluster/kubernetes/namespacer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,28 @@ type namespaceViaDiscovery struct {
}

// NewNamespacer creates an implementation of Namespacer
func NewNamespacer(d discovery.DiscoveryInterface) (*namespaceViaDiscovery, error) {
fallback, err := getDefaultNamespace()
// If not empty `defaultNamespaceOverride` is used as the namespace when
// a resource doesn't have a namespace specified. If empty the namespace
// from the context in the KUBECONFIG is used, otherwise the "default"
// namespace is used mimicking kubectl behavior
func NewNamespacer(d discovery.DiscoveryInterface, defaultNamespaceOverride string) (*namespaceViaDiscovery, error) {
if defaultNamespaceOverride != "" {
return &namespaceViaDiscovery{fallbackNamespace: defaultNamespaceOverride, disco: d}, nil
}
kubeconfigDefaultNamespace, err := getKubeconfigDefaultNamespace()
if err != nil {
return nil, err
}
return &namespaceViaDiscovery{fallbackNamespace: fallback, disco: d}, nil
if kubeconfigDefaultNamespace != "" {
return &namespaceViaDiscovery{fallbackNamespace: kubeconfigDefaultNamespace, disco: d}, nil
}
return &namespaceViaDiscovery{fallbackNamespace: defaultFallbackNamespace, disco: d}, nil
}

// getDefaultNamespace returns the fallback namespace used by the
// when a namespaced resource doesn't have one specified. This is
// used when syncing to anticipate the identity of a resource in the
// cluster given the manifest from a file (which may be missing the
// namespace).
// getKubeconfigDefaultNamespace returns the namespace specified
// for the current config in KUBECONFIG
// A variable is used for mocking in tests.
var getDefaultNamespace = func() (string, error) {
var getKubeconfigDefaultNamespace = func() (string, error) {
config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
clientcmd.NewDefaultClientConfigLoadingRules(),
&clientcmd.ConfigOverrides{},
Expand All @@ -51,7 +58,7 @@ var getDefaultNamespace = func() (string, error) {
return c.Namespace, nil
}

return defaultFallbackNamespace, nil
return "", nil
}

// effectiveNamespace yields the namespace that would be used for this
Expand Down
29 changes: 19 additions & 10 deletions pkg/cluster/kubernetes/namespacer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,14 @@ users: []
defer os.Unsetenv("KUBECONFIG")
coreClient := makeFakeClient()

ns, err := getDefaultNamespace()
ns, err := getKubeconfigDefaultNamespace()
if err != nil {
t.Fatal("cannot get default namespace")
}
if ns != "namespace" {
t.Fatal("unexpected default namespace", ns)
}

nser, err := NewNamespacer(coreClient.Discovery())
if err != nil {
t.Fatal(err)
}

const defs = `---
apiVersion: apps/v1
kind: Deployment
Expand All @@ -101,7 +96,11 @@ metadata:
t.Fatal(err)
}

assertEffectiveNamespace := func(id, expected string) {
defaultNser, err := NewNamespacer(coreClient.Discovery(), "")
if err != nil {
t.Fatal(err)
}
assertEffectiveNamespace := func(nser namespaceViaDiscovery, id, expected string) {
res, ok := manifests[id]
if !ok {
t.Errorf("manifest for %q not found", id)
Expand All @@ -117,7 +116,17 @@ metadata:
}
}

assertEffectiveNamespace("foo-ns:deployment/hasNamespace", "foo-ns")
assertEffectiveNamespace("<cluster>:deployment/noNamespace", "namespace")
assertEffectiveNamespace("spurious:namespace/notNamespaced", "")
assertEffectiveNamespace(*defaultNser, "foo-ns:deployment/hasNamespace", "foo-ns")
assertEffectiveNamespace(*defaultNser, "<cluster>:deployment/noNamespace", "namespace")
assertEffectiveNamespace(*defaultNser, "spurious:namespace/notNamespaced", "")

overrideNser, err := NewNamespacer(coreClient.Discovery(), "foo-override")
if err != nil {
t.Fatal(err)
}

assertEffectiveNamespace(*overrideNser, "foo-ns:deployment/hasNamespace", "foo-ns")
assertEffectiveNamespace(*overrideNser, "<cluster>:deployment/noNamespace", "foo-override")
assertEffectiveNamespace(*overrideNser, "spurious:namespace/notNamespaced", "")

}
10 changes: 5 additions & 5 deletions pkg/cluster/kubernetes/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"strings"
"testing"

helmopfake "github.com/fluxcd/helm-operator/pkg/client/clientset/versioned/fake"
"github.com/ghodss/yaml"
"github.com/go-kit/kit/log"
"github.com/stretchr/testify/assert"
Expand All @@ -30,6 +29,7 @@ import (
kresource "github.com/fluxcd/flux/pkg/cluster/kubernetes/resource"
"github.com/fluxcd/flux/pkg/resource"
"github.com/fluxcd/flux/pkg/sync"
helmopfake "github.com/fluxcd/helm-operator/pkg/client/clientset/versioned/fake"
)

const (
Expand Down Expand Up @@ -363,10 +363,10 @@ metadata:
}

test := func(t *testing.T, kube *Cluster, defs, expectedAfterSync string, expectErrors bool) {
saved := getDefaultNamespace
getDefaultNamespace = func() (string, error) { return defaultTestNamespace, nil }
defer func() { getDefaultNamespace = saved }()
namespacer, err := NewNamespacer(kube.client.coreClient.Discovery())
saved := getKubeconfigDefaultNamespace
getKubeconfigDefaultNamespace = func() (string, error) { return defaultTestNamespace, nil }
defer func() { getKubeconfigDefaultNamespace = saved }()
namespacer, err := NewNamespacer(kube.client.coreClient.Discovery(), "")
if err != nil {
t.Fatal(err)
}
Expand Down