Skip to content

Commit

Permalink
Fix issues in e2e test (#442)
Browse files Browse the repository at this point in the history
* Fix issues in e2e test

* Increase timeout for cluster wait

* Remove unneeded comments

* Remove unneeded blank line

* Add nebula backup e2e tests

* Fix pull request according to review and add cron backup tests

* add env values to github action e2e and delete created nr after each backup test

* Fix review comments on nebula backup and restore tests.

* leave annotation.AnnLastReplicas alone

* Fix cronbackup and env issue

* Fix timeout
  • Loading branch information
kevinliu24 authored Mar 12, 2024
1 parent 6e9b866 commit 42b0812
Show file tree
Hide file tree
Showing 12 changed files with 1,879 additions and 7 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,16 @@ jobs:
export E2E_DOCKER_CONFIG_JSON_SECRET=`cat ~/.docker/config.json| base64 -w 0`
make e2e E2EARGS="-v=5 -skip-features 'pv expansion|custom config for dynamic|tools for exporter'"
env:
E2E_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
E2E_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
E2E_BR_IMAGE: reg.vesoft-inc.com/cloud-dev/br-ent
E2E_BR_VERSION: v3.7.0
E2E_GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
E2E_OPERATOR_IMAGE: reg.vesoft-inc.com/ci/nebula-operator:ci-e2e
E2E_OPERATOR_INSTALL: "true"
E2E_NC_VERSION: v3.6.0
E2E_NC_VERSION: v3.7.0
E2E_NC_AGENT_IMAGE: reg.vesoft-inc.com/cloud-dev/nebula-agent
E2E_NC_AGENT_VERSION: v3.6.0
E2E_NC_GRAPHD_IMAGE: reg.vesoft-inc.com/vesoft-ent/nebula-graphd-ent
E2E_NC_METAD_IMAGE: reg.vesoft-inc.com/vesoft-ent/nebula-metad-ent
E2E_NC_STORAGED_IMAGE: reg.vesoft-inc.com/vesoft-ent/nebula-storaged-ent
Expand Down
18 changes: 18 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ require (
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
github.com/aws/aws-sdk-go v1.44.178 // indirect
github.com/aws/aws-sdk-go-v2 v1.25.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.0 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.0 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.0 // indirect
github.com/aws/aws-sdk-go-v2/service/s3 v1.50.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 // indirect
github.com/aws/smithy-go v1.20.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
Expand Down
36 changes: 36 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,42 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.44.178 h1:4igreoWPEA7xVLnOeSXLhDXTsTSPKQONZcQ3llWAJw0=
github.com/aws/aws-sdk-go v1.44.178/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v1.25.0 h1:sv7+1JVJxOu/dD/sz/csHX7jFqmP001TIY7aytBWDSQ=
github.com/aws/aws-sdk-go-v2 v1.25.0/go.mod h1:G104G1Aho5WqF+SR3mDIobTABQzpYV0WxMsKxlMggOA=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 h1:2UO6/nT1lCZq1LqM67Oa4tdgP1CvL1sLSxvuD+VrOeE=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0/go.mod h1:5zGj2eA85ClyedTDK+Whsu+w9yimnVIZvhvBKrDquM8=
github.com/aws/aws-sdk-go-v2/config v1.27.0 h1:J5sdGCAHuWKIXLeXiqr8II/adSvetkx0qdZwdbXXpb0=
github.com/aws/aws-sdk-go-v2/config v1.27.0/go.mod h1:cfh8v69nuSUohNFMbIISP2fhmblGmYEOKs5V53HiHnk=
github.com/aws/aws-sdk-go-v2/credentials v1.17.0 h1:lMW2x6sKBsiAJrpi1doOXqWFyEPoE886DTb1X0wb7So=
github.com/aws/aws-sdk-go-v2/credentials v1.17.0/go.mod h1:uT41FIH8cCIxOdUYIL0PYyHlL1NoneDuDSCwg5VE/5o=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 h1:xWCwjjvVz2ojYTP4kBKUuUh9ZrXfcAXpflhOUUeXg1k=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0/go.mod h1:j3fACuqXg4oMTQOR2yY7m0NmJY0yBK4L4sLsRXq1Ins=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 h1:NPs/EqVO+ajwOoq56EfcGKa3L3ruWuazkIw1BqxwOPw=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0/go.mod h1:D+duLy2ylgatV+yTlQ8JTuLfDD0BnFvnQRc+o6tbZ4M=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 h1:ks7KGMVUMoDzcxNWUlEdI+/lokMFD136EL6DWmUOV80=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0/go.mod h1:hL6BWM/d/qz113fVitZjbXR0E+RCTU1+x+1Idyn5NgE=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.0 h1:TkbRExyKSVHELwG9gz2+gql37jjec2R5vus9faTomwE=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.0/go.mod h1:T3/9xMKudHhnj8it5EqIrhvv11tVZqWYkKcot+BFStc=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 h1:a33HuFlO0KsveiP90IUJh8Xr/cx9US2PqkSroaLc+o8=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0/go.mod h1:SxIkWpByiGbhbHYTo9CMTUnx2G4p4ZQMrDPcRRy//1c=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.0 h1:UiSyK6ent6OKpkMJN3+k5HZ4sk4UfchEaaW5wv7SblQ=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.0/go.mod h1:l7kzl8n8DXoRyFz5cIMG70HnPauWa649TUhgw8Rq6lo=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 h1:SHN/umDLTmFTmYfI+gkanz6da3vK8Kvj/5wkqnTHbuA=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0/go.mod h1:l8gPU5RYGOFHJqWEpPMoRTP0VoaWQSkJdKo+hwWnnDA=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.0 h1:l5puwOHr7IxECuPMIuZG7UKOzAnF24v6t4l+Z5Moay4=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.0/go.mod h1:Oov79flWa/n7Ni+lQC3z+VM7PoRM47omRqbJU9B5Y7E=
github.com/aws/aws-sdk-go-v2/service/s3 v1.50.0 h1:jZAdMD1ioZdqirzzVVRhpHHWJmcGGCn8JqDYBs5nmYA=
github.com/aws/aws-sdk-go-v2/service/s3 v1.50.0/go.mod h1:1o/W6JFUuREj2ExoQ21vHJgO7wakvjhol91M9eknFgs=
github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 h1:u6OkVDxtBPnxPkZ9/63ynEe+8kHbtS5IfaC4PzVxzWM=
github.com/aws/aws-sdk-go-v2/service/sso v1.19.0/go.mod h1:YqbU3RS/pkDVu+v+Nwxvn0i1WB0HkNWEePWbmODEbbs=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 h1:6DL0qu5+315wbsAEEmzK+P9leRwNbkp+lGjPC+CEvb8=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0/go.mod h1:olUAyg+FaoFaL/zFaeQQONjOZ9HXoxgvI/c7mQTYz7M=
github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 h1:cjTRjh700H36MQ8M0LnDn33W3JmwC77mdxIIyPWCdpM=
github.com/aws/aws-sdk-go-v2/service/sts v1.27.0/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc=
github.com/aws/smithy-go v1.20.0 h1:6+kZsCXZwKxZS9RfISnPc4EXlHoyAkm2hPuM8X2BrrQ=
github.com/aws/smithy-go v1.20.0/go.mod h1:uo5RKksAl4PzhqaAbjd4rLgFoq5koTsQKYuGe7dklGc=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
Expand Down
7 changes: 7 additions & 0 deletions tests/e2e/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type CommonConfig struct {
// DockerConfigJsonSecret is the docker config file.
// export E2E_DOCKER_CONFIG_JSON_SECRET=`cat ~/.docker/config.json| base64 -w 0`
DockerConfigJsonSecret Base64Value `env:"E2E_DOCKER_CONFIG_JSON_SECRET"`
AWSAccessKey Base64Value `env:"E2E_AWS_ACCESS_KEY_ID"`
AWSSecretKey Base64Value `env:"E2E_AWS_SECRET_ACCESS_KEY"`
GSSecret Base64Value `env:"E2E_GOOGLE_APPLICATION_CREDENTIALS"`
}

type ClusterConfig struct {
Expand All @@ -75,6 +78,10 @@ type OperatorConfig struct {
type NebulaClusterConfig struct {
ChartPath string `env:"E2E_NC_CHART_PATH,notEmpty,required" envDefault:"../../charts/nebula-cluster"`
Version string `env:"E2E_NC_VERSION"`
AgentImage string `env:"E2E_NC_AGENT_IMAGE"`
AgentVersion string `env:"E2E_NC_AGENT_VERSION"`
BrImage string `env:"E2E_BR_IMAGE"`
BrVersion string `env:"E2E_BR_VERSION"`
GraphdImage string `env:"E2E_NC_GRAPHD_IMAGE"`
MetadImage string `env:"E2E_NC_METAD_IMAGE"`
StoragedImage string `env:"E2E_NC_STORAGED_IMAGE"`
Expand Down
274 changes: 274 additions & 0 deletions tests/e2e/envfuncsext/backup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
package envfuncsext

import (
"context"
"fmt"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"sigs.k8s.io/e2e-framework/klient/wait"
"sigs.k8s.io/e2e-framework/pkg/env"
"sigs.k8s.io/e2e-framework/pkg/envconf"

appsv1alpha1 "github.com/vesoft-inc/nebula-operator/apis/apps/v1alpha1"
)

type (
NebulaBackupInstallOptions struct {
Name string
Namespace string
Spec appsv1alpha1.BackupSpec
CronBackupOps *NebulaCronBackupOptions
}

NebulaCronBackupOptions struct {
Schedule string
TestPause bool
}

nebulaBackupCtxKey struct {
backupType string
}

NebulaBackupCtxValue struct {
// general fields
Name string
Namespace string
BackupFileName string
StorageType string
BucketName string
Region string
CleanBackupData bool

// for cron backup only
Schedule string
TestPause bool
TriggeredBackupName string
BackupSpec appsv1alpha1.BackupSpec
}

NebulaBackupOption func(*NebulaBackupOptions)
NebulaBackupOptions struct {
WaitOptions []wait.Option
}
)

func DeployNebulaBackup(incremental bool, nbCtx NebulaBackupInstallOptions) env.Func {
return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
namespaceToUse := cfg.Namespace()
if nbCtx.Namespace != "" {
namespaceToUse = nbCtx.Namespace
}

nb := &appsv1alpha1.NebulaBackup{
ObjectMeta: metav1.ObjectMeta{
Name: nbCtx.Name,
Namespace: namespaceToUse,
},
Spec: nbCtx.Spec,
}

ctx, err := CreateObject(nb)(ctx, cfg)
if err != nil {
return ctx, fmt.Errorf("error creating nebula backup [%v/%v]: %v", namespaceToUse, nbCtx.Name, err)
}

key := nebulaBackupCtxKey{backupType: "base"}
if incremental {
key = nebulaBackupCtxKey{backupType: "incr"}
}

var stoType, region, bucketName string
if nb.Spec.Config.S3 != nil {
stoType = "S3"
region = nb.Spec.Config.S3.Region
bucketName = nb.Spec.Config.S3.Bucket
} else if nb.Spec.Config.GS != nil {
stoType = "GS"
region = nb.Spec.Config.GS.Location
bucketName = nb.Spec.Config.GS.Bucket
}

return context.WithValue(ctx, key, &NebulaBackupCtxValue{
Name: nbCtx.Name,
Namespace: namespaceToUse,
StorageType: stoType,
Region: region,
BucketName: bucketName,
CleanBackupData: *nb.Spec.CleanBackupData,
}), nil
}
}

func GetNebulaBackupCtxValue(incremental bool, ctx context.Context) *NebulaBackupCtxValue {
key := nebulaBackupCtxKey{backupType: "base"}
if incremental {
key = nebulaBackupCtxKey{backupType: "incr"}
}

v := ctx.Value(key)
data, _ := v.(*NebulaBackupCtxValue)
return data
}

func WaitNebulaBackupFinished(incremental bool, opts ...NebulaBackupOption) env.Func {
return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
o := (&NebulaBackupOptions{}).WithOptions(opts...)

backupContextValue := GetNebulaBackupCtxValue(incremental, ctx)

nb := &appsv1alpha1.NebulaBackup{}
if err := wait.For(func(ctx context.Context) (done bool, err error) {
err = cfg.Client().Resources().Get(ctx, backupContextValue.Name, backupContextValue.Namespace, nb)
if err != nil {
klog.ErrorS(err, "Get NebulaBackup failed", "namespace", backupContextValue.Namespace, "name", backupContextValue.Name)
return true, err
}

klog.V(4).InfoS("Waiting for NebulaBackup to complete",
"namespace", nb.Namespace, "name", nb.Name,
"generation", nb.Generation,
)

if nb.Status.Phase == appsv1alpha1.BackupComplete {
return true, nil
}

if nb.Status.Phase == appsv1alpha1.BackupFailed || nb.Status.Phase == appsv1alpha1.BackupInvalid {
return true, fmt.Errorf("nebula backup [%v/%v] has failed", nb.Namespace, nb.Name)
}

return false, nil
}, o.WaitOptions...); err != nil {
klog.ErrorS(err, "Waiting for NebulaBackup to complete failed", "namespace", backupContextValue.Namespace, "name", backupContextValue.Name)
return ctx, err
}

klog.InfoS("Waiting for NebulaBackup to complete successful", "namespace", backupContextValue.Namespace, "name", backupContextValue.Name, "backup file name", nb.Status.BackupName)

key := nebulaBackupCtxKey{backupType: "base"}
if incremental {
key = nebulaBackupCtxKey{backupType: "incr"}
}

return context.WithValue(ctx, key, &NebulaBackupCtxValue{
Name: backupContextValue.Name,
Namespace: backupContextValue.Namespace,
BackupFileName: nb.Status.BackupName,
StorageType: backupContextValue.StorageType,
Region: backupContextValue.Region,
BucketName: backupContextValue.BucketName,
CleanBackupData: backupContextValue.CleanBackupData,
}), nil
}
}

func (o *NebulaBackupOptions) WithOptions(opts ...NebulaBackupOption) *NebulaBackupOptions {
for _, opt := range opts {
opt(o)
}
return o
}

func WithNebulaBackupWaitOptions(opts ...wait.Option) NebulaBackupOption {
return func(o *NebulaBackupOptions) {
o.WaitOptions = append(o.WaitOptions, opts...)
}
}

func DeleteNebulaBackup(incremental bool) env.Func {
return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
backupContextValue := GetNebulaBackupCtxValue(incremental, ctx)

nb := &appsv1alpha1.NebulaBackup{
ObjectMeta: metav1.ObjectMeta{
Name: backupContextValue.Name,
Namespace: backupContextValue.Namespace,
},
}

ctx, err := DeleteObject(nb)(ctx, cfg)
if err != nil {
return ctx, fmt.Errorf("error deleting nebula backup [%v/%v]: %v", backupContextValue.Namespace, backupContextValue.Name, err)
}

return ctx, nil
}
}

func WaitForCleanBackup(incremental bool, opts ...NebulaBackupOption) env.Func {
return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
o := (&NebulaBackupOptions{}).WithOptions(opts...)

backupContextValue := GetNebulaBackupCtxValue(incremental, ctx)

nb := &appsv1alpha1.NebulaBackup{}
if err := wait.For(func(ctx context.Context) (done bool, err error) {
err = cfg.Client().Resources().Get(ctx, backupContextValue.Name, backupContextValue.Namespace, nb)
if err != nil {
if apierrors.IsNotFound(err) {
return true, nil
}
return true, fmt.Errorf("error deleting nebula backup [%v/%v]: %v", backupContextValue.Namespace, backupContextValue.Name, err)
}

if nb.Status.Phase == appsv1alpha1.BackupComplete || nb.Status.Phase == appsv1alpha1.BackupClean {
klog.V(4).InfoS("Waiting for NebulaBackup cleanup to complete",
"namespace", nb.Namespace, "name", nb.Name, "file name", backupContextValue.BackupFileName,
"generation", nb.Generation,
)
return false, nil
}

return true, fmt.Errorf("nebula backup clean for [%v/%v] has failed", backupContextValue.Namespace, backupContextValue.Name)
}, o.WaitOptions...); err != nil {
klog.ErrorS(err, "Waiting for NebulaBackup clean to complete failed", "namespace", backupContextValue.Namespace, "name", backupContextValue.Name, "file name", backupContextValue.BackupFileName)
return ctx, err
}
klog.InfoS("Waiting for NebulaBackup clean to complete successful", "namespace", backupContextValue.Namespace, "name", backupContextValue.Name, "file name", backupContextValue.BackupFileName)

return ctx, nil
}
}

func CreateServiceAccount(namespace, name string) env.Func {
return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
sa := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}

if ctx, err := CreateObject(sa)(ctx, cfg); err != nil {
if apierrors.IsAlreadyExists(err) {
klog.Infof("service account [%s/%s] already exists", sa.Namespace, sa.Name)
return ctx, nil
}
return ctx, err
}

klog.Infof("Service account [%s/%s] created successfully", namespace, name)
return ctx, nil
}
}

func DeleteServiceAccount(namespace, name string) env.Func {
return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) {
sa := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}

if err := cfg.Client().Resources().Delete(ctx, sa); err != nil {
return ctx, err
}

klog.Infof("Service account [%s/%s] deleted successfully", namespace, name)
return ctx, nil
}
}
Loading

0 comments on commit 42b0812

Please sign in to comment.