diff --git a/fleetconfig-controller/charts/fleetconfig-controller/README.md b/fleetconfig-controller/charts/fleetconfig-controller/README.md index d02388e2..75d7b4ca 100644 --- a/fleetconfig-controller/charts/fleetconfig-controller/README.md +++ b/fleetconfig-controller/charts/fleetconfig-controller/README.md @@ -100,7 +100,6 @@ Resource specifications for all klusterlet-managed containers. | `fleetConfig.hub.kubeconfig.context` | The context to use in the kubeconfig file. Leave empty to use the current context. | `""` | | `fleetConfig.hub.kubeconfig.inCluster` | If set, the kubeconfig will be read from the cluster. Only applicable for same-cluster operations. | `true` | | `fleetConfig.hub.kubeconfig.secretReference.name` | The name of the secret. | `""` | -| `fleetConfig.hub.kubeconfig.secretReference.namespace` | The namespace the secret is in. | `""` | | `fleetConfig.hub.kubeconfig.secretReference.kubeconfigKey` | The map key to access the kubeconfig. | `kubeconfig` | | `fleetConfig.hub.singletonControlPlane.enabled` | Whether to enable the singleton control plane. Set to false if using Cluster Manager. | `false` | | `fleetConfig.hub.singletonControlPlane.name` | The name of the singleton control plane. | `singleton-controlplane` | @@ -121,7 +120,6 @@ Resource specifications for all klusterlet-managed containers. | `fleetConfig.spokes[0].kubeconfig.context` | The context to use in the kubeconfig file. Leave empty to use the current context. | `""` | | `fleetConfig.spokes[0].kubeconfig.inCluster` | If set, the kubeconfig will be read from the cluster. Only applicable for same-cluster operations. | `true` | | `fleetConfig.spokes[0].kubeconfig.secretReference.name` | The name of the secret. | `""` | -| `fleetConfig.spokes[0].kubeconfig.secretReference.namespace` | The namespace the secret is in. | `""` | | `fleetConfig.spokes[0].kubeconfig.secretReference.kubeconfigKey` | The map key to access the kubeconfig. | `kubeconfig` | | `fleetConfig.spokes[0].proxyCa` | Proxy CA certificate, optional. | `""` | | `fleetConfig.spokes[0].proxyUrl` | URL of a forward proxy server used by agents to connect to the Hub cluster, optional. | `""` | @@ -131,7 +129,6 @@ Resource specifications for all klusterlet-managed containers. | `fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.context` | The context to use in the kubeconfig file. | `""` | | `fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.inCluster` | If set, the kubeconfig will be read from the cluster. Only applicable for same-cluster operations. | `false` | | `fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.secretReference.name` | The name of the secret. | `""` | -| `fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.secretReference.namespace` | The namespace the secret is in. | `""` | | `fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.secretReference.kubeconfigKey` | The map key to access the kubeconfig. | `kubeconfig` | | `fleetConfig.spokes[0].klusterlet.forceInternalEndpointLookupManaged` | If true, the klusterlet accesses the managed cluster using the internal endpoint from the public cluster-info in the managed cluster instead of using managedClusterKubeconfig. | `false` | | `fleetConfig.spokes[0].klusterlet.resources.limits.cpu` | The number of CPU units to request, e.g., '800m'. | `""` | diff --git a/fleetconfig-controller/charts/fleetconfig-controller/templates/fleetconfig.yaml b/fleetconfig-controller/charts/fleetconfig-controller/templates/fleetconfig.yaml index 343481cb..0ad501f1 100644 --- a/fleetconfig-controller/charts/fleetconfig-controller/templates/fleetconfig.yaml +++ b/fleetconfig-controller/charts/fleetconfig-controller/templates/fleetconfig.yaml @@ -40,9 +40,12 @@ spec: createNamespace: {{ .Values.fleetConfig.hub.createNamespace }} force: {{ .Values.fleetConfig.hub.force }} {{- with .Values.fleetConfig.hub.kubeconfig }} + {{- if and .inCluster (and .secretReference (not (empty .secretReference.name))) }} + {{- fail "hub.kubeconfig.inCluster and hub.kubeconfig.secretReference are mutually exclusive" }} + {{- end }} kubeconfig: - context: {{ .context | quote }} - inCluster: {{ .inCluster }} + context: {{ default "" .context | quote }} + inCluster: {{ default false .inCluster }} {{- if and .secretReference (not (empty .secretReference.name)) }} secretReference: {{ toYaml .secretReference | nindent 6 }} {{- end }} @@ -82,8 +85,11 @@ spec: createNamespace: {{ .createNamespace }} syncLabels: {{ .syncLabels }} {{- with .kubeconfig }} + {{- if and .inCluster (and .secretReference (not (empty .secretReference.name))) }} + {{- fail "spoke.kubeconfig.inCluster and spoke.kubeconfig.secretReference are mutually exclusive" }} + {{- end }} kubeconfig: - context: {{ .context | quote }} + context: {{ default "" .context | quote }} inCluster: {{ .inCluster }} {{- if and .secretReference (not (empty .secretReference.name)) }} secretReference: {{ toYaml .secretReference | nindent 6 }} @@ -108,9 +114,12 @@ spec: forceInternalEndpointLookupManaged: {{ .klusterlet.forceInternalEndpointLookupManaged }} singleton: {{ .klusterlet.singleton }} {{- $mck := .klusterlet.managedClusterKubeconfig -}} + {{- if and $mck.inCluster (and $mck.secretReference (not (empty $mck.secretReference.name))) }} + {{- fail "spoke.klusterlet.managedClusterKubeconfig.inCluster and spoke.klusterlet.managedClusterKubeconfig.secretReference are mutually exclusive" }} + {{- end }} {{- if or $mck.context $mck.inCluster (and $mck.secretReference (not (empty $mck.secretReference.name))) }} managedClusterKubeconfig: - context: {{ $mck.context | quote }} + context: {{ default "" $mck.context | quote }} inCluster: {{ $mck.inCluster }} {{- if and $mck.secretReference (not (empty $mck.secretReference.name)) }} secretReference: {{ toYaml $mck.secretReference | nindent 8 }} diff --git a/fleetconfig-controller/charts/fleetconfig-controller/values.yaml b/fleetconfig-controller/charts/fleetconfig-controller/values.yaml index e3f3066a..13601397 100644 --- a/fleetconfig-controller/charts/fleetconfig-controller/values.yaml +++ b/fleetconfig-controller/charts/fleetconfig-controller/values.yaml @@ -138,8 +138,6 @@ fleetConfig: secretReference: ## @param fleetConfig.hub.kubeconfig.secretReference.name The name of the secret. name: "" - ## @param fleetConfig.hub.kubeconfig.secretReference.namespace The namespace the secret is in. - namespace: "" ## @param fleetConfig.hub.kubeconfig.secretReference.kubeconfigKey The map key to access the kubeconfig. kubeconfigKey: "kubeconfig" ## @descriptionStart @@ -189,7 +187,6 @@ fleetConfig: ## @param fleetConfig.spokes[0].kubeconfig.context The context to use in the kubeconfig file. Leave empty to use the current context. ## @param fleetConfig.spokes[0].kubeconfig.inCluster If set, the kubeconfig will be read from the cluster. Only applicable for same-cluster operations. ## @param fleetConfig.spokes[0].kubeconfig.secretReference.name The name of the secret. - ## @param fleetConfig.spokes[0].kubeconfig.secretReference.namespace The namespace the secret is in. ## @param fleetConfig.spokes[0].kubeconfig.secretReference.kubeconfigKey The map key to access the kubeconfig. ## @param fleetConfig.spokes[0].proxyCa Proxy CA certificate, optional. ## @param fleetConfig.spokes[0].proxyUrl URL of a forward proxy server used by agents to connect to the Hub cluster, optional. @@ -199,7 +196,6 @@ fleetConfig: ## @param fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.context The context to use in the kubeconfig file. ## @param fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.inCluster If set, the kubeconfig will be read from the cluster. Only applicable for same-cluster operations. ## @param fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.secretReference.name The name of the secret. - ## @param fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.secretReference.namespace The namespace the secret is in. ## @param fleetConfig.spokes[0].klusterlet.managedClusterKubeconfig.secretReference.kubeconfigKey The map key to access the kubeconfig. ## @param fleetConfig.spokes[0].klusterlet.forceInternalEndpointLookupManaged If true, the klusterlet accesses the managed cluster using the internal endpoint from the public cluster-info in the managed cluster instead of using managedClusterKubeconfig. ## @param fleetConfig.spokes[0].klusterlet.resources.limits.cpu The number of CPU units to request, e.g., '800m'. @@ -227,7 +223,6 @@ fleetConfig: ## A reference to an existing secret containing a kubeconfig. Must be provided for remote clusters. For same-cluster, must be provided unless InCluster is set to true. secretReference: name: "" - namespace: "" kubeconfigKey: "kubeconfig" proxyCa: "" proxyUrl: "" @@ -244,7 +239,6 @@ fleetConfig: inCluster: false secretReference: name: "" - namespace: "" kubeconfigKey: "kubeconfig" forceInternalEndpointLookupManaged: false ## @descriptionStart diff --git a/fleetconfig-controller/internal/controller/v1beta1/spoke_handler.go b/fleetconfig-controller/internal/controller/v1beta1/spoke_handler.go index 98661e5b..71e352fc 100644 --- a/fleetconfig-controller/internal/controller/v1beta1/spoke_handler.go +++ b/fleetconfig-controller/internal/controller/v1beta1/spoke_handler.go @@ -170,17 +170,14 @@ func (r *SpokeReconciler) doHubWork(ctx context.Context, spoke *v1beta1.Spoke, h logger.Error(err, "failed to get managedCluster after join", "spoke", spoke.Name) return err } + } - // precreate the namespace that the agent will be installed into - // this prevents it from being automatically garbage collected when the spoke is deregistered - if r.InstanceType != v1beta1.InstanceTypeUnified { - err = r.createAgentNamespace(ctx, spoke.Name, spokeKubeconfig) - if err != nil { - logger.Error(err, "failed to create agent namespace", "spoke", spoke.Name) - return err - } - } - + // precreate the namespace that the agent will be installed into + // this prevents it from being automatically garbage collected when the spoke is deregistered + err = r.createAgentNamespace(ctx, spoke) + if err != nil { + logger.Error(err, "failed to create agent namespace", "spoke", spoke.Name) + return err } // check managed clusters joined condition @@ -279,8 +276,18 @@ func (r *SpokeReconciler) doHubWork(ctx context.Context, spoke *v1beta1.Spoke, h return nil } -func (r *SpokeReconciler) createAgentNamespace(ctx context.Context, spokeName string, spokeKubeconfig []byte) error { +func (r *SpokeReconciler) createAgentNamespace(ctx context.Context, spoke *v1beta1.Spoke) error { logger := log.FromContext(ctx) + + if r.InstanceType == v1beta1.InstanceTypeUnified || spoke.IsHubAsSpoke() || spoke.PivotComplete() { + return nil + } + + spokeKubeconfig, err := kube.KubeconfigFromSecretOrCluster(ctx, r.Client, spoke.Spec.Kubeconfig, spoke.Namespace) + if err != nil { + return err + } + spokeRestCfg, err := kube.RestConfigFromKubeconfig(spokeKubeconfig) if err != nil { return err @@ -299,7 +306,7 @@ func (r *SpokeReconciler) createAgentNamespace(ctx context.Context, spokeName st if err != nil && !kerrs.IsAlreadyExists(err) { return err } - logger.V(1).Info("agent namespace configured", "spoke", spokeName, "namespace", agentNamespace) + logger.V(1).Info("agent namespace configured", "spoke", spoke.Name, "namespace", agentNamespace) return nil }