diff --git a/api/v1alpha1/mariadb_galera_types.go b/api/v1alpha1/mariadb_galera_types.go index 985e0b9d..f4cd0cc0 100644 --- a/api/v1alpha1/mariadb_galera_types.go +++ b/api/v1alpha1/mariadb_galera_types.go @@ -231,7 +231,7 @@ func (g *GaleraRecovery) Validate(mdb *MariaDB) error { } } if g.ForceClusterBootstrapInPod != nil { - if err := statefulset.ValidPodName(mdb.ObjectMeta, *g.ForceClusterBootstrapInPod); err != nil { + if err := statefulset.ValidPodName(mdb.ObjectMeta, int(mdb.Spec.Replicas), *g.ForceClusterBootstrapInPod); err != nil { return fmt.Errorf("'spec.galera.recovery.forceClusterBootstrapInPod' invalid: %v", err) } } diff --git a/pkg/statefulset/statefulset.go b/pkg/statefulset/statefulset.go index 9860b9da..b87ae445 100644 --- a/pkg/statefulset/statefulset.go +++ b/pkg/statefulset/statefulset.go @@ -1,6 +1,7 @@ package statefulset import ( + "errors" "fmt" "os" "strconv" @@ -49,10 +50,19 @@ func PodIndex(podName string) (*int, error) { return &index, nil } -func ValidPodName(meta metav1.ObjectMeta, podName string) error { - if _, err := PodIndex(podName); err != nil { +func ValidPodName(meta metav1.ObjectMeta, replicas int, podName string) error { + if replicas < 0 { + return errors.New("replicas must be positive") + } + + index, err := PodIndex(podName) + if err != nil { return fmt.Errorf("invalid Pod index: %v", err) } + if *index < 0 || *index >= replicas { + return fmt.Errorf("index '%d' out of replicas range", *index) + } + if !strings.HasPrefix(podName, meta.Name) { return fmt.Errorf("invalid Pod name: must start with '%s'", meta.Name) } diff --git a/pkg/statefulset/statefulset_test.go b/pkg/statefulset/statefulset_test.go index 95b9eaf5..08257c94 100644 --- a/pkg/statefulset/statefulset_test.go +++ b/pkg/statefulset/statefulset_test.go @@ -8,56 +8,80 @@ import ( func TestStatefulSetValidPodName(t *testing.T) { tests := []struct { - name string - meta metav1.ObjectMeta - podName string - wantErr bool + name string + meta metav1.ObjectMeta + replicas int + podName string + wantErr bool }{ { name: "empty", meta: metav1.ObjectMeta{ Name: "", }, - podName: "", - wantErr: true, + replicas: 0, + podName: "", + wantErr: true, }, { - name: "invalid", + name: "negative replicas", + meta: metav1.ObjectMeta{ + Name: "", + }, + replicas: -1, + podName: "", + wantErr: true, + }, + { + name: "no index no prefix", meta: metav1.ObjectMeta{ Name: "mariadb-galera", }, - podName: "foo", - wantErr: true, + replicas: 3, + podName: "foo", + wantErr: true, }, { name: "no index", meta: metav1.ObjectMeta{ Name: "mariadb-galera", }, - podName: "mariadb-galera", - wantErr: true, + replicas: 3, + podName: "mariadb-galera", + wantErr: true, + }, + { + name: "invalid index", + meta: metav1.ObjectMeta{ + Name: "mariadb-galera", + }, + replicas: 3, + podName: "mariadb-galera-5", + wantErr: true, }, { name: "no prefix", meta: metav1.ObjectMeta{ Name: "mariadb-galera", }, - podName: "foo-0", - wantErr: true, + replicas: 3, + podName: "foo-0", + wantErr: true, }, { name: "valid", meta: metav1.ObjectMeta{ Name: "mariadb-galera", }, - podName: "mariadb-galera-0", - wantErr: false, + replicas: 3, + podName: "mariadb-galera-0", + wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := ValidPodName(tt.meta, tt.podName) + err := ValidPodName(tt.meta, tt.replicas, tt.podName) if !tt.wantErr && err != nil { t.Errorf("unexpected error: %v", err) }