10000 Select remote namespace name when offloading by aleoli · Pull Request #2310 · liqotech/liqo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Select remote namespace name when offloading #2310

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 1 commit into from
Feb 5, 2024
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
9 changes: 8 additions & 1 deletion apis/offloading/v1alpha1/namespaceoffloading_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ const (
// DefaultNameMappingStrategyType -> the remote namespace is assigned a default name which ensures uniqueness
// and avoids conflicts (localNamespaceName-localClusterID).
DefaultNameMappingStrategyType NamespaceMappingStrategyType = "DefaultName"
// SelectedNameMappingStrategyType -> the remote namespace is assigned a name chosen by the user.
// (the creation may fail in case of conflicts).
SelectedNameMappingStrategyType NamespaceMappingStrategyType = "SelectedName"
)

// PodOffloadingStrategyType represents different strategies to offload pods in this Namespace.
Expand Down Expand Up @@ -97,11 +100,15 @@ type NamespaceOffloadingSpec struct {
// NamespaceMappingStrategy allows users to map local and remote namespace names according to two
// different strategies: "DefaultName", which ensures uniqueness and prevents conflicts, and "EnforceSameName",
// which enforces the same name at the cost of possible conflicts.
// +kubebuilder:validation:Enum="EnforceSameName";"DefaultName"
// +kubebuilder:validation:Enum="EnforceSameName";"DefaultName";"SelectedName"
// +kubebuilder:default="DefaultName"
// +kubebuilder:validation:Optional
NamespaceMappingStrategy NamespaceMappingStrategyType `json:"namespaceMappingStrategy"`

// RemoteNamespaceName allows users to choose a specific name for the remote namespace.
// This field is required if NamespaceMappingStrategy is set to "SelectedName". It is ignored otherwise.
RemoteNamespaceName string `json:"remoteNamespaceName,omitempty"`

// PodOffloadingStrategy allows users to configure how pods in this namespace are offloaded, according to three
// different strategies: "Local" (i.e. no pod offloading is performed), "Remote" (i.e. all pods are offloaded
// in remote clusters), "LocalAndRemote" (i.e. no constraints are enforced besides the ones
Expand Down
11 changes: 9 additions & 2 deletions cmd/liqoctl/cmd/offload.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,12 @@ func newOffloadNamespaceCommand(ctx context.Context, f *factory.Factory) *cobra.

namespaceMappingStrategy := args.NewEnum([]string{
string(offloadingv1alpha1.EnforceSameNameMappingStrategyType),
string(offloadingv1alpha1.DefaultNameMappingStrategyType)},
string(offloadingv1alpha1.DefaultNameMappingStrategyType),
string(offloadingv1alpha1.SelectedNameMappingStrategyType)},
string(offloadingv1alpha1.DefaultNameMappingStrategyType))

var remoteNamespaceName = ""

outputFormat := args.NewEnum([]string{"json", "yaml"}, "")

options := offload.Options{Factory: f}
Expand All @@ -104,6 +107,7 @@ func newOffloadNamespaceCommand(ctx context.Context, f *factory.Factory) *cobra.
PreRun: func(cmd *cobra.Command, args []string) {
options.PodOffloadingStrategy = offloadingv1alpha1.PodOffloadingStrategyType(podOffloadingStrategy.Value)
options.NamespaceMappingStrategy = offloadingv1alpha1.NamespaceMappingStrategyType(namespaceMappingStrategy.Value)
options.RemoteNamespaceName = remoteNamespaceName
options.OutputFormat = outputFormat.Value
options.Printer.CheckErr(options.ParseClusterSelectors(selectors))
},
Expand All @@ -117,8 +121,11 @@ func newOffloadNamespaceCommand(ctx context.Context, f *factory.Factory) *cobra.
cmd.Flags().Var(podOffloadingStrategy, "pod-offloading-strategy",
"The constraints regarding pods scheduling in this namespace, among Local, Remote and LocalAndRemote")
cmd.Flags().Var(namespaceMappingStrategy, "namespace-mapping-strategy",
"The naming strategy adopted for the creation of remote namespaces, among DefaultName and EnforceSameName")
"The naming strategy adopted for the creation of remote namespaces, among DefaultName, EnforceSameName and SelectedName")
cmd.Flags().DurationVar(&options.Timeout, "timeout", 20*time.Second, "The timeout for the offloading process")
cmd.Flags().StringVar(&remoteNamespaceName, "remote-namespace-name", "",
"The name of the remote namespace, required when using the SelectedName NamespaceMappingStrategy. "+
"Otherwise, it is ignored")

