Skip to content
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

Support specifying the transfer net by configmap #1241

Closed
wants to merge 2 commits into from
Closed
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
57 changes: 52 additions & 5 deletions pkg/controller/plan/kubevirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import (
"context"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
Expand Down Expand Up @@ -53,7 +54,9 @@

// Annotations
const (
// Transfer network annotation (value=network-attachment-definition name)
// Legacy transfer network annotation
AnnMultusDefaultNetwork = "v1.multus-cni.io/default-network"
// Transfer network annotation (value=[]NetworkSelectionElement)
AnnTransferNetwork = "k8s.v1.cni.cncf.io/networks"
// Contains validations for a Kubevirt VM. Needs to be removed when
// creating a VM from a template.
Expand Down Expand Up @@ -1227,8 +1230,10 @@
annotations[planbase.AnnRetainAfterCompletion] = "true"
}
if r.Plan.Spec.TransferNetwork != nil {
annotations[AnnTransferNetwork] = path.Join(
r.Plan.Spec.TransferNetwork.Namespace, r.Plan.Spec.TransferNetwork.Name)
err = r.setTransferNetworkAnnotation(annotations)
if err != nil {
return
}
}
if r.Plan.Spec.Warm || !r.Destination.Provider.IsHost() || r.Plan.IsSourceProviderOCP() {
// Set annotation for WFFC storage classes. Note that we create data volumes while
Expand Down Expand Up @@ -1757,8 +1762,10 @@
// pod annotations
annotations := map[string]string{}
if r.Plan.Spec.TransferNetwork != nil {
annotations[AnnTransferNetwork] = path.Join(
r.Plan.Spec.TransferNetwork.Namespace, r.Plan.Spec.TransferNetwork.Name)
err = r.setTransferNetworkAnnotation(annotations)
if err != nil {
return
}
}
// pod
pod = &core.Pod{
Expand Down Expand Up @@ -2351,6 +2358,46 @@
return
}

// Set the transfer network annotation (either the namespaced name of the NAD, or a NetworkSelectionElement)
func (r *KubeVirt) setTransferNetworkAnnotation(annotations map[string]string) (err error) {
if r.Plan.Spec.TransferNetwork != nil {
switch r.Plan.Spec.TransferNetwork.Kind {
case ConfigMap:
var configMap *core.ConfigMap
configMap, err = r.getTransferNetworkConfigMap()

Check failure on line 2367 in pkg/controller/plan/kubevirt.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to err (ineffassign)
var bytes []byte
bytes, err = json.Marshal([]map[string]string{configMap.Data})
if err != nil {
err = liberr.Wrap(err)
return
}
annotations[AnnTransferNetwork] = fmt.Sprintf("%s", bytes)

Check failure on line 2374 in pkg/controller/plan/kubevirt.go

View workflow job for this annotation

GitHub Actions / lint

S1025: the argument's underlying type is a slice of bytes, should use a simple conversion instead of fmt.Sprintf (gosimple)
if err != nil {
return
}
default:
annotations[AnnMultusDefaultNetwork] = path.Join(
r.Plan.Spec.TransferNetwork.Namespace, r.Plan.Spec.TransferNetwork.Name)
}
}
return
}

// Get the configMap containing the NetworkSelectionElement for the transfer network.
func (r *KubeVirt) getTransferNetworkConfigMap() (configMap *core.ConfigMap, err error) {
configMap = &core.ConfigMap{}
err = r.Client.Get(
context.TODO(),
client.ObjectKey{Name: r.Plan.Spec.TransferNetwork.Name, Namespace: r.Plan.Spec.TransferNetwork.Namespace},
configMap,
)
if err != nil {
err = liberr.Wrap(err)
return
}
return
}

// Represents a CDI DataVolume, its associated PVC, and added behavior.
type ExtendedDataVolume struct {
*cdi.DataVolume
Expand Down
91 changes: 83 additions & 8 deletions pkg/controller/plan/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"path"
Expand Down Expand Up @@ -104,6 +105,12 @@
False = libcnd.False
)

// Kinds
const (
ConfigMap = "ConfigMap"
NetworkAttachmentDefinition = "NetworkAttachmentDefinition"
)

// Validate the plan resource.
func (r *Reconciler) validate(plan *api.Plan) error {
// Provider.
Expand Down Expand Up @@ -628,29 +635,97 @@
return nil
}

// Validate transfer network selection.
func (r *Reconciler) validateTransferNetwork(plan *api.Plan) (err error) {
if plan.Spec.TransferNetwork == nil {
// validateTransferNetworkConfigMap checks for the presence of a configMap matching the specified
// namespace and name, checks that the content is a valid NetworkSelectionElement, and then ensures
// that the NetworkAttachmentDefinition specified by the NSE exists.
func (r *Reconciler) validateTransferNetworkConfigMap(plan *api.Plan, key client.ObjectKey) (err error) {
notFound := libcnd.Condition{
Type: TransferNetNotValid,
Status: True,
Category: Critical,
Reason: NotFound,
Message: "Transfer network ConfigMap could not be found.",
}
notValid := libcnd.Condition{
Type: TransferNetNotValid,
Status: True,
Category: Critical,
Reason: NotValid,
Message: "Transfer network ConfigMap not valid.",
}
configMap := &v1.ConfigMap{}
err = r.Get(context.TODO(), key, configMap)
if err != nil {
if k8serr.IsNotFound(err) {
err = nil
plan.Status.SetCondition(notFound)
return
}
return
}
var bytes []byte
bytes, err = json.Marshal(configMap.Data)
if err != nil {
err = nil
plan.Status.SetCondition(notValid)
return

Check failure on line 671 in pkg/controller/plan/validation.go

View workflow job for this annotation

GitHub Actions / lint

error is not nil (line 667) but it returns nil (nilerr)
}
var nse net.NetworkSelectionElement
err = json.Unmarshal(bytes, &nse)
if err != nil {
err = nil
plan.Status.SetCondition(notValid)
return

Check failure on line 678 in pkg/controller/plan/validation.go

View workflow job for this annotation

GitHub Actions / lint

error is not nil (line 674) but it returns nil (nilerr)
}
key.Namespace = nse.Namespace
key.Name = nse.Name
err = r.validateTransferNetworkAttachmentDefinition(plan, key)
return
}

func (r *Reconciler) validateTransferNetworkAttachmentDefinition(plan *api.Plan, key client.ObjectKey) (err error) {
notFound := libcnd.Condition{
Type: TransferNetNotValid,
Status: True,
Category: Critical,
Reason: NotFound,
Message: "Transfer network is not valid.",
}
key := client.ObjectKey{
Namespace: plan.Spec.TransferNetwork.Namespace,
Name: plan.Spec.TransferNetwork.Name,
Message: "Transfer network could not be found.",
}
netAttachDef := &net.NetworkAttachmentDefinition{}
err = r.Get(context.TODO(), key, netAttachDef)
if k8serr.IsNotFound(err) {
err = nil
plan.Status.SetCondition(notFound)
}
return
}

// Validate transfer network selection.
func (r *Reconciler) validateTransferNetwork(plan *api.Plan) (err error) {
if plan.Spec.TransferNetwork == nil {
return
}

key := client.ObjectKey{
Namespace: plan.Spec.TransferNetwork.Namespace,
Name: plan.Spec.TransferNetwork.Name,
}

switch plan.Spec.TransferNetwork.Kind {
case ConfigMap:
err = r.validateTransferNetworkConfigMap(plan, key)
case "", NetworkAttachmentDefinition:
err = r.validateTransferNetworkAttachmentDefinition(plan, key)
default:
unsupported := libcnd.Condition{
Type: TransferNetNotValid,
Status: True,
Category: Critical,
Reason: NotSupported,
Message: "Unsupported transfer network reference Kind.",
}
plan.Status.SetCondition(unsupported)
}
if err != nil {
err = liberr.Wrap(err)
}
Expand Down
Loading