From 172b653bad580e15f77076094ca2ff3570b3cfe3 Mon Sep 17 00:00:00 2001 From: Kostiantyn Kalynovskyi Date: Sat, 10 Apr 2021 19:57:04 +0000 Subject: [PATCH] Pass GW IP to vino-builder in networks struct Change-Id: I33e2c855f74b75716dda9e3c081e23c090e7186e --- docs/api/vino.md | 13 +++---- pkg/api/v1/vino_builder.go | 12 +++--- pkg/api/v1/zz_generated.deepcopy.go | 21 ++-------- pkg/controllers/bmh.go | 59 ++++++++++++++++++----------- 4 files changed, 49 insertions(+), 56 deletions(-) diff --git a/docs/api/vino.md b/docs/api/vino.md index af66984..7cfb125 100644 --- a/docs/api/vino.md +++ b/docs/api/vino.md @@ -104,6 +104,7 @@ string

Builder

+

TODO (kkalynovskyi) create an API object for this, and refactor vino-builder to read it from kubernetes.

@@ -128,8 +129,8 @@ string @@ -158,6 +159,7 @@ map[string]./pkg/api/v1.BuilderDomain (Appears on:Builder)

+

BuilderDomain represents a VINO libvirt domain

networks
- -map[string]./pkg/api/v1.BuilderNetwork + +[]Network
@@ -184,12 +186,6 @@ map[string]./pkg/api/v1.BuilderNetworkInterface
-

BuilderNetwork -

-

-(Appears on: -Builder) -

BuilderNetworkInterface

@@ -679,6 +675,7 @@ string

(Appears on: +Builder, VinoSpec)

Network defines libvirt networks

