Skip to content

Commit

Permalink
[PWX-38584][PWX-38575] Updated Autopilot deployment to include readin…
Browse files Browse the repository at this point in the history
…ess checks
  • Loading branch information
Manali Daigavane committed Aug 21, 2024
1 parent 30ed9ab commit 283c360
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ operator:

container:
@echo "Building operator image $(OPERATOR_IMG)"
docker build --pull --tag $(OPERATOR_IMG) -f build/Dockerfile .
docker build --no-cache --pull --tag $(OPERATOR_IMG) -f build/Dockerfile .

DOCK_BUILD_CNT := golang:1.21

Expand Down
55 changes: 52 additions & 3 deletions drivers/storage/portworx/component/autopilot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package component
import (
"context"
"fmt"
coreops "github.com/portworx/sched-ops/k8s/core"
authv1 "k8s.io/api/authentication/v1"
"k8s.io/kubernetes/pkg/apis/core"
"reflect"
"sort"
"strings"
"time"

coreops "github.com/portworx/sched-ops/k8s/core"
authv1 "k8s.io/api/authentication/v1"
"k8s.io/kubernetes/pkg/apis/core"

"github.com/sirupsen/logrus"

"github.com/hashicorp/go-version"
Expand Down Expand Up @@ -650,6 +651,31 @@ func (c *autopilot) createDeployment(
return nil
}

// Function to check if ReadinessProbe should be added to the autopilot container
// Readiness probe is added to the autopilot container if the image version is greater than 1.3.15
// as autopilot container has a /ready endpoint from 1.3.15 onwards
func shouldAddReadinessProbe(image string) bool {
// Get the image tag using the existing function
imageVersion := pxutil.GetImageTag(image)

if imageVersion == "" {
logrus.Errorf("Could not extract version from image: %s", image)
return false

Check warning on line 663 in drivers/storage/portworx/component/autopilot.go

View check run for this annotation

Codecov / codecov/patch

drivers/storage/portworx/component/autopilot.go#L662-L663

Added lines #L662 - L663 were not covered by tests
}

// Parse the image version and the threshold version using go-version
currentVersion, err := version.NewSemver(imageVersion)
if err != nil {
logrus.Errorf("Invalid version format: %s", imageVersion)
return false
}

thresholdVersion, _ := version.NewSemver("1.3.15")

// Compare the current version with the threshold version
return currentVersion.GreaterThan(thresholdVersion)
}

func (c *autopilot) getAutopilotDeploymentSpec(
cluster *corev1.StorageCluster,
ownerRef *metav1.OwnerReference,
Expand Down Expand Up @@ -678,6 +704,23 @@ func (c *autopilot) getAutopilotDeploymentSpec(
maxSurge := intstr.FromInt(1)
imagePullPolicy := pxutil.ImagePullPolicy(cluster)

var readinessProbe *v1.Probe
if shouldAddReadinessProbe(imageName) {
readinessProbe = &v1.Probe{
ProbeHandler: v1.ProbeHandler{
HTTPGet: &v1.HTTPGetAction{
Path: "/ready",
Port: intstr.FromInt(9628),
},
},
InitialDelaySeconds: 10,
PeriodSeconds: 10,
TimeoutSeconds: 5,
SuccessThreshold: 1,
FailureThreshold: 3,
}
}

deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: AutopilotDeploymentName,
Expand Down Expand Up @@ -756,6 +799,12 @@ func (c *autopilot) getAutopilotDeploymentSpec(
},
}

// Only assign the readiness probe if it's not nil
// and the container is the autopilot container
if readinessProbe != nil && deployment.Spec.Template.Spec.Containers[0].Name == AutopilotContainerName {
deployment.Spec.Template.Spec.Containers[0].ReadinessProbe = readinessProbe
}

if cluster.Spec.ImagePullSecret != nil && *cluster.Spec.ImagePullSecret != "" {
deployment.Spec.Template.Spec.ImagePullSecrets = append(
[]v1.LocalObjectReference{},
Expand Down
213 changes: 213 additions & 0 deletions drivers/storage/portworx/components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3498,6 +3498,219 @@ func TestAutopilotInstall(t *testing.T) {

}

func TestPresenceOfReadinessProbeForAutopilotValidImageTagGreaterThan1_3_15(t *testing.T) {
// Arrange
mockCtrl := gomock.NewController(t)
versionClient := fakek8sclient.NewSimpleClientset()
versionClient.Discovery().(*fakediscovery.FakeDiscovery).FakedServerVersion = &version.Info{
GitVersion: "v1.25.0",
}
setUpMockCoreOps(mockCtrl, versionClient)
fakeExtClient := fakeextclient.NewSimpleClientset()
apiextensionsops.SetInstance(apiextensionsops.New(fakeExtClient))
reregisterComponents()
k8sClient := testutil.FakeK8sClient()
driver := portworx{}
err := driver.Init(k8sClient, runtime.NewScheme(), record.NewFakeRecorder(0))
require.NoError(t, err)

stcSpec := &corev1.StorageCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "px-cluster",
Namespace: "kube-test",
},
Spec: corev1.StorageClusterSpec{
Monitoring: &corev1.MonitoringSpec{Telemetry: &corev1.TelemetrySpec{}},
Autopilot: &corev1.AutopilotSpec{
Enabled: true,
Image: "portworx/autopilot:1.3.16",
},
Security: &corev1.SecuritySpec{
Enabled: true,
Auth: &corev1.AuthSpec{
SelfSigned: &corev1.SelfSignedSpec{
Issuer: stringPtr(defaultSelfSignedIssuer),
TokenLifetime: stringPtr(defaultTokenLifetime),
SharedSecret: stringPtr(pxutil.SecurityPXSharedSecretSecretName),
},
},
},
},
}
cluster := stcSpec.DeepCopy()
err = driver.SetDefaultsOnStorageCluster(cluster)
require.NoError(t, err)

// Act
err = driver.PreInstall(cluster)

// Assert
require.NoError(t, err)
autopilotDeployment := &appsv1.Deployment{}
err = testutil.Get(k8sClient, autopilotDeployment, component.AutopilotDeploymentName, cluster.Namespace)
require.NoError(t, err)
require.Equal(t, autopilotDeployment.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet.Path, "/ready")
}

func TestAbsenceOfReadinessProbeForAutopilotValidImageTagLesserThanOrEqual1_3_15(t *testing.T) {
// Arrange
mockCtrl := gomock.NewController(t)
versionClient := fakek8sclient.NewSimpleClientset()
versionClient.Discovery().(*fakediscovery.FakeDiscovery).FakedServerVersion = &version.Info{
GitVersion: "v1.25.0",
}
setUpMockCoreOps(mockCtrl, versionClient)
fakeExtClient := fakeextclient.NewSimpleClientset()
apiextensionsops.SetInstance(apiextensionsops.New(fakeExtClient))
reregisterComponents()
k8sClient := testutil.FakeK8sClient()
driver := portworx{}
err := driver.Init(k8sClient, runtime.NewScheme(), record.NewFakeRecorder(0))
require.NoError(t, err)
stcSpec := &corev1.StorageCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "px-cluster",
Namespace: "kube-test",
},
Spec: corev1.StorageClusterSpec{
Monitoring: &corev1.MonitoringSpec{Telemetry: &corev1.TelemetrySpec{}},
Autopilot: &corev1.AutopilotSpec{
Enabled: true,
Image: "portworx/autopilot:1.3.15",
},
Security: &corev1.SecuritySpec{
Enabled: true,
Auth: &corev1.AuthSpec{
SelfSigned: &corev1.SelfSignedSpec{
Issuer: stringPtr(defaultSelfSignedIssuer),
TokenLifetime: stringPtr(defaultTokenLifetime),
SharedSecret: stringPtr(pxutil.SecurityPXSharedSecretSecretName),
},
},
},
},
}
cluster := stcSpec.DeepCopy()
err = driver.SetDefaultsOnStorageCluster(cluster)
require.NoError(t, err)

// Act
err = driver.PreInstall(cluster)

// Assert
require.NoError(t, err)
autopilotDeployment := &appsv1.Deployment{}
err = testutil.Get(k8sClient, autopilotDeployment, component.AutopilotDeploymentName, cluster.Namespace)
require.NoError(t, err)
require.Nil(t, autopilotDeployment.Spec.Template.Spec.Containers[0].ReadinessProbe)
}

