Browse Source

Build BMH network config

This constructs a VM's BMH network config secret, based on a template.
It also integrates IPAM functionality into the controller.

TODOs for subsequent patchsets:
- manage VM mac addresses.
- implement replacement of e.g. $vino.nodebridgegw
- confirm the nameservers definition below works
  (it's a different field than we use in hostgenerator-m3)

The current patchset generates a networkData like so from the sample CRs:

links:
  - id: management
    name: management
    type: bridge
    mtu: 1500
    #  ethernet_mac_address: ??
    bridgeName: vminfra-bridge
  - id: external
    name: external
    type: sriov-bond
    mtu: 9100
    #  ethernet_mac_address: ??
    bond_miimon: 100
    bond_mode: 802.3ad
    bond_xmit_hash_policy: layer3+4
    pf: [enp29s0f0,enp219s1f1]
    vlan: 100
networks:
  - id: management
    type: ipv4
    link: management
    ip_address: 192.168.2.10
    #netmask: "TODO - see if needed when ip has CIDR range"
    dns_nameservers: [135.188.34.124]
    routes:
      - network: 10.0.0.0
        netmask: 255.255.255.0
        gateway: $vino.nodebridgegw
  - id: external
    type: ipv4
    link: external
    ip_address: 169.0.0.10
    #netmask: "TODO - see if needed when ip has CIDR range"
    dns_nameservers: []
    routes:
      - network: 0.0.0.0
        netmask: 0.0.0.0
        gateway: 169.0.0.1

Change-Id: I99b1a104764687c8b84f2495591e0712bed73ae5
changes/74/778774/8
Matt McEuen 1 year ago
parent
commit
7dddf0f7d1
  1. 43
      config/crd/bases/airship.airshipit.org_vinoes.yaml
  2. 12
      config/rbac/role.yaml
  3. 3
      config/samples/ippool.yaml
  4. 44
      config/samples/network-template-secret.yaml
  5. 31
      config/samples/vino_cr.yaml
  6. 28
      docs/api/vino.md
  7. 6
      go.mod
  8. 11
      go.sum
  9. 5
      main.go
  10. 22
      pkg/api/v1/vino_types.go
  11. 16
      pkg/api/v1/zz_generated.deepcopy.go
  12. 81
      pkg/controllers/bmh.go
  13. 4
      pkg/controllers/bmh_test.go
  14. 3
      pkg/controllers/vino_controller.go
  15. 3
      tools/deployment/test-cr.sh

43
config/crd/bases/airship.airshipit.org_vinoes.yaml

@ -97,14 +97,18 @@ spec:
items:
description: VMRoutes defined
properties:
to:
gateway:
type: string
via:
netmask:
type: string
network:
type: string
type: object
type: array
subnet:
type: string
type:
type: string
type: object
type: array
nodeSelector:
@ -163,8 +167,7 @@ spec:
description: Parameter for Node master or worker-standard
type: string
networkDataTemplate:
description: NetworkDataTemplate reference a Secret containing
a template key
description: NetworkDataTemplate must have a template key
properties:
name:
type: string
@ -172,22 +175,24 @@ spec:
type: string
type: object
networkInterfaces:
description: NetworkInterface define interface on the VM
properties:
mtu:
type: integer
name:
description: Define parameter for network interfaces
type: string
network:
type: string
options:
additionalProperties:
items:
description: NetworkInterface define interface on the VM
properties:
mtu:
type: integer
name:
description: Define parameter for network interfaces
type: string
type: object
type:
type: string
type: object
network:
type: string
options:
additionalProperties:
type: string
type: object
type:
type: string
type: object
type: array
type: object
type: array
vmBridge:

12
config/rbac/role.yaml

@ -32,6 +32,18 @@ rules:
- patch
- update
- watch
- apiGroups:
- airship.airshipit.org
resources:
- ippools
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- airship.airshipit.org
resources:

3
config/samples/ippool.yaml

@ -1,3 +1,6 @@
# Note: IPPools are intended to be created and managed by ViNO itself.
# ViNO will perform IPAM based on end user input in the ViNO CR.
# This resource here is just a reference.
apiVersion: airship.airshipit.org/v1
kind: IPPool
metadata:

44
config/samples/network-template-secret.yaml

@ -1,3 +1,9 @@
# This template creates a cloud-init network configuration,
# based upon these input values:
#
# .Node: the Node from a ViNO CR
# .Networks: the list of Networks from a ViNO CR
# .Generated: host-specific info generated/calculated by ViNO itself
apiVersion: v1
kind: Secret
metadata:
@ -5,4 +11,40 @@ metadata:
namespace: default
type: Opaque
stringData:
template: REPLACEME
template: |
{{ $netToIface := dict }}
links:
{{- range .Node.NetworkInterfaces }}
- id: {{ .Name }}
name: {{ .Name }}
type: {{ .Type }}
mtu: {{ .MTU }}
# ethernet_mac_address: ??
{{- if .Options -}}
{{ range $key, $val := .Options }}
{{ $key }}: {{ $val }}
{{- end }}
{{- end }}
{{- /* Save the network->interface mapping, needed below */ -}}
{{- $_ := set $netToIface .NetworkName .Name }}
{{- end }}
networks:
{{- range .Networks }}
- id: {{ .Name }}
type: {{ .Type }}
link: {{ index $netToIface .Name }}
ip_address: {{ index $.Generated.IPAddresses .Name }}
#netmask: "TODO - see if needed when ip has CIDR range"
dns_nameservers: {{ .DNSServers }}
{{- if .Routes }}
routes:
{{- range .Routes }}
- network: {{ .Network }}
{{ if .Netmask }}netmask: {{ .Netmask }}{{ end }}
gateway: {{ .Gateway }}
{{- end }}
{{- end }}
{{- end }}
#services:
# TODO: confirm dns_nameservers above does the trick here

31
config/samples/vino_cr.yaml

@ -14,19 +14,24 @@ spec:
networks:
- name: management
subnet: 192.168.2.0/20
type: ipv4
allocationStart: 192.168.2.10
allocationStop: 192.168.2.14 # docs should specify that the range should = number of vms (to permit future expansion over multiple vino crs etc)
routes:
- to: 10.0.0.0/24
via: $vino.nodebridgegw # vino will need to populate this from the nodelabel value `airshipit.org/vino.nodebridgegw`
- network: 10.0.0.0
netmask: 255.255.255.0
gateway: $vino.nodebridgegw # vino will need to populate this from the nodelabel value `airshipit.org/vino.nodebridgegw`
dns_servers: ["135.188.34.124"]
- name: external
subnet: 169.0.0.0/24
type: ipv4
routes:
- to: 0.0.0.0/0
via: 169.0.0.1
- network: 0.0.0.0
netmask: 0.0.0.0
gateway: 169.0.0.1
allocationStart: 169.0.0.10
allocationStop: 169.0.0.254
vmBridge: lo
nodes:
- name: "worker"
@ -34,6 +39,24 @@ spec:
networkDataTemplate:
name: "test-template"
namespace: "default"
networkInterfaces:
- name: management
type: bridge
network: management
mtu: 1500
options:
bridgeName: vminfra-bridge
- name: external
type: sriov-bond
network: external
mtu: 9100
options:
# this is an 'open-ended' set of k/v pairs, validation is perfomed by vino rather than crd schema.
pf: "[enp29s0f0,enp219s1f1]"
vlan: "100"
bond_mode: 802.3ad
bond_xmit_hash_policy: layer3+4
bond_miimon: "100"
bmcCredentials:
username: "admin"
password: "passw0rd"

28
docs/api/vino.md

@ -541,6 +541,16 @@ string
</tr>
<tr>
<td>
<code>type</code><br>
<em>
string
</em>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>allocationStart</code><br>
<em>
string
@ -756,7 +766,7 @@ NamespacedName
<code>networkInterfaces</code><br>
<em>
<a href="#airship.airshipit.org/v1.NetworkInterface">
NetworkInterface
[]NetworkInterface
</a>
</em>
</td>
@ -785,7 +795,7 @@ NamespacedName
</em>
</td>
<td>
<p>NetworkDataTemplate reference a Secret containing a template key</p>
<p>NetworkDataTemplate must have a template key</p>
</td>
</tr>
</tbody>
@ -883,7 +893,17 @@ map[string]string
<tbody>
<tr>
<td>
<code>to</code><br>
<code>network</code><br>
<em>
string
</em>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>netmask</code><br>
<em>
string
</em>
@ -893,7 +913,7 @@ string
</tr>
<tr>
<td>
<code>via</code><br>
<code>gateway</code><br>
<em>
string
</em>

6
go.mod

@ -3,12 +3,16 @@ module vino
go 1.13
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/evanphx/json-patch v4.9.0+incompatible
github.com/go-logr/logr v0.3.0
github.com/go-logr/zapr v0.2.0
github.com/metal3-io/baremetal-operator v0.0.0-20210111093319-93a6fd209b9a
github.com/golang/mock v1.4.4
github.com/huandu/xstrings v1.3.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/metal3-io/baremetal-operator v0.0.0-20210111093319-93a6fd209b9a
github.com/mitchellh/copystructure v1.1.1 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/onsi/ginkgo v1.14.2
github.com/onsi/gomega v1.10.2

11
go.sum

@ -53,7 +53,12 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
@ -368,6 +373,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@ -444,6 +451,8 @@ github.com/metal3-io/baremetal-operator v0.0.0-20210111093319-93a6fd209b9a h1:Gx
github.com/metal3-io/baremetal-operator v0.0.0-20210111093319-93a6fd209b9a/go.mod h1:ydVPYnA+ShdlzVn0DcrRWbhFJwo9OGuEFZJ2GWVSB10=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.1.1 h1:Bp6x9R1Wn16SIz3OfeDr0b7RnCG2OB66Y7PQyC/cvq4=
github.com/mitchellh/copystructure v1.1.1/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
@ -453,6 +462,8 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=

5
main.go

@ -32,6 +32,7 @@ import (
vinov1 "vino/pkg/api/v1"
"vino/pkg/controllers"
"vino/pkg/ipam"
)
var (
@ -80,9 +81,13 @@ func main() {
os.Exit(1)
}
ipammer := ipam.NewIpam(ctrl.Log.WithName("IPAM"), mgr.GetClient(),
os.Getenv("RUNTIME_NAMESPACE"))
if err = (&controllers.VinoReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Ipam: ipammer,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Vino")
os.Exit(1)

22
pkg/api/v1/vino_types.go

@ -44,7 +44,7 @@ type VinoSpec struct {
// Define network parameters
Networks []Network `json:"networks,omitempty"`
// Define node details
Node []NodeSet `json:"nodes,omitempty"`
Nodes []NodeSet `json:"nodes,omitempty"`
// DaemonSetOptions defines how vino will spawn daemonset on nodes
DaemonSetOptions DaemonSetOptions `json:"daemonSetOptions,omitempty"`
// VMBridge defines the single interface name to be used as a bridge for VMs
@ -78,6 +78,7 @@ type Network struct {
//Network Parameter defined
Name string `json:"name,omitempty"`
SubNet string `json:"subnet,omitempty"`
Type string `json:"type,omitempty"`
AllocationStart string `json:"allocationStart,omitempty"`
AllocationStop string `json:"allocationStop,omitempty"`
DNSServers []string `json:"dns_servers,omitempty"`
@ -86,20 +87,21 @@ type Network struct {
// VMRoutes defined
type VMRoutes struct {
To string `json:"to,omitempty"`
Via string `json:"via,omitempty"`
Network string `json:"network,omitempty"`
Netmask string `json:"netmask,omitempty"`
Gateway string `json:"gateway,omitempty"`
}
//NodeSet node definitions
type NodeSet struct {
//Parameter for Node master or worker-standard
Name string `json:"name,omitempty"`
Count int `json:"count,omitempty"`
NodeLabel VMNodeFlavor `json:"labels,omitempty"`
LibvirtTemplate NamespacedName `json:"libvirtTemplate,omitempty"`
NetworkInterface *NetworkInterface `json:"networkInterfaces,omitempty"`
DiskDrives *DiskDrivesTemplate `json:"diskDrives,omitempty"`
// NetworkDataTemplate reference a Secret containing a template key
Name string `json:"name,omitempty"`
Count int `json:"count,omitempty"`
NodeLabel VMNodeFlavor `json:"labels,omitempty"`
LibvirtTemplateDefinition NamespacedName `json:"libvirtTemplate,omitempty"`
NetworkInterfaces []NetworkInterface `json:"networkInterfaces,omitempty"`
DiskDrives *DiskDrivesTemplate `json:"diskDrives,omitempty"`
// NetworkDataTemplate must have a template key
NetworkDataTemplate NamespacedName `json:"networkDataTemplate,omitempty"`
}

16
pkg/api/v1/zz_generated.deepcopy.go

@ -308,11 +308,13 @@ func (in *NodeSelector) DeepCopy() *NodeSelector {
func (in *NodeSet) DeepCopyInto(out *NodeSet) {
*out = *in
in.NodeLabel.DeepCopyInto(&out.NodeLabel)
out.LibvirtTemplate = in.LibvirtTemplate
if in.NetworkInterface != nil {
in, out := &in.NetworkInterface, &out.NetworkInterface
*out = new(NetworkInterface)
(*in).DeepCopyInto(*out)
out.LibvirtTemplateDefinition = in.LibvirtTemplateDefinition
if in.NetworkInterfaces != nil {
in, out := &in.NetworkInterfaces, &out.NetworkInterfaces
*out = make([]NetworkInterface, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.DiskDrives != nil {
in, out := &in.DiskDrives, &out.DiskDrives
@ -463,8 +465,8 @@ func (in *VinoSpec) DeepCopyInto(out *VinoSpec) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Node != nil {
in, out := &in.Node, &out.Node
if in.Nodes != nil {
in, out := &in.Nodes, &out.Nodes
*out = make([]NodeSet, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])

81
pkg/controllers/bmh.go

@ -1,6 +1,4 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@ -22,6 +20,7 @@ import (
"fmt"
"text/template"
"github.com/Masterminds/sprig"
"github.com/go-logr/logr"
metal3 "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
corev1 "k8s.io/api/core/v1"
@ -32,8 +31,20 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
vinov1 "vino/pkg/api/v1"
"vino/pkg/ipam"
)
type networkTemplateValues struct {
Node vinov1.NodeSet // the specific node type to be templated
BMHName string
Networks []vinov1.Network
Generated generatedValues // Host-specific values calculated by ViNO: IP, etc
}
type generatedValues struct {
IPAddresses map[string]string // a map of network names to IP addresses
}
func (r *VinoReconciler) ensureBMHs(ctx context.Context, vino *vinov1.Vino) error {
labelOpt := client.MatchingLabels{
vinov1.VinoLabelDSNameSelector: vino.Name,
@ -56,7 +67,11 @@ func (r *VinoReconciler) ensureBMHs(ctx context.Context, vino *vinov1.Vino) erro
"pod name",
types.NamespacedName{Namespace: pod.Namespace, Name: pod.Name},
)
err := r.createBMHperPod(ctx, vino, pod)
err := r.createIpamNetworks(ctx, vino)
if err != nil {
return err
}
err = r.createBMHperPod(ctx, vino, pod)
if err != nil {
return err
}
@ -101,8 +116,22 @@ func (r *VinoReconciler) reconcileBMHs(ctx context.Context, vino *vinov1.Vino) e
return nil
}
func (r *VinoReconciler) createIpamNetworks(ctx context.Context, vino *vinov1.Vino) error {
for _, network := range vino.Spec.Networks {
subnetRange, err := ipam.NewRange(network.AllocationStart, network.AllocationStop)
if err != nil {
return err
}
err = r.Ipam.AddSubnetRange(ctx, network.SubNet, subnetRange)
if err != nil {
return err
}
}
return nil
}
func (r *VinoReconciler) createBMHperPod(ctx context.Context, vino *vinov1.Vino, pod corev1.Pod) error {
for _, node := range vino.Spec.Node {
for _, node := range vino.Spec.Nodes {
logger := logr.FromContext(ctx)
logger.Info("Creating BMHs for vino node", "node name", node.Name, "count", node.Count)
prefix := r.getBMHNodePrefix(vino, pod)
@ -115,7 +144,43 @@ func (r *VinoReconciler) createBMHperPod(ctx context.Context, vino *vinov1.Vino,
return err
}
netData, netDataNs, err := r.reconcileBMHNetworkData(ctx, node, vino, nil)
// Allocate an IP for each of this BMH's network interfaces
ipAddresses := map[string]string{}
for _, iface := range node.NetworkInterfaces {
networkName := iface.NetworkName
subnet := ""
subnetRange := vinov1.Range{}
for _, network := range vino.Spec.Networks {
if network.Name == networkName {
subnet = network.SubNet
subnetRange, err = ipam.NewRange(network.AllocationStart,
network.AllocationStop)
if err != nil {
return err
}
break
}
}
if subnet == "" {
return fmt.Errorf("Interface %s doesn't have a matching network defined", networkName)
}
ipAllocatedTo := fmt.Sprintf("%s/%s", bmhName, iface.NetworkName)
ipAddress, er := r.Ipam.AllocateIP(ctx, subnet, subnetRange, ipAllocatedTo)
if er != nil {
return er
}
ipAddresses[networkName] = ipAddress
}
values := networkTemplateValues{
Node: node,
BMHName: bmhName,
Networks: vino.Spec.Networks,
Generated: generatedValues{
IPAddresses: ipAddresses,
},
}
netData, netDataNs, err := r.reconcileBMHNetworkData(ctx, node, vino, values)
if err != nil {
return err
}
@ -213,7 +278,7 @@ func (r *VinoReconciler) reconcileBMHNetworkData(
ctx context.Context,
node vinov1.NodeSet,
vino *vinov1.Vino,
values interface{}) (string, string, error) {
values networkTemplateValues) (string, string, error) {
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: node.NetworkDataTemplate.Name,
@ -234,7 +299,7 @@ func (r *VinoReconciler) reconcileBMHNetworkData(
return "", "", fmt.Errorf("network template secret %v has no key '%s'", objKey, TemplateDefaultKey)
}
tpl, err := template.New("net-template").Parse(string(rawTmpl))
tpl, err := template.New("net-template").Funcs(sprig.TxtFuncMap()).Parse(string(rawTmpl))
if err != nil {
return "", "", err
}
@ -245,7 +310,7 @@ func (r *VinoReconciler) reconcileBMHNetworkData(
return "", "", err
}
name := fmt.Sprintf("%s-%s-%s", vino.Namespace, vino.Name, node.Name)
name := fmt.Sprintf("%s-network-data", values.BMHName)
ns := getRuntimeNamespace()
netSecret := &corev1.Secret{

4
pkg/controllers/bmh_test.go

@ -40,7 +40,7 @@ var _ = Describe("Test BMH reconciliation", func() {
os.Setenv("RUNTIME_NAMESPACE", "vino-system")
defer os.Unsetenv("RUNTIME_NAMESPACE")
vino := testVINO()
vino.Spec.Node = []vinov1.NodeSet{
vino.Spec.Nodes = []vinov1.NodeSet{
{
Name: "worker",
Count: 3,
@ -141,7 +141,7 @@ var _ = Describe("Test BMH reconciliation", func() {
networkSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "default-vino-worker",
Name: "default-vino-node01-worker-0-network-data",
Namespace: "vino-system",
},
}

3
pkg/controllers/vino_controller.go

@ -39,6 +39,7 @@ import (
"sigs.k8s.io/yaml"
vinov1 "vino/pkg/api/v1"
"vino/pkg/ipam"
)
const (
@ -53,10 +54,12 @@ const (
type VinoReconciler struct {
client.Client
Scheme *runtime.Scheme
Ipam *ipam.Ipam
}
// +kubebuilder:rbac:groups=airship.airshipit.org,resources=vinoes,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=airship.airshipit.org,resources=vinoes/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=airship.airshipit.org,resources=ippools,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=pods,verbs=list;watch
// +kubebuilder:rbac:groups="",resources=nodes,verbs=get;list;watch
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;patch

3
tools/deployment/test-cr.sh

@ -50,5 +50,6 @@ bmhCount=$(kubectl get baremetalhosts -n vino-system -o name | wc -l)
[[ "$bmhCount" -eq "3" ]]
kubectl get secret -o yaml -n vino-system default-vino-test-cr-worker
kubectl get -o yaml -n vino-system \
$(kubectl get secret -o name -n vino-system | grep network-data)
kubectl get secret -o yaml -n vino-system default-vino-test-cr-credentials

Loading…
Cancel
Save