Skip to content

feat: Configure namespace sync in helm chart #726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
6 changes: 0 additions & 6 deletions api/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,4 @@ const (
GlobalMirrorVariableName = "globalImageRegistryMirror"
// ImageRegistriesVariableName is the image registries patch variable name.
ImageRegistriesVariableName = "imageRegistries"

// NamespaceSyncLabelKey is a label that can be applied to a namespace.
//
// When a namespace has a label with this key, ClusterClasses and their Templates are
// copied to the namespace from a source namespace. The copies are not updated or deleted.
NamespaceSyncLabelKey = "caren.nutanix.com/namespace-sync"
)
3 changes: 3 additions & 0 deletions charts/cluster-api-runtime-extensions-nutanix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ A Helm chart for cluster-api-runtime-extensions-nutanix
| image.repository | string | `"ghcr.io/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix"` | |
| image.tag | string | `""` | |
| imagePullSecrets | list | `[]` | Optional secrets used for pulling the container image |
| namespaceSync.enabled | bool | `true` | |
| namespaceSync.sourceNamespace | string | `""` | |
| namespaceSync.targetNamespaceLabelKey | string | `"caren.nutanix.com/namespace-sync"` | |
| nodeSelector | object | `{}` | |
| priorityClassName | string | `"system-cluster-critical"` | Priority class to be used for the pod. |
| resources.limits.cpu | string | `"100m"` | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ spec:
args:
- --webhook-cert-dir=/runtimehooks-certs/
- --defaults-namespace=$(POD_NAMESPACE)
- --namespacesync-enabled={{ .Values.namespaceSync.enabled }}
- --namespacesync-source-namespace={{ .Values.namespaceSync.sourceNamespace | default .Release.Namespace }}
- --namespacesync-target-namespace-label-key={{ .Values.namespaceSync.targetNamespaceLabelKey }}
- --helm-addons-configmap={{ .Values.helmAddonsConfigMap }}
- --cni.cilium.helm-addon.default-values-template-configmap-name={{ .Values.hooks.cni.cilium.helmAddonStrategy.defaultValueTemplateConfigMap.name }}
- --nfd.helm-addon.default-values-template-configmap-name={{ .Values.hooks.nfd.helmAddonStrategy.defaultValueTemplateConfigMap.name }}
Expand Down
14 changes: 14 additions & 0 deletions charts/cluster-api-runtime-extensions-nutanix/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,20 @@
"imagePullSecrets": {
"type": "array"
},
"namespaceSync": {
"properties": {
"enabled": {
"type": "boolean"
},
"sourceNamespace": {
"type": "string"
},
"targetNamespaceLabelKey": {
"type": "string"
}
},
"type": "object"
},
"nodeSelector": {
"properties": {},
"type": "object"
Expand Down
10 changes: 10 additions & 0 deletions charts/cluster-api-runtime-extensions-nutanix/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ selfHostedRegistry: true

deployDefaultClusterClasses: true

# The ClusterClass and the Templates it references must be in the same namespace
# as the Cluster. To enable cluster creation in user-defined namespaces, CAREN
# will copy all ClusterClasses and Templates from the source namespace to every
# target namespace, i.e., every namespace that has a label with a matching key.
namespaceSync:
enabled: true
targetNamespaceLabelKey: caren.nutanix.com/namespace-sync
# By default, sourceNamespace is the helm release namespace.
sourceNamespace: ""

deployment:
replicas: 1

Expand Down
65 changes: 40 additions & 25 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

caaphv1 "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/external/sigs.k8s.io/cluster-api-addon-provider-helm/api/v1alpha1"
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1"
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers"
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/server"
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/controllers/namespacesync"
Expand Down Expand Up @@ -148,30 +147,46 @@ func main() {
os.Exit(1)
}

unstructuredCachingClient, err := client.New(mgr.GetConfig(), client.Options{
HTTPClient: mgr.GetHTTPClient(),
Cache: &client.CacheOptions{
Reader: mgr.GetCache(),
Unstructured: true,
},
})
if err != nil {
setupLog.Error(err, "unable to create unstructured caching client")
os.Exit(1)
}

if err := (&namespacesync.Reconciler{
Client: mgr.GetClient(),
UnstructuredCachingClient: unstructuredCachingClient,
SourceClusterClassNamespace: namespacesyncOptions.SourceNamespace,
TargetNamespaceFilter: namespacesync.NamespaceHasLabelKey(v1alpha1.NamespaceSyncLabelKey),
}).SetupWithManager(
signalCtx,
mgr,
controller.Options{MaxConcurrentReconciles: namespacesyncOptions.Concurrency},
); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "namespacesync.Reconciler")
os.Exit(1)
if namespacesyncOptions.Enabled {
if namespacesyncOptions.SourceNamespace == "" ||
namespacesyncOptions.TargetNamespaceLabelKey == "" {
setupLog.Error(
nil,
"Namespace Sync is enabled, but source namespace and/or target namespace label key are not configured.",
)
os.Exit(1)
}

unstructuredCachingClient, err := client.New(mgr.GetConfig(), client.Options{
HTTPClient: mgr.GetHTTPClient(),
Cache: &client.CacheOptions{
Reader: mgr.GetCache(),
Unstructured: true,
},
})
if err != nil {
setupLog.Error(err, "unable to create unstructured caching client")
os.Exit(1)
}

if err := (&namespacesync.Reconciler{
Client: mgr.GetClient(),
UnstructuredCachingClient: unstructuredCachingClient,
SourceClusterClassNamespace: namespacesyncOptions.SourceNamespace,
TargetNamespaceFilter: namespacesync.NamespaceHasLabelKey(namespacesyncOptions.TargetNamespaceLabelKey),
}).SetupWithManager(
signalCtx,
mgr,
controller.Options{MaxConcurrentReconciles: namespacesyncOptions.Concurrency},
); err != nil {
setupLog.Error(
err,
"unable to create controller",
"controller",
"namespacesync.Reconciler",
)
os.Exit(1)
}
}

if err := mgr.Start(signalCtx); err != nil {
Expand Down
24 changes: 20 additions & 4 deletions pkg/controllers/namespacesync/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@ package namespacesync

import (
"github.com/spf13/pflag"
corev1 "k8s.io/api/core/v1"
)

type Options struct {
Concurrency int
SourceNamespace string
Enabled bool
Concurrency int
SourceNamespace string
TargetNamespaceLabelKey string
}

func (o *Options) AddFlags(flags *pflag.FlagSet) {
pflag.CommandLine.BoolVar(
&o.Enabled,
"namespacesync-enabled",
false,
"Enable copying of ClusterClasses and Templates from a source namespace to one or more target namespaces.",
)

pflag.CommandLine.IntVar(
&o.Concurrency,
"namespacesync-concurrency",
Expand All @@ -24,6 +32,14 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) {
pflag.CommandLine.StringVar(
&o.SourceNamespace,
"namespacesync-source-namespace",
corev1.NamespaceDefault, "Namespace from which ClusterClasses and Templates are copied.",
"",
"Namespace from which ClusterClasses and Templates are copied.",
)

pflag.CommandLine.StringVar(
&o.TargetNamespaceLabelKey,
"namespacesync-target-namespace-label-key",
"",
"Label key to determine if a namespace is a target. If a namespace has a label with this key, copy ClusterClasses and Templates to it from the source namespace.", //nolint:lll // Output will be wrapped.
)
}
Loading