func TestAbsenceOfReadinessProbeForAutopilotInValidImageWithoutColon(t *testing.T) {
// Arrange
mockCtrl := gomock.NewController(t)
versionClient := fakek8sclient.NewSimpleClientset()
versionClient.Discovery().(*fakediscovery.FakeDiscovery).FakedServerVersion = &version.Info{
GitVersion: "v1.25.0",
}
setUpMockCoreOps(mockCtrl, versionClient)
fakeExtClient := fakeextclient.NewSimpleClientset()
apiextensionsops.SetInstance(apiextensionsops.New(fakeExtClient))
reregisterComponents()
k8sClient := testutil.FakeK8sClient()
driver := portworx{}
err := driver.Init(k8sClient, runtime.NewScheme(), record.NewFakeRecorder(0))
require.NoError(t, err)
stcSpec := &corev1.StorageCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "px-cluster",
Namespace: "kube-test",
},
Spec: corev1.StorageClusterSpec{
Monitoring: &corev1.MonitoringSpec{Telemetry: &corev1.TelemetrySpec{}},
Autopilot: &corev1.AutopilotSpec{
Enabled: true,
Image: "portworx/autopilot",
},
Security: &corev1.SecuritySpec{
Enabled: true,
Auth: &corev1.AuthSpec{
SelfSigned: &corev1.SelfSignedSpec{
Issuer: stringPtr(defaultSelfSignedIssuer),
TokenLifetime: stringPtr(defaultTokenLifetime),
SharedSecret: stringPtr(pxutil.SecurityPXSharedSecretSecretName),
},
},
},
},
}
cluster := stcSpec.DeepCopy()
err = driver.SetDefaultsOnStorageCluster(cluster)
require.NoError(t, err)

