
This removes references to "vm", "vino", and "vbmh" in the API and replaces them with "bmh" since at least the existing functionality of SIP is applicable to any BMH, not just those backed by vino/VMs. If/when we add functionality specific to VM nodes, the API for those features should be named/documented accordingly. This also updates BMH scheduling to support arbitrary label selectors [0]. [0]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements Closes: #8 Closes: #9 Change-Id: I105fe3dc854c032c755997c47c24997a03cd65e6
224 lines
5.9 KiB
Go
224 lines
5.9 KiB
Go
package services_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
|
|
airshipv1 "sipcluster/pkg/api/v1"
|
|
|
|
metal3 "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
appsv1 "k8s.io/api/apps/v1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
"sipcluster/pkg/bmh"
|
|
"sipcluster/pkg/services"
|
|
"sipcluster/testutil"
|
|
)
|
|
|
|
const (
|
|
ip1 = "192.168.0.1"
|
|
ip2 = "192.168.0.2"
|
|
)
|
|
|
|
var bmh1 *metal3.BareMetalHost
|
|
var bmh2 *metal3.BareMetalHost
|
|
|
|
var m1 *bmh.Machine
|
|
var m2 *bmh.Machine
|
|
|
|
// Re-declared from services package for testing purposes
|
|
type host struct {
|
|
Name string `json:"name"`
|
|
BMC bmc `json:"bmc"`
|
|
}
|
|
|
|
type bmc struct {
|
|
IP string `json:"ip"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
var _ = Describe("Service Set", func() {
|
|
var machineList *bmh.MachineList
|
|
BeforeEach(func() {
|
|
bmh1, _ = testutil.CreateBMH(1, "default", "control-plane", 1)
|
|
bmh2, _ = testutil.CreateBMH(2, "default", "control-plane", 2)
|
|
|
|
bmcUsername := "root"
|
|
bmcPassword := "password"
|
|
bmcSecret := testutil.CreateBMCAuthSecret(bmh1.GetName(), bmh1.GetNamespace(), bmcUsername,
|
|
bmcPassword)
|
|
Expect(k8sClient.Create(context.Background(), bmcSecret)).Should(Succeed())
|
|
|
|
bmh1.Spec.BMC.CredentialsName = bmcSecret.Name
|
|
bmh2.Spec.BMC.CredentialsName = bmcSecret.Name
|
|
|
|
m1 = &bmh.Machine{
|
|
BMH: *bmh1,
|
|
Data: &bmh.MachineData{
|
|
IPOnInterface: map[string]string{
|
|
"eno3": ip1,
|
|
},
|
|
},
|
|
}
|
|
|
|
m2 = &bmh.Machine{
|
|
BMH: *bmh2,
|
|
Data: &bmh.MachineData{
|
|
IPOnInterface: map[string]string{
|
|
"eno3": ip2,
|
|
},
|
|
},
|
|
}
|
|
|
|
machineList = &bmh.MachineList{
|
|
Machines: map[string]*bmh.Machine{
|
|
bmh1.GetName(): m1,
|
|
bmh2.GetName(): m2,
|
|
},
|
|
}
|
|
})
|
|
|
|
AfterEach(func() {
|
|
opts := []client.DeleteAllOfOption{client.InNamespace("default")}
|
|
Expect(k8sClient.DeleteAllOf(context.Background(), &metal3.BareMetalHost{}, opts...)).Should(Succeed())
|
|
Expect(k8sClient.DeleteAllOf(context.Background(), &airshipv1.SIPCluster{}, opts...)).Should(Succeed())
|
|
Expect(k8sClient.DeleteAllOf(context.Background(), &corev1.Secret{}, opts...)).Should(Succeed())
|
|
})
|
|
|
|
Context("When new SIP cluster is created", func() {
|
|
It("Deploys services", func() {
|
|
By("Getting machine IPs and creating secrets, pods, and nodeport service")
|
|
|
|
sipCluster, nodeSSHPrivateKeys := testutil.CreateSIPCluster("default", "default", 1, 1)
|
|
Expect(k8sClient.Create(context.Background(), nodeSSHPrivateKeys)).Should(Succeed())
|
|
machineList = &bmh.MachineList{
|
|
Machines: map[string]*bmh.Machine{
|
|
bmh1.GetName(): m1,
|
|
bmh2.GetName(): m2,
|
|
},
|
|
}
|
|
|
|
set := services.NewServiceSet(logger, *sipCluster, machineList, k8sClient)
|
|
|
|
serviceList, err := set.ServiceList()
|
|
Expect(serviceList).To(HaveLen(2))
|
|
Expect(err).To(Succeed())
|
|
for _, svc := range serviceList {
|
|
err := svc.Deploy()
|
|
Expect(err).ToNot(HaveOccurred())
|
|
}
|
|
|
|
Eventually(func() error {
|
|
return testDeployment(sipCluster, *machineList)
|
|
}, 5, 1).Should(Succeed())
|
|
})
|
|
|
|
It("Does not deploy a Jump Host when an invalid SSH key is provided", func() {
|
|
sip, _ := testutil.CreateSIPCluster("default", "default", 1, 1)
|
|
sip.Spec.Services.Auth = []airshipv1.SIPClusterService{}
|
|
sip.Spec.Services.LoadBalancer = []airshipv1.SIPClusterService{}
|
|
sip.Spec.Services.JumpHost[0].SSHAuthorizedKeys = []string{
|
|
"sshrsaAAAAAAAAAAAAAAAAAAAAAinvalidkey",
|
|
}
|
|
|
|
set := services.NewServiceSet(logger, *sip, machineList, k8sClient)
|
|
serviceList, err := set.ServiceList()
|
|
Expect(err).To(Succeed())
|
|
|
|
for _, svc := range serviceList {
|
|
err := svc.Deploy()
|
|
Expect(err).To(HaveOccurred())
|
|
}
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
func testDeployment(sip *airshipv1.SIPCluster, machineList bmh.MachineList) error {
|
|
loadBalancerDeployment := &appsv1.Deployment{}
|
|
err := k8sClient.Get(context.Background(), types.NamespacedName{
|
|
Namespace: "default",
|
|
Name: services.LoadBalancerServiceName + "-" + sip.GetName(),
|
|
}, loadBalancerDeployment)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
loadBalancerSecret := &corev1.Secret{}
|
|
err = k8sClient.Get(context.Background(), types.NamespacedName{
|
|
Namespace: "default",
|
|
Name: services.LoadBalancerServiceName + "-" + sip.GetName(),
|
|
}, loadBalancerSecret)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
loadBalancerService := &corev1.Service{}
|
|
err = k8sClient.Get(context.Background(), types.NamespacedName{
|
|
Namespace: "default",
|
|
Name: services.LoadBalancerServiceName + "-" + sip.GetName(),
|
|
}, loadBalancerService)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
jumpHostDeployment := &appsv1.Deployment{}
|
|
err = k8sClient.Get(context.Background(), types.NamespacedName{
|
|
Namespace: "default",
|
|
Name: services.JumpHostServiceName + "-" + sip.GetName(),
|
|
}, jumpHostDeployment)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
jumpHostHostAliases := jumpHostDeployment.Spec.Template.Spec.HostAliases
|
|
Expect(jumpHostHostAliases).To(ConsistOf(
|
|
corev1.HostAlias{
|
|
IP: ip1,
|
|
Hostnames: []string{bmh1.GetName()},
|
|
},
|
|
corev1.HostAlias{
|
|
IP: ip2,
|
|
Hostnames: []string{bmh2.GetName()},
|
|
},
|
|
))
|
|
|
|
jumpHostService := &corev1.Service{}
|
|
err = k8sClient.Get(context.Background(), types.NamespacedName{
|
|
Namespace: "default",
|
|
Name: services.JumpHostServiceName + "-" + sip.GetName(),
|
|
}, jumpHostService)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
jumpHostSecret := &corev1.Secret{}
|
|
err = k8sClient.Get(context.Background(), types.NamespacedName{
|
|
Namespace: "default",
|
|
Name: services.JumpHostServiceName + "-" + sip.GetName(),
|
|
}, jumpHostSecret)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var hosts []host
|
|
err = json.Unmarshal(jumpHostSecret.Data["hosts"], &hosts)
|
|
Expect(err).To(BeNil())
|
|
for _, host := range hosts {
|
|
for _, machine := range machineList.Machines {
|
|
if host.Name == machine.BMH.Name {
|
|
Expect(host.BMC.Username).To(Equal(machine.Data.BMCUsername))
|
|
Expect(host.BMC.Password).To(Equal(machine.Data.BMCPassword))
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|