diff --git a/pkg/api/v1/vino_builder.go b/pkg/api/v1/vino_builder.go index 7d31777..3a2bb87 100644 --- a/pkg/api/v1/vino_builder.go +++ b/pkg/api/v1/vino_builder.go @@ -16,20 +16,18 @@ limitations under the License. package v1 +// TODO (kkalynovskyi) create an API object for this, and refactor vino-builder to read it from kubernetes. type Builder struct { - GWIPBridge string `json:"gwIPBridge,omitempty"` - Networks map[string]BuilderNetwork `json:"networks,omitempty"` - Domains map[string]BuilderDomain `json:"domains,omitempty"` + GWIPBridge string `json:"gwIPBridge,omitempty"` + Networks []Network `json:"networks,omitempty"` + Domains map[string]BuilderDomain `json:"domains,omitempty"` } type BuilderNetworkInterface struct { MACAddress string `json:"macAddress,omitempty"` } -type BuilderNetwork struct { - // Placeholder for future development -} - +// BuilderDomain represents a VINO libvirt domain type BuilderDomain struct { Interfaces map[string]BuilderNetworkInterface `json:"interfaces,omitempty"` } diff --git a/pkg/api/v1/zz_generated.deepcopy.go b/pkg/api/v1/zz_generated.deepcopy.go index a97e2fa..b577090 100644 --- a/pkg/api/v1/zz_generated.deepcopy.go +++ b/pkg/api/v1/zz_generated.deepcopy.go @@ -60,9 +60,9 @@ func (in *Builder) DeepCopyInto(out *Builder) { *out = *in if in.Networks != nil { in, out := &in.Networks, &out.Networks - *out = make(map[string]BuilderNetwork, len(*in)) - for key, val := range *in { - (*out)[key] = val + *out = make([]Network, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Domains != nil { @@ -106,21 +106,6 @@ func (in *BuilderDomain) DeepCopy() *BuilderDomain { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BuilderNetwork) DeepCopyInto(out *BuilderNetwork) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BuilderNetwork. -func (in *BuilderNetwork) DeepCopy() *BuilderNetwork { - if in == nil { - return nil - } - out := new(BuilderNetwork) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BuilderNetworkInterface) DeepCopyInto(out *BuilderNetworkInterface) { *out = *in diff --git a/pkg/controllers/bmh.go b/pkg/controllers/bmh.go index 7fd109c..3dfb81a 100644 --- a/pkg/controllers/bmh.go +++ b/pkg/controllers/bmh.go @@ -156,7 +156,7 @@ func (r *VinoReconciler) createBMHperPod(ctx context.Context, vino *vinov1.Vino, return err } - ip, err := r.getBridgeIP(ctx, k8sNode) + nodeNetworks, err := r.nodeNetworks(ctx, vino.Spec.Networks, k8sNode) if err != nil { return err } @@ -173,13 +173,14 @@ func (r *VinoReconciler) createBMHperPod(ctx context.Context, vino *vinov1.Vino, return nodeErr } - values, nodeErr := r.networkValues(ctx, bmhName, ip, node, vino) + domainNetValues, nodeErr := r.domainSpecificNetValues(ctx, bmhName, node, nodeNetworks) if nodeErr != nil { return nodeErr } - nodeNetworkValues[roleSuffix] = values.Generated + // save domain specific generated values to a map + nodeNetworkValues[roleSuffix] = domainNetValues.Generated - netData, netDataNs, nodeErr := r.reconcileBMHNetworkData(ctx, node, vino, values) + netData, netDataNs, nodeErr := r.reconcileBMHNetworkData(ctx, node, vino, domainNetValues) if nodeErr != nil { return nodeErr } @@ -197,9 +198,7 @@ func (r *VinoReconciler) createBMHperPod(ctx context.Context, vino *vinov1.Vino, ObjectMeta: metav1.ObjectMeta{ Name: bmhName, Namespace: getRuntimeNamespace(), - // TODO add rack and server labels, when we crearly define mechanism - // which labels we are copying - Labels: labels, + Labels: labels, }, Spec: metal3.BareMetalHostSpec{ NetworkData: &corev1.SecretReference{ @@ -221,19 +220,38 @@ func (r *VinoReconciler) createBMHperPod(ctx context.Context, vino *vinov1.Vino, } } } + logger.Info("annotating node", "node", k8sNode.Name) - if err = r.annotateNode(ctx, ip, k8sNode, nodeNetworkValues); err != nil { + if err = r.annotateNode(ctx, k8sNode, nodeNetworkValues, nodeNetworks); err != nil { return err } return nil } -func (r *VinoReconciler) networkValues( +// nodeNetworks returns a copy of node network with a unique per node values +func (r *VinoReconciler) nodeNetworks(ctx context.Context, + globalNetworks []vinov1.Network, + k8sNode *corev1.Node) ([]vinov1.Network, error) { + bridgeIP, err := r.getBridgeIP(ctx, k8sNode) + if err != nil { + return []vinov1.Network{}, err + } + + for netIndex, network := range globalNetworks { + for routeIndex, route := range network.Routes { + if route.Gateway == "$vinobridge" { + globalNetworks[netIndex].Routes[routeIndex].Gateway = bridgeIP + } + } + } + return globalNetworks, nil +} + +func (r *VinoReconciler) domainSpecificNetValues( ctx context.Context, bmhName string, - bridgeIP string, node vinov1.NodeSet, - vino *vinov1.Vino) (networkTemplateValues, error) { + networks []vinov1.Network) (networkTemplateValues, error) { // Allocate an IP for each of this BMH's network interfaces ipAddresses := map[string]string{} macAddresses := map[string]string{} @@ -242,12 +260,7 @@ func (r *VinoReconciler) networkValues( subnet := "" var err error subnetRange := vinov1.Range{} - for netIndex, network := range vino.Spec.Networks { - for routeIndex, route := range network.Routes { - if route.Gateway == "$vinobridge" { - vino.Spec.Networks[netIndex].Routes[routeIndex].Gateway = bridgeIP - } - } + for _, network := range networks { if network.Name == networkName { subnet = network.SubNet subnetRange, err = ipam.NewRange(network.AllocationStart, @@ -274,7 +287,7 @@ func (r *VinoReconciler) networkValues( return networkTemplateValues{ Node: node, BMHName: bmhName, - Networks: vino.Spec.Networks, + Networks: networks, Generated: generatedValues{ IPAddresses: ipAddresses, MACAddresses: macAddresses, @@ -283,15 +296,15 @@ func (r *VinoReconciler) networkValues( } func (r *VinoReconciler) annotateNode(ctx context.Context, - gwIP string, k8sNode *corev1.Node, - values map[string]generatedValues) error { + domainInterfaceValues map[string]generatedValues, + networks []vinov1.Network) error { logr.FromContext(ctx).Info("Getting GW bridge IP from node", "node", k8sNode.Name) builderValues := vinov1.Builder{ - Domains: make(map[string]vinov1.BuilderDomain), - GWIPBridge: gwIP, + Domains: make(map[string]vinov1.BuilderDomain), + Networks: networks, } - for domainName, domain := range values { + for domainName, domain := range domainInterfaceValues { builderDomain := vinov1.BuilderDomain{ Interfaces: make(map[string]vinov1.BuilderNetworkInterface), }