// Act
err = driver.PreInstall(cluster)

// Assert
require.NoError(t, err)
autopilotDeployment := &appsv1.Deployment{}
err = testutil.Get(k8sClient, autopilotDeployment, component.AutopilotDeploymentName, cluster.Namespace)
require.NoError(t, err)
require.Nil(t, autopilotDeployment.Spec.Template.Spec.Containers[0].ReadinessProbe)
}

func TestAbsenceOfReadinessProbeForAutopilotInValidImageTag(t *testing.T) {
// Arrange
mockCtrl := gomock.NewController(t)
versionClient := fakek8sclient.NewSimpleClientset()
versionClient.Discovery().(*fakediscovery.FakeDiscovery).FakedServerVersion = &version.Info{
GitVersion: "v1.25.0",
}
setUpMockCoreOps(mockCtrl, versionClient)
fakeExtClient := fakeextclient.NewSimpleClientset()
apiextensionsops.SetInstance(apiextensionsops.New(fakeExtClient))
reregisterComponents()
k8sClient := testutil.FakeK8sClient()
driver := portworx{}
err := driver.Init(k8sClient, runtime.NewScheme(), record.NewFakeRecorder(0))
require.NoError(t, err)
stcSpec := &corev1.StorageCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "px-cluster",
Namespace: "kube-test",
},
Spec: corev1.StorageClusterSpec{
Monitoring: &corev1.MonitoringSpec{Telemetry: &corev1.TelemetrySpec{}},
Autopilot: &corev1.AutopilotSpec{
Enabled: true,
Image: "portworx/autopilot:77u",
},
Security: &corev1.SecuritySpec{
Enabled: true,
Auth: &corev1.AuthSpec{
SelfSigned: &corev1.SelfSignedSpec{
Issuer: stringPtr(defaultSelfSignedIssuer),
TokenLifetime: stringPtr(defaultTokenLifetime),
SharedSecret: stringPtr(pxutil.SecurityPXSharedSecretSecretName),
},
},
},
},
}
cluster := stcSpec.DeepCopy()
err = driver.SetDefaultsOnStorageCluster(cluster)
require.NoError(t, err)

// Act
err = driver.PreInstall(cluster)

// Assert
require.NoError(t, err)
autopilotDeployment := &appsv1.Deployment{}
err = testutil.Get(k8sClient, autopilotDeployment, component.AutopilotDeploymentName, cluster.Namespace)
require.NoError(t, err)
require.Nil(t, autopilotDeployment.Spec.Template.Spec.Containers[0].ReadinessProbe)
}

func TestAutopilotWithoutImage(t *testing.T) {
mockCtrl := gomock.NewController(t)
setUpMockCoreOps(mockCtrl, fakek8sclient.NewSimpleClientset())
Expand Down

0 comments on commit 283c360

Please sign in to comment.