Enabling Liveness and Readiness Probes in ACI Provider (#280)

* Enabling Liveness and Readiness Probes in ACI Provider

* Adding a check to ensure both exec and httpGet are not provided
This commit is contained in:
Jeremy Rickard
2018-07-30 14:38:36 -06:00
committed by Robbie Zhang
parent 13fbd5c38e
commit a4d8f74c7d
2 changed files with 181 additions and 0 deletions

View File

@@ -722,11 +722,67 @@ func (p *ACIProvider) getContainers(pod *v1.Pod) ([]aci.Container, error) {
}
}
if container.LivenessProbe != nil {
probe, err := getProbe(container.LivenessProbe)
if err != nil {
return nil, err
}
c.LivenessProbe = probe
}
if container.ReadinessProbe != nil {
probe, err := getProbe(container.ReadinessProbe)
if err != nil {
return nil, err
}
c.ReadinessProbe = probe
}
containers = append(containers, c)
}
return containers, nil
}
func getProbe(probe *v1.Probe) (*aci.ContainerProbe, error) {
if probe.Handler.Exec != nil && probe.Handler.HTTPGet != nil {
return nil, fmt.Errorf("probe may not specify more than one of \"exec\" and \"httpGet\"")
}
if probe.Handler.Exec == nil && probe.Handler.HTTPGet == nil {
return nil, fmt.Errorf("probe must specify one of \"exec\" and \"httpGet\"")
}
// Probes have can have a Exec or HTTP Get Handler.
// Create those if they exist, then add to the
// ContainerProbe struct
var exec *aci.ContainerExecProbe
if probe.Handler.Exec != nil {
exec = &aci.ContainerExecProbe{
Command: probe.Handler.Exec.Command,
}
}
var httpGET *aci.ContainerHTTPGetProbe
if probe.Handler.HTTPGet != nil {
httpGET = &aci.ContainerHTTPGetProbe{
Port: probe.Handler.HTTPGet.Port.IntValue(),
Path: probe.Handler.HTTPGet.Path,
Scheme: string(probe.Handler.HTTPGet.Scheme),
}
}
return &aci.ContainerProbe{
Exec: exec,
HTTPGet: httpGET,
InitialDelaySeconds: probe.InitialDelaySeconds,
Period: probe.PeriodSeconds,
FailureThreshold: probe.FailureThreshold,
SuccessThreshold: probe.SuccessThreshold,
TimeoutSeconds: probe.TimeoutSeconds,
}, nil
}
func (p *ACIProvider) getVolumes(pod *v1.Pod) ([]aci.Volume, error) {
volumes := make([]aci.Volume, 0, len(pod.Spec.Volumes))
for _, v := range pod.Spec.Volumes {

View File

@@ -20,6 +20,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes/fake"
)
@@ -460,3 +461,127 @@ func prepareMocks() (*AADMock, *ACIMock, *ACIProvider, error) {
func ptrQuantity(q resource.Quantity) *resource.Quantity {
return &q
}
func TestCreatePodWithLivenessProbe(t *testing.T) {
_, aciServerMocker, provider, err := prepareMocks()
if err != nil {
t.Fatal("Unable to prepare the mocks", err)
}
podName := "pod-" + uuid.New().String()
podNamespace := "ns-" + uuid.New().String()
aciServerMocker.OnCreate = func(subscription, resourceGroup, containerGroup string, cg *aci.ContainerGroup) (int, interface{}) {
assert.Equal(t, fakeSubscription, subscription, "Subscription doesn't match")
assert.Equal(t, fakeResourceGroup, resourceGroup, "Resource group doesn't match")
assert.NotNil(t, cg, "Container group is nil")
assert.Equal(t, podNamespace+"-"+podName, containerGroup, "Container group name is not expected")
assert.NotNil(t, cg.ContainerGroupProperties, "Container group properties should not be nil")
assert.NotNil(t, cg.ContainerGroupProperties.Containers, "Containers should not be nil")
assert.Equal(t, 1, len(cg.ContainerGroupProperties.Containers), "1 Container is expected")
assert.Equal(t, "nginx", cg.ContainerGroupProperties.Containers[0].Name, "Container nginx is expected")
assert.NotNil(t, cg.Containers[0].LivenessProbe, "Liveness probe expected")
assert.Equal(t, cg.Containers[0].LivenessProbe.InitialDelaySeconds, 10, "Initial Probe Delay doesn't match")
assert.Equal(t, cg.Containers[0].LivenessProbe.Period, 5, "Probe Period doesn't match")
assert.Equal(t, cg.Containers[0].LivenessProbe.TimeoutSeconds, 60, "Probe Timeout doesn't match")
assert.Equal(t, cg.Containers[0].LivenessProbe.SuccessThreshold, 3, "Probe Success Threshold doesn't match")
assert.Equal(t, cg.Containers[0].LivenessProbe.FailureThreshold, 5, "Probe Failure Threshold doesn't match")
assert.NotNil(t, cg.Containers[0].LivenessProbe.HTTPGet, "Expected an HTTP Get Probe")
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: podName,
Namespace: podNamespace,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
v1.Container{
Name: "nginx",
LivenessProbe: &v1.Probe{
Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{
Port: intstr.FromString("8080"),
Path: "/",
},
},
InitialDelaySeconds: 10,
PeriodSeconds: 5,
TimeoutSeconds: 60,
SuccessThreshold: 3,
FailureThreshold: 5,
},
},
},
},
}
if err := provider.CreatePod(pod); err != nil {
t.Fatal("Failed to create pod", err)
}
return http.StatusOK, cg
}
}
func TestCreatePodWithReadinessProbe(t *testing.T) {
_, aciServerMocker, provider, err := prepareMocks()
if err != nil {
t.Fatal("Unable to prepare the mocks", err)
}
podName := "pod-" + uuid.New().String()
podNamespace := "ns-" + uuid.New().String()
aciServerMocker.OnCreate = func(subscription, resourceGroup, containerGroup string, cg *aci.ContainerGroup) (int, interface{}) {
assert.Equal(t, fakeSubscription, subscription, "Subscription doesn't match")
assert.Equal(t, fakeResourceGroup, resourceGroup, "Resource group doesn't match")
assert.NotNil(t, cg, "Container group is nil")
assert.Equal(t, podNamespace+"-"+podName, containerGroup, "Container group name is not expected")
assert.NotNil(t, cg.ContainerGroupProperties, "Container group properties should not be nil")
assert.NotNil(t, cg.ContainerGroupProperties.Containers, "Containers should not be nil")
assert.Equal(t, 1, len(cg.ContainerGroupProperties.Containers), "1 Container is expected")
assert.Equal(t, "nginx", cg.ContainerGroupProperties.Containers[0].Name, "Container nginx is expected")
assert.NotNil(t, cg.Containers[0].ReadinessProbe, "Readiness probe expected")
assert.Equal(t, cg.Containers[0].ReadinessProbe.InitialDelaySeconds, 10, "Initial Probe Delay doesn't match")
assert.Equal(t, cg.Containers[0].ReadinessProbe.Period, 5, "Probe Period doesn't match")
assert.Equal(t, cg.Containers[0].ReadinessProbe.TimeoutSeconds, 60, "Probe Timeout doesn't match")
assert.Equal(t, cg.Containers[0].ReadinessProbe.SuccessThreshold, 3, "Probe Success Threshold doesn't match")
assert.Equal(t, cg.Containers[0].ReadinessProbe.FailureThreshold, 5, "Probe Failure Threshold doesn't match")
assert.NotNil(t, cg.Containers[0].ReadinessProbe.HTTPGet, "Expected an HTTP Get Probe")
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: podName,
Namespace: podNamespace,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
v1.Container{
Name: "nginx",
ReadinessProbe: &v1.Probe{
Handler: v1.Handler{
HTTPGet: &v1.HTTPGetAction{
Port: intstr.FromString("8080"),
Path: "/",
},
},
InitialDelaySeconds: 10,
PeriodSeconds: 5,
TimeoutSeconds: 60,
SuccessThreshold: 3,
FailureThreshold: 5,
},
},
},
},
}
if err := provider.CreatePod(pod); err != nil {
t.Fatal("Failed to create pod", err)
}
return http.StatusOK, cg
}
}