diff --git a/README.md b/README.md index e6d7987..58a3fe3 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,13 @@ While ViNO is responsible for setting up VM infrastructure, such as: - networking - bmh objects, with labels: * location - i.e. `rack: 8` and `node: rdm8r008c002` - should follow k8s semi-standard - * vm role - i.e. `node-type: worker` + * vm role - i.e. `node-type: worker` * vm flavor - i.e `node-flavor: foobar` * networks - i.e. `networks: [foo, bar]` -and the details for ViNO can be found [here](https://hackmd.io/KSu8p4QeTc2kXIjlrso2eA) +and the details for ViNO can be found [here](https://hackmd.io/KSu8p4QeTc2kXIjlrso2eA) The Cluster Support Infrastructure Provider, or SIP, is responsible for the lifecycle of: -- identifying the correct `BareMetalHost` resources to label (or unlabel) based on scheduling constraints. +- identifying the correct `BareMetalHost` resources to label (or unlabel) based on scheduling constraints. - extract IP address information from `BareMetalHost` objects to use in the creation of supporting infrastructure. - creating support infra for the tenant k8s cluster: * load balancers (for tenant k8s api) @@ -49,9 +49,9 @@ Pseudo Algorithm at a high level after reading the `SIPCluster` CR: #### Identity BMH VM's - Gather BMH's that meet the criteria expected for the groups -- Check for existing labeled BMH's +- Check for existing labeled BMH's - Complete the expected scheduling contraints : - - If master + - If master - collect into list of bmh's to label - If worker - collect into list of bmh's to label diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml index 58db114..3d46cff 100644 --- a/config/certmanager/certificate.yaml +++ b/config/certmanager/certificate.yaml @@ -1,6 +1,6 @@ # The following manifests contain a self-signed issuer CR and a certificate CR. # More document can be found at https://docs.cert-manager.io -# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for +# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for # breaking changes apiVersion: cert-manager.io/v1alpha2 kind: Issuer diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml index 90d7c31..e631f77 100644 --- a/config/certmanager/kustomizeconfig.yaml +++ b/config/certmanager/kustomizeconfig.yaml @@ -1,4 +1,4 @@ -# This configuration is for teaching kustomize how to update name ref and var substitution +# This configuration is for teaching kustomize how to update name ref and var substitution nameReference: - kind: Issuer group: cert-manager.io diff --git a/config/crd/bases/airship.airshipit.org_sipclusters.yaml b/config/crd/bases/airship.airshipit.org_sipclusters.yaml index 73120ac..85f1d7c 100644 --- a/config/crd/bases/airship.airshipit.org_sipclusters.yaml +++ b/config/crd/bases/airship.airshipit.org_sipclusters.yaml @@ -58,7 +58,7 @@ spec: type: object optional: properties: - clusterIp: + clusterIP: type: string sshkey: type: string @@ -91,13 +91,13 @@ spec: identify the required BMH's to allow CAPI to build a cluster type: string vm-flavor: - description: VmFlavor is essentially a Flavor label identifying + description: VMFlavor is essentially a Flavor label identifying the type of Node that meets the construction reqirements type: string type: object description: Nodes are the list of Nodes objects workers, or master - that definee eexpectations of the Tenant cluster VmRole is either - Control or Workers VmRole VmRoles `json:"vm-role,omitempty"` + that definee eexpectations of the Tenant cluster VMRole is either + Control or Workers VMRole VMRoles `json:"vm-role,omitempty"` type: object required: - infra diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 865752e..26d1af3 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -16,12 +16,12 @@ bases: - ../crd - ../rbac - ../manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml #- ../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. #- ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus patchesStrategicMerge: @@ -30,7 +30,7 @@ patchesStrategicMerge: # endpoint w/o any authn/z, please comment the following line. - manager_auth_proxy_patch.yaml -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml #- manager_webhook_patch.yaml diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml index 77e743d..a945ed1 100644 --- a/config/default/manager_auth_proxy_patch.yaml +++ b/config/default/manager_auth_proxy_patch.yaml @@ -1,4 +1,4 @@ -# This patch inject a sidecar container which is a HTTP proxy for the +# This patch inject a sidecar container which is a HTTP proxy for the # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. apiVersion: apps/v1 kind: Deployment diff --git a/config/kustomization.yaml b/config/kustomization.yaml index fe5fb50..cf7e1f3 100644 --- a/config/kustomization.yaml +++ b/config/kustomization.yaml @@ -1,4 +1,3 @@ -# # Adds namespace to all resources. namespace: sip-system diff --git a/config/samples/airship_v1beta1_sipcluster.yaml b/config/samples/airship_v1beta1_sipcluster.yaml index 166fd62..244bba6 100644 --- a/config/samples/airship_v1beta1_sipcluster.yaml +++ b/config/samples/airship_v1beta1_sipcluster.yaml @@ -24,7 +24,7 @@ spec: infra: loadbalancer: optional: - clusterIp: 1.2.3.4 #<-- this aligns to the VIP IP for undercloud k8s + clusterIP: 1.2.3.4 #<-- this aligns to the VIP IP for undercloud k8s image: haproxy:foo nodeLabels: - airship-masters diff --git a/main.go b/main.go index a5b1e50..88e9bad 100644 --- a/main.go +++ b/main.go @@ -41,6 +41,7 @@ var ( setupLog = ctrl.Log.WithName("setup") ) +//nolint:errcheck func init() { _ = clientgoscheme.AddToScheme(scheme) @@ -52,7 +53,6 @@ func init() { // Add Kubernetes Coree?? _ = corev1.AddToScheme(scheme) - } func main() { diff --git a/pkg/api/v1/sipcluster_types.go b/pkg/api/v1/sipcluster_types.go index d6e41dc..d785b12 100644 --- a/pkg/api/v1/sipcluster_types.go +++ b/pkg/api/v1/sipcluster_types.go @@ -31,9 +31,9 @@ type SIPClusterSpec struct { Config *SipConfig `json:"config,omitempty"` // Nodes are the list of Nodes objects workers, or master that definee eexpectations // of the Tenant cluster - // VmRole is either Control or Workers - // VmRole VmRoles `json:"vm-role,omitempty"` - Nodes map[VmRoles]NodeSet `json:"nodes,omitempty"` + // VMRole is either Control or Workers + // VMRole VMRoles `json:"vm-role,omitempty"` + Nodes map[VMRoles]NodeSet `json:"nodes,omitempty"` // Infra is the collection of expeected configuration details // for the multiple infrastructure services or pods that SIP manages @@ -49,7 +49,7 @@ type SipConfig struct { ClusterName string `json:"cluster-name,omitempty"` } -// VmRoles defines the states the provisioner will report +// VMRoles defines the states the provisioner will report // the tenant has having. type InfraService string @@ -77,16 +77,16 @@ const ( // type NodeSet struct { - // VmFlavor is essentially a Flavor label identifying the + // VMFlavor is essentially a Flavor label identifying the // type of Node that meets the construction reqirements - VmFlavor string `json:"vm-flavor,omitempty"` + VMFlavor string `json:"vm-flavor,omitempty"` // PlaceHolder until we define the real expected // Implementation // Scheduling define constraints the allows the SIP Scheduler // to identify the required BMH's to allow CAPI to build a cluster Scheduling SpreadTopology `json:"spreadTopology,omitempty"` // Count defines the scale expectations for the Nodes - Count *VmCount `json:"count,omitempty"` + Count *VMCount `json:"count,omitempty"` } type SpreadTopology string @@ -109,25 +109,22 @@ type InfraConfig struct { } type OptsConfig struct { - SshKey string `json:"sshkey,omitempty"` - ClusterIp string `json:"clusterIp,omitempty"` + SSHKey string `json:"sshkey,omitempty"` + ClusterIP string `json:"clusterIP,omitempty"` } -// VmRoles defines the states the provisioner will report +// VMRoles defines the states the provisioner will report // the tenant has having. -type VmRoles string +type VMRoles string // Possible Node or VM Roles for a Tenant const ( - // VmMaster means the state is unknown - VmMaster VmRoles = "master" - - // VmWorker means the state is unknown - VmWorker VmRoles = "worker" + VMMaster VMRoles = "master" + VMWorker = "worker" ) -// VmCount -type VmCount struct { +// VMCount +type VMCount struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run "make" to regenerate code after modifying this file Active int `json:"active,omitempty"` diff --git a/pkg/api/v1/zz_generated.deepcopy.go b/pkg/api/v1/zz_generated.deepcopy.go index 7c4e7ec..8ad4251 100644 --- a/pkg/api/v1/zz_generated.deepcopy.go +++ b/pkg/api/v1/zz_generated.deepcopy.go @@ -61,7 +61,7 @@ func (in *NodeSet) DeepCopyInto(out *NodeSet) { *out = *in if in.Count != nil { in, out := &in.Count, &out.Count - *out = new(VmCount) + *out = new(VMCount) **out = **in } } @@ -160,7 +160,7 @@ func (in *SIPClusterSpec) DeepCopyInto(out *SIPClusterSpec) { } if in.Nodes != nil { in, out := &in.Nodes, &out.Nodes - *out = make(map[VmRoles]NodeSet, len(*in)) + *out = make(map[VMRoles]NodeSet, len(*in)) for key, val := range *in { (*out)[key] = *val.DeepCopy() } @@ -215,16 +215,16 @@ func (in *SipConfig) DeepCopy() *SipConfig { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VmCount) DeepCopyInto(out *VmCount) { +func (in *VMCount) DeepCopyInto(out *VMCount) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VmCount. -func (in *VmCount) DeepCopy() *VmCount { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMCount. +func (in *VMCount) DeepCopy() *VMCount { if in == nil { return nil } - out := new(VmCount) + out := new(VMCount) in.DeepCopyInto(out) return out } diff --git a/pkg/controllers/sipcluster_controller.go b/pkg/controllers/sipcluster_controller.go index 087bdc5..ac62f3b 100644 --- a/pkg/controllers/sipcluster_controller.go +++ b/pkg/controllers/sipcluster_controller.go @@ -65,9 +65,9 @@ func (r *SIPClusterReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) // Tghis only works if I add a finalizer to CRD TODO if sip.ObjectMeta.DeletionTimestamp.IsZero() { // machines - err, machines := r.gatherVBMH(sip) + machines, err := r.gatherVBMH(sip) if err != nil { - //log.Error(err, "unable to gather vBMHs") + log.Error(err, "unable to gather vBMHs") return ctrl.Result{}, err } @@ -82,24 +82,22 @@ func (r *SIPClusterReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) log.Error(err, "unable to finish creation/update ..") return ctrl.Result{}, err } - } else { + } else if containsString(sip.ObjectMeta.Finalizers, sipFinalizerName) { // Deleting the SIP , what do we do now - if containsString(sip.ObjectMeta.Finalizers, sipFinalizerName) { - // our finalizer is present, so lets handle any external dependency - err := r.finalize(sip) - if err != nil { - log.Error(err, "unable to finalize") - return ctrl.Result{}, err - } - - // remove our finalizer from the list and update it. - sip.ObjectMeta.Finalizers = removeString(sip.ObjectMeta.Finalizers, sipFinalizerName) - if err := r.Update(context.Background(), &sip); err != nil { - return ctrl.Result{}, err - } + // our finalizer is present, so lets handle any external dependency + err := r.finalize(sip) + if err != nil { + log.Error(err, "unable to finalize") + return ctrl.Result{}, err } + // remove our finalizer from the list and update it. + sip.ObjectMeta.Finalizers = removeString(sip.ObjectMeta.Finalizers, sipFinalizerName) + if err := r.Update(context.Background(), &sip); err != nil { + return ctrl.Result{}, err + } } + return ctrl.Result{}, nil } @@ -155,9 +153,9 @@ func removeString(slice []string, s string) (result []string) { */ // machines -func (r *SIPClusterReconciler) gatherVBMH(sip airshipv1.SIPCluster) (error, *airshipvms.MachineList) { +func (r *SIPClusterReconciler) gatherVBMH(sip airshipv1.SIPCluster) (*airshipvms.MachineList, error) { // 1- Let me retrieve all BMH that are unlabeled or already labeled with the target Tenant/CNF - // 2- Let me now select the one's that meet teh scheduling criteria + // 2- Let me now select the one's that meet the scheduling criteria // If I schedule successfully then // If Not complete schedule , then throw an error. logger := r.Log.WithValues("SIPCluster", r.NamespacedName) @@ -171,7 +169,7 @@ func (r *SIPClusterReconciler) gatherVBMH(sip airshipv1.SIPCluster) (error, *air logger.Info("gathering machines", "machines", machines.String()) err := machines.Schedule(sip, r.Client) if err != nil { - return err, machines + return machines, err } // we extract the information in a generic way @@ -179,14 +177,13 @@ func (r *SIPClusterReconciler) gatherVBMH(sip airshipv1.SIPCluster) (error, *air // If there are some issues finnding information the vBMH // Are flagged Unschedulable // Loop and Try to find new vBMH to complete tge schedule - //fmt.Printf("gatherVBMH.Extrapolate sip:%v machines:%v\n", sip, machines) if machines.Extrapolate(sip, r.Client) { - logger.Info("successfuly extrapolated machines") + logger.Info("successfully extrapolated machines") break } } - return nil, machines + return machines, nil } func (r *SIPClusterReconciler) deployInfra(sip airshipv1.SIPCluster, machines *airshipvms.MachineList) error { @@ -217,20 +214,14 @@ func (r *SIPClusterReconciler) deployInfra(sip airshipv1.SIPCluster, machines *a finish shoulld take care of any wrpa up tasks.. */ func (r *SIPClusterReconciler) finish(sip airshipv1.SIPCluster, machines *airshipvms.MachineList) error { - // UnLabel the vBMH's - err := machines.ApplyLabels(sip, r.Client) - if err != nil { - return err - } - return nil - + return machines.ApplyLabels(sip, r.Client) } /** -Deal with Deletion andd Finalizers if any is needed -Such as i'e what are we doing with the lables on teh vBMH's +Deal with Deletion and Finalizers if any is needed +Such as i'e what are we doing with the lables on the vBMH's **/ func (r *SIPClusterReconciler) finalize(sip airshipv1.SIPCluster) error { logger := r.Log.WithValues("SIPCluster", sip.GetNamespace()+"/"+sip.GetName()) @@ -248,16 +239,19 @@ func (r *SIPClusterReconciler) finalize(sip airshipv1.SIPCluster) error { } } // Clean Up common servicce stuff - airshipsvc.FinalizeCommon(sip, r.Client) + err := airshipsvc.FinalizeCommon(sip, r.Client) + if err != nil { + return err + } // 1- Let me retrieve all vBMH mapped for this SIP Cluster - // 2- Let me now select the one's that meet teh scheduling criteria + // 2- Let me now select the one's that meet the scheduling criteria // If I schedule successfully then // If Not complete schedule , then throw an error. machines := &airshipvms.MachineList{} logger.Info("finalize sip machines", "machines", machines.String()) // Update the list of Machines. - err := machines.GetCluster(sip, r.Client) + err = machines.GetCluster(sip, r.Client) if err != nil { return err } diff --git a/pkg/controllers/sipcluster_controller_test.go b/pkg/controllers/sipcluster_controller_test.go index bd88c52..8665112 100644 --- a/pkg/controllers/sipcluster_controller_test.go +++ b/pkg/controllers/sipcluster_controller_test.go @@ -36,7 +36,7 @@ import ( var _ = Describe("SIPCluster controller", func() { Context("When it detects a new SIPCluster", func() { It("Should schedule available nodes", func() { - By("Labelling nodes") + By("Labeling nodes") // Create vBMH test objects nodes := []string{"master", "master", "master", "worker", "worker", "worker", "worker"} @@ -74,7 +74,7 @@ var _ = Describe("SIPCluster controller", func() { }) It("Should not schedule nodes when there is an insufficient number of available master nodes", func() { - By("Not labelling any nodes") + By("Not labeling any nodes") // Create vBMH test objects nodes := []string{"master", "master", "worker", "worker", "worker", "worker"} @@ -111,7 +111,7 @@ var _ = Describe("SIPCluster controller", func() { }) It("Should not schedule nodes when there is an insufficient number of available worker nodes", func() { - By("Not labelling any nodes") + By("Not labeling any nodes") // Create vBMH test objects nodes := []string{"master", "master", "master", "worker", "worker"} diff --git a/pkg/controllers/suite_test.go b/pkg/controllers/suite_test.go index 88e1442..0924b0f 100644 --- a/pkg/controllers/suite_test.go +++ b/pkg/controllers/suite_test.go @@ -20,6 +20,8 @@ import ( "path/filepath" "testing" + airshipv1 "sipcluster/pkg/api/v1" + metal3 "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -31,7 +33,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/envtest/printer" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - airshipv1 "sipcluster/pkg/api/v1" // +kubebuilder:scaffold:imports ) diff --git a/pkg/services/errors.go b/pkg/services/errors.go index bff5e6c..45f6177 100644 --- a/pkg/services/errors.go +++ b/pkg/services/errors.go @@ -14,8 +14,6 @@ package services -import () - // ErrAuthTypeNotSupported is returned when wrong AuthType is provided type ErrInfraServiceNotSupported struct { } diff --git a/pkg/services/infrastructureservice.go b/pkg/services/infrastructureservice.go index 2de30b5..357aac2 100644 --- a/pkg/services/infrastructureservice.go +++ b/pkg/services/infrastructureservice.go @@ -31,7 +31,7 @@ import ( // Init : prepares the Service // Deploy : deploys the service -// Validate : will make sure that the deployment is successfull +// Validate : will make sure that the deployment is successful type InfrastructureService interface { // Deploy(airshipv1.SIPCluster, *airshipvms.MachineList, client.Client) error @@ -49,10 +49,12 @@ func (s *Service) Deploy(sip airshipv1.SIPCluster, machines *airshipvms.MachineL // do something, might decouple this a bit // If the serviucces are defined as Helm Chart , then deploy might be simply - //. Lets make sure that teh namespace is in pace. + // Lets make sure that the namespace is in place. // will be called the name of the cluster. - s.createNS(sip.Spec.Config.ClusterName, c) - // Take the data from teh appropriate Machines + if err := s.createNS(sip.Spec.Config.ClusterName, c); err != nil { + return err + } + // Take the data from the appropriate Machines // Prepare the Config fmt.Printf("Deploy Service:%v \n", s.serviceName) return nil @@ -83,14 +85,12 @@ func (s *Service) createNS(serviceNamespaceName string, c client.Client) error { } return nil - } func (s *Service) Validate() error { // do something, might decouple this a bit fmt.Printf("Validate Service:%v \n", s.serviceName) return nil - } func (s *Service) Finalize(sip airshipv1.SIPCluster, c client.Client) error { @@ -112,16 +112,16 @@ func FinalizeCommon(sip airshipv1.SIPCluster, c client.Client) error { } return nil - } // Service Factory func NewService(infraName airshipv1.InfraService, infraCfg airshipv1.InfraConfig) (InfrastructureService, error) { - if infraName == airshipv1.LoadBalancerService { + switch infraName { + case airshipv1.LoadBalancerService: return newLoadBalancer(infraCfg), nil - } else if infraName == airshipv1.JumpHostService { + case airshipv1.JumpHostService: return newJumpHost(infraCfg), nil - } else if infraName == airshipv1.AuthHostService { + case airshipv1.AuthHostService: return newAuthHost(infraCfg), nil } return nil, ErrInfraServiceNotSupported{} diff --git a/pkg/services/jumppod.go b/pkg/services/jumppod.go index 05ca88c..e17efe6 100644 --- a/pkg/services/jumppod.go +++ b/pkg/services/jumppod.go @@ -33,9 +33,15 @@ func newJumpHost(infraCfg airshipv1.InfraConfig) InfrastructureService { /* -The SIP Cluster operator will manufacture a jump host pod specifically for this tenant cluster. Much like we did above for master nodes by extracting IP addresses, we would need to extract the `oam-ipv4` ip address for all nodes and create a configmap to bind mount into the pod so it understands what host IPs represent the clusters. +The SIP Cluster operator will manufacture a jump host pod specifically for this +tenant cluster. Much like we did above for master nodes by extracting IP +addresses, we would need to extract the `oam-ipv4` ip address for all nodes and +create a configmap to bind mount into the pod so it understands what host IPs +represent the clusters. -The expectation is the Jump Pod runs `sshd` protected by `uam` to allow operators to SSH directly to the Jump Pod and authenticate via UAM to immediately access their cluster. +The expectation is the Jump Pod runs `sshd` protected by `uam` to allow +operators to SSH directly to the Jump Pod and authenticate via UAM to +immediately access their cluster. It will provide the following functionality over SSH: @@ -46,6 +52,8 @@ It will provide the following functionality over SSH: - A kubectl binary and kubeconfig (cluster-admin) for the cluster - SSH access to the cluster node VMs - Libvirt console logs for the VMs - - We will secure libvirt with tls and provide keys to every jump host with curated interfaces to extract logs remotely for all VMs for their clusters. + - We will secure libvirt with tls and provide keys to every jump host + with curated interfaces to extract logs remotely for all VMs for their + clusters. */ diff --git a/pkg/services/loadbalancer.go b/pkg/services/loadbalancer.go index c4ab5e0..7a7c254 100644 --- a/pkg/services/loadbalancer.go +++ b/pkg/services/loadbalancer.go @@ -30,21 +30,21 @@ func (l *LoadBalancer) Deploy(sip airshipv1.SIPCluster, machines *airshipvms.Mac // do something, might decouple this a bit // If the serviucces are defined as Helm Chart , then deploy might be simply - // Take the data from teh appropriate Machines + // Take the data from the appropriate Machines // Prepare the Config - l.Service.Deploy(sip, machines, c) - err := l.Prepare(sip, machines, c) + err := l.Service.Deploy(sip, machines, c) if err != nil { return err } - return nil + return l.Prepare(sip, machines, c) } func (l *LoadBalancer) Prepare(sip airshipv1.SIPCluster, machines *airshipvms.MachineList, c client.Client) error { fmt.Printf("%s.Prepare machines:%s \n", l.Service.serviceName, machines) for _, machine := range machines.Machines { - if machine.VMRole == airshipv1.VmMaster { - fmt.Printf("%s.Prepare for machine:%s ip is %s\n", l.Service.serviceName, machine, machine.Data.IpOnInterface[sip.Spec.InfraServices[l.Service.serviceName].NodeInterface]) + if machine.VMRole == airshipv1.VMMaster { + ip := machine.Data.IPOnInterface[sip.Spec.InfraServices[l.Service.serviceName].NodeInterface] + fmt.Printf("%s.Prepare for machine:%s ip is %s\n", l.Service.serviceName, machine, ip) } } return nil @@ -63,11 +63,20 @@ func newLoadBalancer(infraCfg airshipv1.InfraConfig) InfrastructureService { :::warning -For the loadbalanced interface a **static asignment** via network data is required. For now, we will not support updates to this field without manual intervention. In other words, there is no expectation that the SIP operator watches `BareMetalHost` objects and reacts to changes in the future. The expectation would instead to re-deliver the `SIPCluster` object to force a no-op update to load balancer configuration is updated. +For the loadbalanced interface a **static asignment** via network data is +required. For now, we will not support updates to this field without manual +intervention. In other words, there is no expectation that the SIP operator +watches `BareMetalHost` objects and reacts to changes in the future. The +expectation would instead to re-deliver the `SIPCluster` object to force a +no-op update to load balancer configuration is updated. ::: -By extracting these IP address from the appropriate/defined interface for each master node, we can build our loadbalancer service endpoint list to feed to haproxy. In other words, the SIP Cluster will now manufacture an haproxy configuration file that directs traffic to all IP endpoints found above over port 6443. For example: +By extracting these IP address from the appropriate/defined interface for each +master node, we can build our loadbalancer service endpoint list to feed to +haproxy. In other words, the SIP Cluster will now manufacture an haproxy +configuration file that directs traffic to all IP endpoints found above over +port 6443. For example: ``` gotpl @@ -93,10 +102,14 @@ backend kube-apiservers {% end %} ``` -This will be saved as a configmap and mounted into the cluster specific haproxy daemonset across all undercloud control nodes. +This will be saved as a configmap and mounted into the cluster specific haproxy +daemonset across all undercloud control nodes. -We will then create a Kubernetes NodePort `Service` that will direct traffic on the infrastructure `nodePort` defined in the SIP Cluster definition to these haproxy workloads. +We will then create a Kubernetes NodePort `Service` that will direct traffic on +the infrastructure `nodePort` defined in the SIP Cluster definition to these +haproxy workloads. -At this point, the SIP Cluster controller can now label the VMs appropriately so they'll be scheduled by the Cluster-API process. +At this point, the SIP Cluster controller can now label the VMs appropriately +so they'll be scheduled by the Cluster-API process. */ diff --git a/pkg/vbmh/errors.go b/pkg/vbmh/errors.go index 04cdf71..e1654e1 100644 --- a/pkg/vbmh/errors.go +++ b/pkg/vbmh/errors.go @@ -14,23 +14,25 @@ func (e ErrorConstraintNotFound) Error() string { } type ErrorUnableToFullySchedule struct { - TargetNode airshipv1.VmRoles + TargetNode airshipv1.VMRoles TargetFlavor string } func (e ErrorUnableToFullySchedule) Error() string { - return fmt.Sprintf("Unable to complete a schedule with a target of %v nodes, with a flavor of %v ", e.TargetNode, e.TargetFlavor) + return fmt.Sprintf("Unable to complete a schedule with a target of %v nodes, with a flavor of %v", + e.TargetNode, e.TargetFlavor) } -type ErrorHostIpNotFound struct { +type ErrorHostIPNotFound struct { HostName string ServiceName airshipv1.InfraService IPInterface string Message string } -func (e ErrorHostIpNotFound) Error() string { - return fmt.Sprintf("Unable to identify the vBMH Host %v IP address on interface %v required by Infrastructure Service %v %s ", e.HostName, e.IPInterface, e.ServiceName, e.Message) +func (e ErrorHostIPNotFound) Error() string { + return fmt.Sprintf("Unable to identify the vBMH Host %v IP address on interface %v required by "+ + "Infrastructure Service %v %s ", e.HostName, e.IPInterface, e.ServiceName, e.Message) } // ErrorUknownSpreadTopology is returned when wrong AuthType is provided diff --git a/pkg/vbmh/machines.go b/pkg/vbmh/machines.go index b73d59e..580fcf0 100644 --- a/pkg/vbmh/machines.go +++ b/pkg/vbmh/machines.go @@ -52,7 +52,7 @@ const ( // UnableToSchedule, This BMH has something wrong with it // The BMH itself doesnt depict the error situation - // i.e. teh NetworkData is missing something + // i.e. the NetworkData is missing something UnableToSchedule ScheduledState = "UnableToSchedule" ) @@ -78,7 +78,7 @@ const ( SipNodeTypeLabel = BaseAirshipSelector + "/" + SipNodeTypeLabelName ) -// MAchine represents an individual BMH CR, and teh appropriate +// MAchine represents an individual BMH CR, and the appropriate // attributes required to manage the SIP Cluster scheduling and // rocesing needs about thhem type Machine struct { @@ -87,23 +87,25 @@ type Machine struct { // scheduleLabels // I expect to build this over time / if not might not be needed ScheduleLabels map[string]string - VMRole airshipv1.VmRoles + VMRole airshipv1.VMRoles // Data will contain whatever information is needed from the server // IF it ends up een just the IP then maybe we can collapse into a field Data *MachineData } func (m *Machine) String() string { - return fmt.Sprintf("Machine {\n\tBmh:%s\n\tScheduleStatus:%s\n\tVmRole:%v\n}\n", m.BMH.ObjectMeta.Name, m.ScheduleStatus, m.VMRole) + // TODO(howell): cleanup this manual marshaling + return fmt.Sprintf("Machine {\n\tBmh:%s\n\tScheduleStatus:%s\n\tVMRole:%v\n}\n", + m.BMH.ObjectMeta.Name, m.ScheduleStatus, m.VMRole) } -func NewMachine(bmh metal3.BareMetalHost, nodeRole airshipv1.VmRoles, schedState ScheduledState) (m *Machine) { +func NewMachine(bmh metal3.BareMetalHost, nodeRole airshipv1.VMRoles, schedState ScheduledState) (m *Machine) { return &Machine{ BMH: bmh, ScheduleStatus: schedState, VMRole: nodeRole, Data: &MachineData{ - IpOnInterface: make(map[string]string), + IPOnInterface: make(map[string]string), }, } } @@ -111,7 +113,7 @@ func NewMachine(bmh metal3.BareMetalHost, nodeRole airshipv1.VmRoles, schedState type MachineData struct { // Collect all IP's for the interfaces defined // In the list of Services - IpOnInterface map[string]string + IPOnInterface map[string]string } // MachineList contains the list of Scheduled or ToBeScheduled machines @@ -120,12 +122,11 @@ type MachineList struct { // ViNO Machines Machines map[string]*Machine // Keep track of how many we have mark for scheduled. - ReadyForScheduleCount map[airshipv1.VmRoles]int + ReadyForScheduleCount map[airshipv1.VMRoles]int Log logr.Logger } func (ml *MachineList) hasMachine(bmh metal3.BareMetalHost) bool { - if &bmh == nil { return false } @@ -133,13 +134,11 @@ func (ml *MachineList) hasMachine(bmh metal3.BareMetalHost) bool { } func (ml *MachineList) String() string { + // TODO(howell): This output probably isn't formatted properly var sb strings.Builder - for mName, machine := range ml.Machines { - sb.WriteString("[" + mName + "]:" + machine.String()) } - return sb.String() } @@ -169,17 +168,17 @@ func (ml *MachineList) Schedule(sip airshipv1.SIPCluster, c client.Client) error return nil } -func (ml *MachineList) init(nodes map[airshipv1.VmRoles]airshipv1.NodeSet) { +func (ml *MachineList) init(nodes map[airshipv1.VMRoles]airshipv1.NodeSet) { // Only Initialize 1st time if len(ml.Machines) == 0 { mlSize := 0 mlNodeTypes := 0 for _, nodeCfg := range nodes { mlSize = mlSize + nodeCfg.Count.Active + nodeCfg.Count.Standby - mlNodeTypes = mlNodeTypes + 1 + mlNodeTypes++ } - //fmt.Printf("Schedule.init mlSize:%d\n", mlSize) - ml.ReadyForScheduleCount = make(map[airshipv1.VmRoles]int, mlNodeTypes) + fmt.Printf("Schedule.init mlSize:%d\n", mlSize) + ml.ReadyForScheduleCount = make(map[airshipv1.VMRoles]int, mlNodeTypes) ml.Machines = make(map[string]*Machine, 0) } } @@ -200,7 +199,7 @@ func (ml *MachineList) getBMHs(c client.Client) (*metal3.BareMetalHostList, erro logger.Info("Getting all available BaremetalHosts that are not scheduled") err := c.List(context.Background(), bmhList, client.MatchingLabels(scheduleLabels)) if err != nil { - logger.Info("Recieved an error while getting BaremetalHost list", "error", err.Error()) + logger.Info("Received an error while getting BaremetalHost list", "error", err.Error()) return bmhList, err } logger.Info("Got a list of hosts", "BaremetalHostCount", len(bmhList.Items)) @@ -210,7 +209,8 @@ func (ml *MachineList) getBMHs(c client.Client) (*metal3.BareMetalHostList, erro return bmhList, fmt.Errorf("Unable to identify vBMH available for scheduling. Selecting %v ", scheduleLabels) } -func (ml *MachineList) identifyNodes(sip airshipv1.SIPCluster, bmhList *metal3.BareMetalHostList, c client.Client) error { +func (ml *MachineList) identifyNodes(sip airshipv1.SIPCluster, + bmhList *metal3.BareMetalHostList, c client.Client) error { logger := ml.Log.WithValues("SIPCluster", ml.NamespacedName) // If using the SIP Sheduled label, we now have a list of vBMH;'s // that are not scheduled @@ -220,10 +220,10 @@ func (ml *MachineList) identifyNodes(sip airshipv1.SIPCluster, bmhList *metal3.B // Only deals with AntiAffinity at : // - Racks : Dont select two machines in the same rack // - Server : Dont select two machines in the same server - logger.Info("Trying to identifiy BaremetalHosts that match scheduling parameters", + logger.Info("Trying to identify BaremetalHosts that match scheduling parameters", "initial BMH count", len(bmhList.Items)) for nodeRole, nodeCfg := range sip.Spec.Nodes { - logger := logger.WithValues("role", nodeRole) + logger := logger.WithValues("role", nodeRole) //nolint:govet ml.ReadyForScheduleCount[nodeRole] = 0 logger.Info("Getting host constraints") scheduleSetMap, err := ml.initScheduleMaps(nodeRole, nodeCfg.Scheduling) @@ -239,7 +239,8 @@ func (ml *MachineList) identifyNodes(sip airshipv1.SIPCluster, bmhList *metal3.B return nil } -func (ml *MachineList) initScheduleMaps(role airshipv1.VmRoles, constraint airshipv1.SpreadTopology) (*ScheduleSet, error) { +func (ml *MachineList) initScheduleMaps(role airshipv1.VMRoles, + constraint airshipv1.SpreadTopology) (*ScheduleSet, error) { logger := ml.Log.WithValues("SIPCluster", ml.NamespacedName, "role", role, "spread topology", constraint) var labelName string switch constraint { @@ -258,10 +259,10 @@ func (ml *MachineList) initScheduleMaps(role airshipv1.VmRoles, constraint airsh set: make(map[string]bool), labelName: labelName, }, nil - } -func (ml *MachineList) countScheduledAndTobeScheduled(nodeRole airshipv1.VmRoles, c client.Client, sipCfg *airshipv1.SipConfig) int { +func (ml *MachineList) countScheduledAndTobeScheduled(nodeRole airshipv1.VMRoles, + c client.Client, sipCfg *airshipv1.SipConfig) int { bmhList := &metal3.BareMetalHostList{} scheduleLabels := map[string]string{ @@ -282,14 +283,14 @@ func (ml *MachineList) countScheduledAndTobeScheduled(nodeRole airshipv1.VmRoles // With what is already there. logger.Info("Got already scheduled BaremetalHosts from kubernetes", "count", len(bmhList.Items)) for _, bmh := range bmhList.Items { - logger := logger.WithValues("BMH name", bmh.GetName()) + logger := logger.WithValues("BMH name", bmh.GetName()) //nolint:govet readyScheduled := !ml.hasMachine(bmh) logger.Info("Checking if BMH is already marked to be scheduled", "ready to be scheduled", readyScheduled) if readyScheduled { logger.Info("BMH host is not yet marked as ready to be scheduled, marking it as ready to be scheduled") // Add it to the list. ml.Machines[bmh.ObjectMeta.Name] = NewMachine(bmh, nodeRole, Scheduled) - ml.ReadyForScheduleCount[nodeRole] = ml.ReadyForScheduleCount[nodeRole] + 1 + ml.ReadyForScheduleCount[nodeRole]++ } } // ReadyForScheduleCount should include: @@ -299,8 +300,9 @@ func (ml *MachineList) countScheduledAndTobeScheduled(nodeRole airshipv1.VmRoles return ml.ReadyForScheduleCount[nodeRole] } -func (ml *MachineList) scheduleIt(nodeRole airshipv1.VmRoles, nodeCfg airshipv1.NodeSet, bmList *metal3.BareMetalHostList, - scheduleSet *ScheduleSet, c client.Client, sipCfg *airshipv1.SipConfig) error { +func (ml *MachineList) scheduleIt(nodeRole airshipv1.VMRoles, nodeCfg airshipv1.NodeSet, + bmList *metal3.BareMetalHostList, scheduleSet *ScheduleSet, + c client.Client, sipCfg *airshipv1.SipConfig) error { logger := ml.Log.WithValues("SIPCluster", ml.NamespacedName, "role", nodeRole) validBmh := true // Count the expectations stated in the CR @@ -314,19 +316,19 @@ func (ml *MachineList) scheduleIt(nodeRole airshipv1.VmRoles, nodeCfg airshipv1. if nodeTarget == 0 { return nil } - logger.Info("Checking list of BMH initialy received as not scheduled anywhere yet") + logger.Info("Checking list of BMH initially received as not scheduled anywhere yet") for _, bmh := range bmList.Items { - logger := logger.WithValues("BaremetalHost Name", bmh.GetName()) + logger := logger.WithValues("BaremetalHost Name", bmh.GetName()) //nolint:govet if !ml.hasMachine(bmh) { logger.Info("BaremetalHost not yet marked as ready to be scheduled") constraint := nodeCfg.Scheduling // Do I care about this constraint - logger := logger.WithValues("constraint", constraint) + logger := logger.WithValues("constraint", constraint) //nolint:govet if scheduleSet.Active() { logger.Info("constraint is active") // Check if bmh has the label - bmhConstraintCondition, flavorMatch := scheduleSet.GetLabels(bmh.Labels, nodeCfg.VmFlavor) + bmhConstraintCondition, flavorMatch := scheduleSet.GetLabels(bmh.Labels, nodeCfg.VMFlavor) logger.Info("Checked BMH constraint condition and flavor match", "constraint condition", bmhConstraintCondition, "flavor match", flavorMatch) @@ -336,7 +338,6 @@ func (ml *MachineList) scheduleIt(nodeRole airshipv1.VmRoles, nodeCfg airshipv1. // If its in the list already for the constraint , theen this bmh is disqualified. Skip it if scheduleSet.Exists(bmhConstraintCondition) { logger.Info("Constraint slot is alrady taken some BMH from this constraint is already allocated, skipping it") - validBmh = false break } else { scheduleSet.Add(bmhConstraintCondition) @@ -348,9 +349,11 @@ func (ml *MachineList) scheduleIt(nodeRole airshipv1.VmRoles, nodeCfg airshipv1. if validBmh { // Lets add it to the list as a schedulable thing ml.Machines[bmh.ObjectMeta.Name] = NewMachine(bmh, nodeRole, ToBeScheduled) - ml.ReadyForScheduleCount[nodeRole] = ml.ReadyForScheduleCount[nodeRole] + 1 - // TODO Probable should remove the bmh from the list so if there are other node targets they dont even take it into account - nodeTarget = nodeTarget - 1 + ml.ReadyForScheduleCount[nodeRole]++ + // TODO Probable should remove the bmh from the + // list so if there are other node targets they + // dont even take it into account + nodeTarget-- logger.Info("Marked node as ready to be scheduled", "BMH count to be scheduled", nodeTarget) if nodeTarget == 0 { break @@ -361,14 +364,13 @@ func (ml *MachineList) scheduleIt(nodeRole airshipv1.VmRoles, nodeCfg airshipv1. // ... validBmh = true } - } if nodeTarget > 0 { logger.Info("Failed to get enough BMHs to complete scheduling") return ErrorUnableToFullySchedule{ TargetNode: nodeRole, - TargetFlavor: nodeCfg.VmFlavor, + TargetFlavor: nodeCfg.VMFlavor, } } return nil @@ -380,17 +382,19 @@ func (ml *MachineList) Extrapolate(sip airshipv1.SIPCluster, c client.Client) bo extrapolateSuccess := true fmt.Printf("Schedule.Extrapolate ml.Vbmhs:%d\n", len(ml.Machines)) for _, machine := range ml.Machines { - fmt.Printf("Schedule.Extrapolate machine.Data.IpOnInterface len:%d machine:%v \n", len(machine.Data.IpOnInterface), machine) + fmt.Printf("Schedule.Extrapolate machine.Data.IPOnInterface len:%d machine:%v\n", + len(machine.Data.IPOnInterface), machine) // Skip if I alread extrapolated tehh data for this machine - if len(machine.Data.IpOnInterface) > 0 { + if len(machine.Data.IPOnInterface) > 0 { continue } bmh := machine.BMH // Identify Network Data Secret name networkDataSecret := &corev1.Secret{} - //fmt.Printf("Schedule.Extrapolate Namespace:%s Name:%s\n", bmh.Spec.NetworkData.Namespace, bmh.Spec.NetworkData.Name) + fmt.Printf("Schedule.Extrapolate Namespace:%s Name:%s\n", bmh.Spec.NetworkData.Namespace, + bmh.Spec.NetworkData.Name) // c is a created client. err := c.Get(context.Background(), client.ObjectKey{ Namespace: bmh.Spec.NetworkData.Namespace, @@ -398,21 +402,20 @@ func (ml *MachineList) Extrapolate(sip airshipv1.SIPCluster, c client.Client) bo }, networkDataSecret) if err != nil { machine.ScheduleStatus = UnableToSchedule - ml.ReadyForScheduleCount[machine.VMRole] = ml.ReadyForScheduleCount[machine.VMRole] - 1 + ml.ReadyForScheduleCount[machine.VMRole]-- extrapolateSuccess = false } //fmt.Printf("Schedule.Extrapolate networkDataSecret:%v\n", networkDataSecret) // Assuming there might be other data // Retrieve IP's for Service defined Network Interfaces - err = ml.getIp(machine, networkDataSecret, sip.Spec.InfraServices) + err = ml.getIP(machine, networkDataSecret, sip.Spec.InfraServices) if err != nil { // Lets mark the machine as NotScheduleable. // Update the count of what I have found so far, machine.ScheduleStatus = UnableToSchedule - ml.ReadyForScheduleCount[machine.VMRole] = ml.ReadyForScheduleCount[machine.VMRole] - 1 + ml.ReadyForScheduleCount[machine.VMRole]-- extrapolateSuccess = false } - } fmt.Printf("Schedule.Extrapolate extrapolateSuccess:%t\n", extrapolateSuccess) return extrapolateSuccess @@ -566,36 +569,40 @@ func (ml *MachineList) Extrapolate(sip airshipv1.SIPCluster, c client.Client) bo } ***/ -func (ml *MachineList) getIp(machine *Machine, networkDataSecret *corev1.Secret, infraServices map[airshipv1.InfraService]airshipv1.InfraConfig) error { +func (ml *MachineList) getIP(machine *Machine, networkDataSecret *corev1.Secret, + infraServices map[airshipv1.InfraService]airshipv1.InfraConfig) error { var secretData interface{} // Now I have the Secret // Lets find the IP's for all Interfaces defined in Cfg - foundIp := false + foundIP := false for svcName, svcCfg := range infraServices { - // Did I already find teh IP for these interface - if machine.Data.IpOnInterface[svcCfg.NodeInterface] == "" { - json.Unmarshal(networkDataSecret.Data["networkData"], &secretData) - //fmt.Printf("Schedule.Extrapolate.getIp secretData:%v\n", secretData) + // Did I already find the IP for these interface + if machine.Data.IPOnInterface[svcCfg.NodeInterface] == "" { + err := json.Unmarshal(networkDataSecret.Data["networkData"], &secretData) + if err != nil { + return err + } + fmt.Printf("Schedule.Extrapolate.getIP secretData:%v\n", secretData) queryFilter := fmt.Sprintf("$..networks[? (@.id==\"%s\")].ip_address", svcCfg.NodeInterface) - //fmt.Printf("Schedule.Extrapolate.getIp queryFilter:%v\n", queryFilter) - ip_address, err := jsonpath.Get(queryFilter, secretData) + fmt.Printf("Schedule.Extrapolate.getIP queryFilter:%v\n", queryFilter) + ipAddress, err := jsonpath.Get(queryFilter, secretData) if err == nil { - foundIp = true - for _, value := range ip_address.([]interface{}) { - machine.Data.IpOnInterface[svcCfg.NodeInterface] = value.(string) + foundIP = true + for _, value := range ipAddress.([]interface{}) { + machine.Data.IPOnInterface[svcCfg.NodeInterface] = value.(string) //nolint:errcheck } - } // Skip if error // Should signal that I need to exclude this machine // Which also means I am now short potentially. - fmt.Printf("Schedule.Extrapolate.getIp machine.Data.IpOnInterface[%s]:%v\n", svcCfg.NodeInterface, machine.Data.IpOnInterface[svcCfg.NodeInterface]) + fmt.Printf("Schedule.Extrapolate.getIP machine.Data.IpOnInterface[%s]:%v\n", + svcCfg.NodeInterface, machine.Data.IPOnInterface[svcCfg.NodeInterface]) } - if !foundIp { - return &ErrorHostIpNotFound{ + if !foundIP { + return &ErrorHostIPNotFound{ HostName: machine.BMH.ObjectMeta.Name, ServiceName: svcName, IPInterface: svcCfg.NodeInterface, @@ -612,7 +619,7 @@ func (ml *MachineList) getIp(machine *Machine, networkDataSecret *corev1.Secret, type ScheduleSet struct { // Defines if this set is actually active active bool - // Holds list of elements in teh Set + // Holds list of elements in the Set set map[string]bool // Holds the label name that identifies the constraint labelName string @@ -632,7 +639,7 @@ func (ss *ScheduleSet) Add(labelValue string) { ss.set[labelValue] = true } func (ss *ScheduleSet) GetLabels(labels map[string]string, flavorLabel string) (string, bool) { - //fmt.Printf("Schedule.scheduleIt.GetLabels labels:%v, flavorLabel:%s\n", labels, flavorLabel) + fmt.Printf("Schedule.scheduleIt.GetLabels labels:%v, flavorLabel:%s\n", labels, flavorLabel) if labels == nil { return "", false } @@ -646,12 +653,11 @@ func (ss *ScheduleSet) GetLabels(labels map[string]string, flavorLabel string) ( } /* -ApplyLabel : marks the appropriate machine labels to teh vBMH's that +ApplyLabel : marks the appropriate machine labels to the vBMH's that have benn selected by the scheduling. This is done only after the Infrastcuture Services have been deployed */ func (ml *MachineList) ApplyLabels(sip airshipv1.SIPCluster, c client.Client) error { - fmt.Printf("ApplyLabels %s size:%d\n", ml.String(), len(ml.Machines)) for _, machine := range ml.Machines { // Only Add LAbels to Machines that are not amrked to be scheduled @@ -677,10 +683,8 @@ func (ml *MachineList) ApplyLabels(sip airshipv1.SIPCluster, c client.Client) er // RemoveLabels removes sip related labels func (ml *MachineList) RemoveLabels(sip airshipv1.SIPCluster, c client.Client) error { - fmt.Printf("ApplyLabels %s size:%d\n", ml.String(), len(ml.Machines)) for _, machine := range ml.Machines { - bmh := &machine.BMH fmt.Printf("RemoveLabels bmh.ObjectMeta.Name:%s\n", bmh.ObjectMeta.Name) delete(bmh.Labels, SipClusterLabel) @@ -700,8 +704,7 @@ func (ml *MachineList) RemoveLabels(sip airshipv1.SIPCluster, c client.Client) e } func (ml *MachineList) GetCluster(sip airshipv1.SIPCluster, c client.Client) error { - - // Initialize teh Target list + // Initialize the Target list ml.init(sip.Spec.Nodes) bmhList := &metal3.BareMetalHostList{} @@ -719,9 +722,9 @@ func (ml *MachineList) GetCluster(sip airshipv1.SIPCluster, c client.Client) err ml.Machines[bmh.ObjectMeta.Name] = &Machine{ BMH: bmh, ScheduleStatus: Scheduled, - VMRole: airshipv1.VmRoles(bmh.Labels[SipNodeTypeLabel]), + VMRole: airshipv1.VMRoles(bmh.Labels[SipNodeTypeLabel]), Data: &MachineData{ - IpOnInterface: make(map[string]string), + IPOnInterface: make(map[string]string), }, } } diff --git a/pkg/vbmh/vbmh_test.go b/pkg/vbmh/vbmh_test.go index 9f0c4ec..8a8ffdf 100644 --- a/pkg/vbmh/vbmh_test.go +++ b/pkg/vbmh/vbmh_test.go @@ -25,7 +25,7 @@ var _ = Describe("MachineList", func() { nodes := map[string]*Machine{} for n := 0; n < numNodes; n++ { bmh, _ := testutil.CreateBMH(n, "default", "master", 6) - nodes[bmh.Name] = NewMachine(*bmh, airshipv1.VmMaster, NotScheduled) + nodes[bmh.Name] = NewMachine(*bmh, airshipv1.VMMaster, NotScheduled) } machineList = &MachineList{ @@ -105,19 +105,19 @@ var _ = Describe("MachineList", func() { Namespace: "default", }, Machines: map[string]*Machine{ - bmh.Name: NewMachine(*bmh, airshipv1.VmMaster, NotScheduled), + bmh.Name: NewMachine(*bmh, airshipv1.VMMaster, NotScheduled), }, - Log: ctrl.Log.WithName("controllers").WithName("SIPCluster"), + Log: ctrl.Log.WithName("controllers").WithName("SIPCluster"), } sipCluster := testutil.CreateSIPCluster("subcluster-1", "default", 1, 3) sipCluster.Spec.InfraServices = map[airshipv1.InfraService]airshipv1.InfraConfig{ - airshipv1.LoadBalancerService: airshipv1.InfraConfig{ + airshipv1.LoadBalancerService: { Image: "haproxy:latest", NodeLabels: map[string]string{ "test": "true", }, - NodePorts: []int{7000, 7001, 7002}, + NodePorts: []int{7000, 7001, 7002}, NodeInterface: "oam-ipv4", }, } @@ -125,7 +125,7 @@ var _ = Describe("MachineList", func() { Expect(ml.Extrapolate(*sipCluster, k8sClient)).To(BeTrue()) // NOTE(drewwalters96): Interface data is b64 encoded in the testutil convenience function. - Expect(ml.Machines[bmh.Name].Data.IpOnInterface).To(Equal(map[string]string{"oam-ipv4": "32.68.51.139"})) + Expect(ml.Machines[bmh.Name].Data.IPOnInterface).To(Equal(map[string]string{"oam-ipv4": "32.68.51.139"})) }) It("Should not retrieve the BMH IP from the BMH's NetworkData secret if no infraServices are defined", func() { @@ -142,23 +142,22 @@ var _ = Describe("MachineList", func() { Namespace: "default", }, Machines: map[string]*Machine{ - bmh.Name: NewMachine(*bmh, airshipv1.VmMaster, NotScheduled), + bmh.Name: NewMachine(*bmh, airshipv1.VMMaster, NotScheduled), }, - Log: ctrl.Log.WithName("controllers").WithName("SIPCluster"), + Log: ctrl.Log.WithName("controllers").WithName("SIPCluster"), } k8sClient := mockClient.NewFakeClient(objs...) sipCluster := testutil.CreateSIPCluster("subcluster-1", "default", 1, 3) Expect(ml.Extrapolate(*sipCluster, k8sClient)).To(BeTrue()) - Expect(len(ml.Machines[bmh.Name].Data.IpOnInterface)).To(Equal(0)) + Expect(len(ml.Machines[bmh.Name].Data.IPOnInterface)).To(Equal(0)) }) - It("Should not retrieve the BMH IP if it has been previously extrapolated", func() { // Store an IP address for each machine var objs []runtime.Object for _, machine := range machineList.Machines { - machine.Data.IpOnInterface = map[string]string{ + machine.Data.IPOnInterface = map[string]string{ "oam-ipv4": "32.68.51.139", } objs = append(objs, &machine.BMH) diff --git a/testutil/testutil.go b/testutil/testutil.go index 4ae8806..52f08dc 100644 --- a/testutil/testutil.go +++ b/testutil/testutil.go @@ -163,7 +163,7 @@ const ( }` ) -// CreateBMH initializes a BaremetalHost with specific parameteres for use in test cases. +// CreateBMH initializes a BaremetalHost with specific parameters for use in test cases. func CreateBMH(node int, namespace string, role string, rack int) (*metal3.BareMetalHost, *corev1.Secret) { rackLabel := fmt.Sprintf("r%d", rack) networkDataName := fmt.Sprintf("node%d-network-data", node) @@ -211,19 +211,19 @@ func CreateSIPCluster(name string, namespace string, masters int, workers int) * Config: &airshipv1.SipConfig{ ClusterName: name, }, - Nodes: map[airshipv1.VmRoles]airshipv1.NodeSet{ - airshipv1.VmMaster: airshipv1.NodeSet{ - VmFlavor: "airshipit.org/vino-flavor=master", + Nodes: map[airshipv1.VMRoles]airshipv1.NodeSet{ + airshipv1.VMMaster: { + VMFlavor: "airshipit.org/vino-flavor=master", Scheduling: airshipv1.ServerAntiAffinity, - Count: &airshipv1.VmCount{ + Count: &airshipv1.VMCount{ Active: masters, Standby: 0, }, }, - airshipv1.VmWorker: airshipv1.NodeSet{ - VmFlavor: "airshipit.org/vino-flavor=worker", + airshipv1.VMWorker: { + VMFlavor: "airshipit.org/vino-flavor=worker", Scheduling: airshipv1.ServerAntiAffinity, - Count: &airshipv1.VmCount{ + Count: &airshipv1.VMCount{ Active: workers, Standby: 0, },