
- Add API to configure a node port range - Map each port to same port on sub-cluster - Implement haproxy settings for workload services, including tcp connect health checks TODO (later): - The existing singular NodePort field is now ignored for this service, since the node port range is used instead, and so should be removed, which will require some refactoring of base service types. Change-Id: I6a5be3e330270c13c3d42c8bba4004b67524911d
339 lines
10 KiB
Go
339 lines
10 KiB
Go
package testutil
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/onsi/gomega"
|
|
|
|
metal3 "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
"k8s.io/apimachinery/pkg/selection"
|
|
|
|
airshipv1 "sipcluster/pkg/api/v1"
|
|
)
|
|
|
|
var bmhRoleToLabelValue = map[airshipv1.BMHRole]string{
|
|
airshipv1.RoleControlPlane: "control-plane",
|
|
airshipv1.RoleWorker: "worker",
|
|
}
|
|
|
|
func UnscheduledSelector() labels.Selector {
|
|
sel := labels.NewSelector()
|
|
r, err := labels.NewRequirement(sipClusterNameLabel, selection.DoesNotExist, nil)
|
|
gomega.Expect(err).Should(gomega.Succeed())
|
|
return sel.Add(*r)
|
|
}
|
|
|
|
const (
|
|
// NOTE(aw442m): These constants have been redefined from the bmh package in order to avoid an import cycle.
|
|
sipClusterNameLabel = "sip.airshipit.org/cluster-name"
|
|
|
|
HostLabel = "vino.airshipit.org/host"
|
|
RackLabel = "vino.airshipit.org/rack"
|
|
bmhLabel = "example.org/bmh-label"
|
|
|
|
sshPrivateKeyBase64 = "DUMMY_DATA"
|
|
|
|
networkDataContent = `
|
|
{
|
|
"links": [
|
|
{
|
|
"id": "eno4",
|
|
"name": "eno4",
|
|
"type": "phy",
|
|
"mtu": 1500
|
|
},
|
|
{
|
|
"id": "enp59s0f1",
|
|
"name": "enp59s0f1",
|
|
"type": "phy",
|
|
"mtu": 9100
|
|
},
|
|
{
|
|
"id": "enp216s0f0",
|
|
"name": "enp216s0f0",
|
|
"type": "phy",
|
|
"mtu": 9100
|
|
},
|
|
{
|
|
"id": "bond0",
|
|
"name": "bond0",
|
|
"type": "bond",
|
|
"bond_links": [
|
|
"enp59s0f1",
|
|
"enp216s0f0"
|
|
],
|
|
"bond_mode": "802.3ad",
|
|
"bond_xmit_hash_policy": "layer3+4",
|
|
"bond_miimon": 100,
|
|
"mtu": 9100
|
|
},
|
|
{
|
|
"id": "bond0.41",
|
|
"name": "bond0.41",
|
|
"type": "vlan",
|
|
"vlan_link": "bond0",
|
|
"vlan_id": 41,
|
|
"mtu": 9100,
|
|
"vlan_mac_address": null
|
|
},
|
|
{
|
|
"id": "bond0.42",
|
|
"name": "bond0.42",
|
|
"type": "vlan",
|
|
"vlan_link": "bond0",
|
|
"vlan_id": 42,
|
|
"mtu": 9100,
|
|
"vlan_mac_address": null
|
|
},
|
|
{
|
|
"id": "bond0.44",
|
|
"name": "bond0.44",
|
|
"type": "vlan",
|
|
"vlan_link": "bond0",
|
|
"vlan_id": 44,
|
|
"mtu": 9100,
|
|
"vlan_mac_address": null
|
|
},
|
|
{
|
|
"id": "bond0.45",
|
|
"name": "bond0.45",
|
|
"type": "vlan",
|
|
"vlan_link": "bond0",
|
|
"vlan_id": 45,
|
|
"mtu": 9100,
|
|
"vlan_mac_address": null
|
|
}
|
|
],
|
|
"networks": [
|
|
{
|
|
"id": "oam-ipv6",
|
|
"type": "ipv6",
|
|
"link": "bond0.41",
|
|
"ip_address": "2001:1890:1001:293d::139",
|
|
"routes": [
|
|
{
|
|
"network": "::/0",
|
|
"netmask": "::/0",
|
|
"gateway": "2001:1890:1001:293d::1"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "oam-ipv4",
|
|
"type": "ipv4",
|
|
"link": "bond0.41",
|
|
"ip_address": "32.68.51.139",
|
|
"netmask": "255.255.255.128",
|
|
"dns_nameservers": [
|
|
"135.188.34.124",
|
|
"135.38.244.16",
|
|
"135.188.34.84"
|
|
],
|
|
"routes": [
|
|
{
|
|
"network": "0.0.0.0",
|
|
"netmask": "0.0.0.0",
|
|
"gateway": "32.68.51.129"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "pxe-ipv6",
|
|
"link": "eno4",
|
|
"type": "ipv6",
|
|
"ip_address": "fd00:900:100:138::11"
|
|
},
|
|
{
|
|
"id": "pxe-ipv4",
|
|
"link": "eno4",
|
|
"type": "ipv4",
|
|
"ip_address": "172.30.0.11",
|
|
"netmask": "255.255.255.128"
|
|
},
|
|
{
|
|
"id": "storage-ipv6",
|
|
"link": "bond0.42",
|
|
"type": "ipv6",
|
|
"ip_address": "fd00:900:100:139::15"
|
|
},
|
|
{
|
|
"id": "storage-ipv4",
|
|
"link": "bond0.42",
|
|
"type": "ipv4",
|
|
"ip_address": "172.31.1.15",
|
|
"netmask": "255.255.255.128"
|
|
},
|
|
{
|
|
"id": "ksn-ipv6",
|
|
"link": "bond0.44",
|
|
"type": "ipv6",
|
|
"ip_address": "fd00:900:100:13a::11"
|
|
},
|
|
{
|
|
"id": "ksn-ipv4",
|
|
"link": "bond0.44",
|
|
"type": "ipv4",
|
|
"ip_address": "172.29.0.11",
|
|
"netmask": "255.255.255.128"
|
|
}
|
|
]
|
|
}`
|
|
)
|
|
|
|
// CreateBMH initializes a BaremetalHost with specific parameters for use in test cases.
|
|
func CreateBMH(node int, namespace string, role airshipv1.BMHRole, rack int) (*metal3.BareMetalHost, *corev1.Secret) {
|
|
rackLabelValue := fmt.Sprintf("r%d", rack)
|
|
hostLabelValue := fmt.Sprintf("stl2%so%d", rackLabelValue, node)
|
|
networkDataName := fmt.Sprintf("node%d-network-data", node)
|
|
return &metal3.BareMetalHost{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: fmt.Sprintf("node0%d", node),
|
|
Namespace: namespace,
|
|
Labels: map[string]string{
|
|
bmhLabel: bmhRoleToLabelValue[role],
|
|
RackLabel: rackLabelValue,
|
|
HostLabel: hostLabelValue,
|
|
},
|
|
},
|
|
Spec: metal3.BareMetalHostSpec{
|
|
NetworkData: &corev1.SecretReference{
|
|
Namespace: namespace,
|
|
Name: networkDataName,
|
|
},
|
|
BMC: metal3.BMCDetails{
|
|
Address: "redfish+https://32.68.51.12/redfish/v1/Systems/System.Embedded.1",
|
|
},
|
|
},
|
|
}, &corev1.Secret{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: networkDataName,
|
|
Namespace: namespace,
|
|
},
|
|
Data: map[string][]byte{
|
|
"networkData": []byte(networkDataContent),
|
|
},
|
|
Type: corev1.SecretTypeOpaque,
|
|
}
|
|
}
|
|
|
|
// CreateSIPCluster initializes a SIPCluster with specific parameters for use in test cases.
|
|
func CreateSIPCluster(name string, namespace string, controlPlanes int, workers int) (
|
|
*airshipv1.SIPCluster, *corev1.Secret) {
|
|
sshPrivateKeySecretName := fmt.Sprintf("%s-ssh-private-key", name)
|
|
return &airshipv1.SIPCluster{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "SIPCluster",
|
|
APIVersion: "airship.airshipit.org/v1",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
Namespace: namespace,
|
|
},
|
|
Spec: airshipv1.SIPClusterSpec{
|
|
Nodes: map[airshipv1.BMHRole]airshipv1.NodeSet{
|
|
airshipv1.RoleControlPlane: {
|
|
LabelSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
bmhLabel: bmhRoleToLabelValue[airshipv1.RoleControlPlane],
|
|
},
|
|
},
|
|
TopologyKey: HostLabel,
|
|
Count: &airshipv1.NodeCount{
|
|
Active: controlPlanes,
|
|
Standby: 0,
|
|
},
|
|
},
|
|
airshipv1.RoleWorker: {
|
|
LabelSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
bmhLabel: bmhRoleToLabelValue[airshipv1.RoleWorker],
|
|
},
|
|
},
|
|
TopologyKey: HostLabel,
|
|
Count: &airshipv1.NodeCount{
|
|
Active: workers,
|
|
Standby: 0,
|
|
},
|
|
},
|
|
},
|
|
Services: airshipv1.SIPClusterServices{
|
|
JumpHost: []airshipv1.JumpHostService{
|
|
{
|
|
SIPClusterService: airshipv1.SIPClusterService{
|
|
Image: "quay.io/airshipit/jump-host",
|
|
NodePort: 30000,
|
|
NodeInterface: "eno3",
|
|
},
|
|
SSHAuthorizedKeys: []string{
|
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCyaozS8kZRw2a1d0O4YXhxtJlDPThqIZilGCsXLbukIFOyMUmMTwQAtwWp5epwU1+5ponC2uBENB6xCCj3cl5Rd43d2/B6HxyAPQGKo6/zKYGAKW2nzYDxSWMl6NUSsiJAyXUA7ZlNZQe0m8PmaferlkQyLLZo3NJpizz6U6ZCtxvj43vEl7NYWnLUEIzGP9zMqltIGnD4vYrU9keVKKXSsp+DkApnbrDapeigeGATCammy2xRrUQDuOvGHsfnQbXr2j0onpTIh0PiLrXLQAPDg8UJRgVB+ThX+neI3rQ320djzRABckNeE6e4Kkwzn+QdZsmA2SDvM9IU7boK1jVQlgUPp7zF5q3hbb8Rx7AadyTarBayUkCgNlrMqth+tmTMWttMqCPxJRGnhhvesAHIl55a28Kzz/2Oqa3J9zwzbyDIwlEXho0eAq3YXEPeBhl34k+7gOt/5Zdbh+yacFoxDh0LrshQgboAijcVVaXPeN0LsHEiVvYIzugwIvCkoFMPWoPj/kEGzPY6FCkVneDA7VoLTCoG8dlrN08Lf05/BGC7Wllm66pTNZC/cKXP+cjpQn1iEuiuPxnPldlMHx9sx2y/BRoft6oT/GzqkNy1NTY/xI+MfmxXnF5kwSbcTbzZQ9fZ8xjh/vmpPBgDNrxOEAT4N6OG7GQIhb9HEhXQCQ== example-key", //nolint
|
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwpOyZjZ4gB0OTvmofH3llh6cBCWaEiEmHZWSkDXr8Bih6HcXVOtYMcFi/ZnUVGUBPw3ATNQBZUaVCYKeF+nDfKTJ9hmnlsyHxV2LeMsVg1o15Pb6f+QJuavEqtE6HI7mHyId4Z1quVTJXDWDW8OZEG7M3VktauqAn/e9UJvlL0bGmTFD1XkNcbRsWMRWkQgt2ozqlgrpPtvrg2/+bNucxX++VUjnsn+fGgAT07kbnrZwppGnAfjbYthxhv7GeSD0+Z0Lf1kiKy/bhUqXsZIuexOfF0YrRyUH1KBl8GCX2OLBYvXHyusByqsrOPiROqRdjX5PsK6HSAS0lk0niTt1p example-key-2", // nolint
|
|
},
|
|
NodeSSHPrivateKeys: sshPrivateKeySecretName,
|
|
},
|
|
},
|
|
LoadBalancerControlPlane: []airshipv1.LoadBalancerServiceControlPlane{
|
|
{
|
|
SIPClusterService: airshipv1.SIPClusterService{
|
|
NodeInterface: "eno3",
|
|
NodePort: 30001,
|
|
},
|
|
},
|
|
},
|
|
LoadBalancerWorker: []airshipv1.LoadBalancerServiceWorker{
|
|
{
|
|
SIPClusterService: airshipv1.SIPClusterService{
|
|
NodeInterface: "eno3",
|
|
NodePort: 30002,
|
|
},
|
|
NodePortRange: airshipv1.PortRange{
|
|
Start: 30002,
|
|
End: 30011,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Status: airshipv1.SIPClusterStatus{},
|
|
},
|
|
&corev1.Secret{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: sshPrivateKeySecretName,
|
|
Namespace: namespace,
|
|
},
|
|
Data: map[string][]byte{
|
|
"key": []byte(sshPrivateKeyBase64),
|
|
},
|
|
Type: corev1.SecretTypeOpaque,
|
|
}
|
|
}
|
|
|
|
// CreateBMCAuthSecret creates a K8s Secret that matches the Metal3.io BaremetalHost credential format for use in test
|
|
// cases.
|
|
func CreateBMCAuthSecret(nodeName string, namespace string, username string, password string) *corev1.Secret {
|
|
return &corev1.Secret{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: corev1.SchemeGroupVersion.String(),
|
|
Kind: "Secret",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: fmt.Sprintf("%s-bmc-credentials", nodeName),
|
|
Namespace: namespace,
|
|
},
|
|
Data: map[string][]byte{
|
|
"username": []byte(username),
|
|
"password": []byte(password),
|
|
},
|
|
}
|
|
}
|
|
|
|
func CompareLabels(expected labels.Selector, actual map[string]string) error {
|
|
if !expected.Matches(labels.Set(actual)) {
|
|
return fmt.Errorf("labels do not match expected selector %v. Has labels %v", expected, actual)
|
|
}
|
|
|
|
return nil
|
|
}
|