Skip to content

Commit

Permalink
fix: update configmap if exists (#566)
Browse files Browse the repository at this point in the history
* fix: update configmap if exists

* feat: add update configmap funcs

* chore: optimize the configmap update code

* fix: check conditions test was failing
  • Loading branch information
mojtaba-esk authored Sep 25, 2024
1 parent 6623172 commit bd3b94d
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 17 deletions.
6 changes: 3 additions & 3 deletions pkg/instance/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,14 @@ func (s *storage) deployFiles(ctx context.Context) error {
data[keyName] = fileContent
}

// create configmap
_, err := s.instance.K8sClient.CreateConfigMap(ctx, s.instance.name, s.instance.execution.Labels(), data)
// If the configmap already exists, we update it
// This ensures long-running tests and image upgrade tests function correctly.
_, err := s.instance.K8sClient.CreateOrUpdateConfigMap(ctx, s.instance.name, s.instance.execution.Labels(), data)
if err != nil {
return ErrFailedToCreateConfigMap.Wrap(err)
}

s.instance.Logger.WithField("configmap", s.instance.name).Debug("deployed configmap")

return nil
}

Expand Down
58 changes: 44 additions & 14 deletions pkg/k8s/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package k8s

import (
"context"
"errors"

v1 "k8s.io/api/core/v1"
apierrs "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -37,31 +38,60 @@ func (c *Client) CreateConfigMap(
return nil, ErrClientTerminated
}

if err := validateConfigMapName(name); err != nil {
if err := validateConfigMap(name, labels, data); err != nil {
return nil, err
}
if err := validateLabels(labels); err != nil {
return nil, err

cm := prepareConfigMap(c.namespace, name, labels, data)
created, err := c.clientset.CoreV1().ConfigMaps(c.namespace).Create(ctx, cm, metav1.CreateOptions{})
if err == nil {
return created, nil
}
if err := validateConfigMapKeys(data); err != nil {
return nil, err

if apierrs.IsAlreadyExists(err) {
return nil, ErrConfigmapAlreadyExists.WithParams(name).Wrap(err)
}
return nil, ErrCreatingConfigmap.WithParams(name).Wrap(err)
}

exists, err := c.ConfigMapExists(ctx, name)
if err != nil {
return nil, err
func (c *Client) UpdateConfigMap(
ctx context.Context, name string,
labels, data map[string]string,
) (*v1.ConfigMap, error) {
if c.terminated {
return nil, ErrClientTerminated
}
if exists {
return nil, ErrConfigmapAlreadyExists.WithParams(name)

if err := validateConfigMap(name, labels, data); err != nil {
return nil, err
}

cm := prepareConfigMap(c.namespace, name, labels, data)
created, err := c.clientset.CoreV1().ConfigMaps(c.namespace).Create(ctx, cm, metav1.CreateOptions{})
if err != nil {
return nil, ErrCreatingConfigmap.WithParams(name).Wrap(err)
updated, err := c.clientset.CoreV1().ConfigMaps(c.namespace).Update(ctx, cm, metav1.UpdateOptions{})
if err == nil {
return updated, nil
}

if apierrs.IsNotFound(err) {
return nil, ErrConfigmapDoesNotExist.WithParams(name).Wrap(err)
}
return nil, ErrUpdatingConfigmap.WithParams(name).Wrap(err)
}

func (c *Client) CreateOrUpdateConfigMap(
ctx context.Context, name string,
labels, data map[string]string,
) (*v1.ConfigMap, error) {
updated, err := c.UpdateConfigMap(ctx, name, labels, data)
if err == nil {
return updated, nil
}

if errors.Is(err, ErrConfigmapDoesNotExist) {
return c.CreateConfigMap(ctx, name, labels, data)
}

return created, nil
return nil, ErrUpdatingConfigmap.WithParams(name).Wrap(err)
}

func (c *Client) DeleteConfigMap(ctx context.Context, name string) error {
Expand Down
1 change: 1 addition & 0 deletions pkg/k8s/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,5 @@ var (
ErrClientTerminated = errors.New("ClientTerminated", "terminated by user")
ErrListingPods = errors.New("ListingPods", "failed to list pods")
ErrGetPodStatus = errors.New("GetPodStatus", "failed to get pod status for pod %s")
ErrUpdatingConfigmap = errors.New("UpdatingConfigmap", "failed to update configmap %s")
)
2 changes: 2 additions & 0 deletions pkg/k8s/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type KubeManager interface {
CreateClusterRole(ctx context.Context, name string, labels map[string]string, policyRules []rbacv1.PolicyRule) error
CreateClusterRoleBinding(ctx context.Context, name string, labels map[string]string, clusterRole, serviceAccount string) error
CreateConfigMap(ctx context.Context, name string, labels, data map[string]string) (*corev1.ConfigMap, error)
CreateOrUpdateConfigMap(ctx context.Context, name string, labels, data map[string]string) (*corev1.ConfigMap, error)
CreateCustomResource(ctx context.Context, name string, gvr *schema.GroupVersionResource, obj *map[string]interface{}) error
CreateDaemonSet(ctx context.Context, name string, labels map[string]string, initContainers []corev1.Container, containers []corev1.Container) (*appv1.DaemonSet, error)
CreateNamespace(ctx context.Context, name string) error
Expand Down Expand Up @@ -74,6 +75,7 @@ type KubeManager interface {
RunCommandInPod(ctx context.Context, podName, containerName string, cmd []string) (string, error)
ConfigMapExists(ctx context.Context, name string) (bool, error)
UpdateDaemonSet(ctx context.Context, name string, labels map[string]string, initContainers []corev1.Container, containers []corev1.Container) (*appv1.DaemonSet, error)
UpdateConfigMap(ctx context.Context, name string, labels, data map[string]string) (*corev1.ConfigMap, error)
WaitForDeployment(ctx context.Context, name string) error
WaitForService(ctx context.Context, name string) error
Terminate()
Expand Down
10 changes: 10 additions & 0 deletions pkg/k8s/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,13 @@ func validatePorts(ports []int) error {
}
return nil
}

func validateConfigMap(name string, labels, data map[string]string) error {
if err := validateConfigMapName(name); err != nil {
return err
}
if err := validateLabels(labels); err != nil {
return err
}
return validateConfigMapKeys(data)
}

0 comments on commit bd3b94d

Please sign in to comment.