cmd.Flags().StringArrayVarP(&selectors, "selector", "l", []string{},
"The selector to filter the target clusters. Can be specified multiple times, defining alternative requirements (i.e., in logical OR)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ spec:
enum:
- EnforceSameName
- DefaultName
- SelectedName
type: string
podOffloadingStrategy:
default: LocalAndRemote
Expand All @@ -166,6 +167,11 @@ spec:
- Remote
- LocalAndRemote
type: string
remoteNamespaceName:
description: RemoteNamespaceName allows users to choose a specific
name for the remote namespace. This field is required if NamespaceMappingStrategy
is set to "SelectedName". It is ignored otherwise.
type: string
type: object
status:
description: NamespaceOffloadingStatus defines the observed state of NamespaceOffloading.
Expand Down
2 changes: 2 additions & 0 deletions docs/usage/namespace-offloading.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ The accepted values are:
* **EnforceSameName**: remote namespaces are named after the local cluster's namespace.
This approach ensures **naming transparency**, which is required by certain applications, as well as guarantees that **cross-namespace DNS queries** referring to reflected services work out of the box (i.e., without adapting the target namespace name).
Yet, it can lead to **conflicts** in case a namespace with the same name already exists inside the selected remote clusters, ultimately causing the remote namespace creation request to be rejected.
* **SelectedName**: you can specify the name of the remote namespace through the `--remote-namespace-name` flag.
This flag is ignored in case the *namespace mapping strategy* is set to *DefaultName* or *EnforceSameName*.

```{admonition} Note
Once configured for a given namespace, the *namespace mapping strategy* is **immutable**, and any modification is prevented by a dedicated Liqo webhook.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,18 @@ func (r *NamespaceOffloadingReconciler) enforceStatus(ctx context.Context, nsoff

// remoteNamespaceName returns the remapped name corresponding to a given namespace.
func (r *NamespaceOffloadingReconciler) remoteNamespaceName(nsoff *offv1alpha1.NamespaceOffloading) string {
if nsoff.Spec.NamespaceMappingStrategy == offv1alpha1.EnforceSameNameMappingStrategyType {
switch nsoff.Spec.NamespaceMappingStrategy {
case offv1alpha1.EnforceSameNameMappingStrategyType:
return nsoff.Namespace
case offv1alpha1.DefaultNameMappingStrategyType:
return nsoff.Namespace + "-" + foreignclusterutils.UniqueName(&r.LocalCluster)
case offv1alpha1.SelectedNameMappingStrategyType:
return nsoff.Spec.RemoteNamespaceName
default:
klog.Errorf("NamespaceOffloading %q: unknown NamespaceMappingStrategy %q, falling back to %q",
klog.KObj(nsoff), nsoff.Spec.NamespaceMappingStrategy, offv1alpha1.DefaultNameMappingStrategyType)
return nsoff.Namespace + "-" + foreignclusterutils.UniqueName(&r.LocalCluster)
}

return nsoff.Namespace + "-" + foreignclusterutils.UniqueName(&r.LocalCluster)
}

// ensureRemoteConditionsConsistence checks for every remote condition of the NamespaceOffloading resource that the
Expand Down
26 changes: 23 additions & 3 deletions pkg/liqo-controller-manager/webhooks/namespaceoffloading/nsoff.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ func (w *nsoffwh) DecodeNamespaceOffloading(obj runtime.RawExtension) (*offv1alp
//
//nolint:gocritic // The signature of this method is imposed by controller runtime.
func (w *nsoffwh) Handle(ctx context.Context, req admission.Request) admission.Response {
var warnings []string

nsoff, err := w.DecodeNamespaceOffloading(req.Object)
if err != nil {
klog.Errorf("Failed decoding NamespaceOffloading object: %v", err)
Expand All @@ -63,9 +61,27 @@ func (w *nsoffwh) Handle(ctx context.Context, req admission.Request) admission.R
return admission.Denied("NamespaceOffloading name must match " + consts.DefaultNamespaceOffloadingName)
}

if req.Operation != admissionv1.Update {
switch req.Operation {
case admissionv1.Create:
return w.handleCreate(ctx, &req, nsoff)
case admissionv1.Update:
return w.handleUpdate(ctx, &req, nsoff)
default:
return admission.Allowed("")
}
}

func (w *nsoffwh) handleCreate(_ context.Context, _ *admission.Request, nsoff *offv1alpha1.NamespaceOffloading) admission.Response {
if nsoff.Spec.NamespaceMappingStrategy == offv1alpha1.SelectedNameMappingStrategyType &&
nsoff.Spec.RemoteNamespaceName == "" {
return admission.Denied("The RemoteNamespaceName value cannot be empty when using the SelectedName NamespaceMappingStrategy")
}

return admission.Allowed("")
}

func (w *nsoffwh) handleUpdate(_ context.Context, req *admission.Request, nsoff *offv1alpha1.NamespaceOffloading) admission.Response {
var warnings []string

// In case of updates, validate the modified fields.
old, err := w.DecodeNamespaceOffloading(req.OldObject)
Expand All @@ -78,6 +94,10 @@ func (w *nsoffwh) Handle(ctx context.Context, req admission.Request) admission.R
return admission.Denied("The NamespaceMappingStrategy value cannot be modified after creation")
}

if old.Spec.RemoteNamespaceName != nsoff.Spec.RemoteNamespaceName {
return admission.Denied("The RemoteNamespaceName value cannot be modified after creation")
}

if nsoff.Spec.PodOffloadingStrategy != offv1alpha1.LocalAndRemotePodOffloadingStrategyType &&
old.Spec.PodOffloadingStrategy != nsoff.Spec.PodOffloadingStrategy {
const msg = "The PodOffloadingStrategy was mutated to a more restrictive setting: existing pods violating this policy might still be running"
Expand Down
3 changes: 3 additions & 0 deletions pkg/liqoctl/offload/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Options struct {
Namespace string
PodOffloadingStrategy offloadingv1alpha1.PodOffloadingStrategyType
NamespaceMappingStrategy offloadingv1alpha1.NamespaceMappingStrategyType
RemoteNamespaceName string
ClusterSelector [][]metav1.LabelSelectorRequirement

OutputFormat string
Expand Down Expand Up @@ -87,6 +88,7 @@ func (o *Options) Run(ctx context.Context) error {
oldStrategy = nsoff.Spec.PodOffloadingStrategy
nsoff.Spec.PodOffloadingStrategy = o.PodOffloadingStrategy
nsoff.Spec.NamespaceMappingStrategy = o.NamespaceMappingStrategy
nsoff.Spec.RemoteNamespaceName = o.RemoteNamespaceName
nsoff.Spec.ClusterSelector = toNodeSelector(o.ClusterSelector)
return nil
})
Expand Down Expand Up @@ -132,6 +134,7 @@ func (o *Options) output() error {
Spec: offloadingv1alpha1.NamespaceOffloadingSpec{
PodOffloadingStrategy: o.PodOffloadingStrategy,
NamespaceMappingStrategy: o.NamespaceMappingStrategy,
RemoteNamespaceName: o.RemoteNamespaceName,
ClusterSelector: toNodeSelector(o.ClusterSelector),
},
}
Expand Down
0